背景
前段時間胞四,項目上一大波新人襲來脊另,恰巧前后兩人需要入職我所在的團隊独郎,由于團隊中已經存在比較系統(tǒng)的新人項目引導(on boarding)流程反粥,其目標是指導新人自行完成項目引導才顿,由于正值項目緊張的特殊時期郑气,我只覺分身乏術腰池,便和新同事討論決定采用“自主學習,定期跟進”的方法演怎,即避乏,由新同事根據既有流程自主學習拍皮,我們每隔兩天進行討論回顧慰技,發(fā)現(xiàn)和解決問題。然而阳藻,結果并不樂觀,其中技術經驗尚淺的同事在無人干預的情況下,幾乎無法取得進展,而在和另一個有十余年工作經驗的同事在討論中發(fā)現(xiàn)他也不能完全掌握其中的知識點拾徙,且對其中幾個部分有很多疑問。這不禁讓我心生疑惑驯杜,究竟是新同事的能力問題還是這個新人項目引導教程存在缺陷呢莺奸?
問題
忙完緊張的項目之后讽膏,我隨即將工作重心轉移到了幫助新人項目引導和個人成長方面闷盔。俗話說,事非經過不知難,我決定自己走一遍現(xiàn)有的項目引導流程旬盯。
首先找到現(xiàn)有文檔,它是一個看起來非常完備的文檔奸晴,包羅萬象,從業(yè)務知識、技術要點,到部署策略、安全開發(fā),無不提及。其中,外鏈近百装蓬,鏈外加鏈,若是新人采用廣度優(yōu)先方式學習還好宪肖,若是深度優(yōu)先控乾,怕是爬進某個官方文檔就難以爬出了娜遵。
再看項目代碼的引導部分,切到作業(yè)練習分支后慨仿,發(fā)現(xiàn)這里的信息也很多镰吆,讀完后對需要完成的任務不能清楚地理解。隨即我試圖通過閱讀代碼尋找到任務的蛛絲馬跡骡和,卻依然霧里看花相寇。最終不得不試圖將網站運行起來唤衫,結合這些文檔绵脯,理解究竟需要做些什么蛆挫,然而首頁是紅通通的500錯誤碼。而在任務過程中瞧剖,當且僅當每一步都正確時抓于,才能得到正確的結果浇借。這期間沒有明確的檢驗機制對任何一步進行驗證,這使得任務難度大大增加巾遭,且與TDD實踐和快速反饋相違背灼舍。
此時片仿,我?guī)缀蹩梢韵胂笮氯藗儍刃牡臒o助和惶恐尤辱,以及為解決這些困難所付出的努力。
與其這樣塔粒,不如手把手地帶兩周筐摘,對新人來說,也許會有更好的體驗圃酵。
不過既然已經發(fā)現(xiàn)了問題馍管,我決定幫助團隊對項目代碼的引導部分進行改進确沸,使其能夠真正承擔預期的職責罗捎。
指導原則
作為新人的項目引導,對新人來說是學習和信心建立的過程豁状,對項目來說是分享和吸納血液的過程雷激。它們相互增益屎暇,互為助力,使新人為新項目做好準備根悼,而項目則獲得新的創(chuàng)造者凶异。
它有別于項目其他工作,諸如調研新技術挤巡、幫助項目改進技術架構剩彬、尋找新的商業(yè)機會等工作需要對項目足夠了解、對技術足夠深入矿卑,從而跨越平庸喉恋,創(chuàng)造更大的價值。相比之下,新人的項目引導轻黑,其著眼點主要放在了解是什么、為什么氓鄙、怎么開始馆揉。只要跨過這一步,就可以發(fā)揮其主觀能動性抖拦,成為項目的獨立貢獻者升酣。
因此,我希望引導教程能夠在知識傳遞的同時不做太過深入的引導态罪,并保持友好:
提供足夠且剛好足夠的知識噩茄,并學以致用
循序漸進,快速驗證
對于第一點向臀,拋棄大而全巢墅,采用小而精的方式诸狭,有針對性地對項目知識總結陳述券膀,有層次地進行任務設計,將領域知識和技術難點融入任務驯遇,使每個任務重點突出芹彬,只有理解了這部分知識才能正確完成任務,而提供足夠且剛好足夠的知識叉庐,意味著知識域和問題域的閉合舒帮,即通過設計限制學習時間,避免發(fā)散和浪費陡叠,完成任務即學會知識點玩郊。
第二點也很重要,它有助于提升用戶體驗枉阵,由淺入深译红,循序漸進,避免陡峭的學習曲線兴溜,這在入門時能有效建立信心侦厚,實現(xiàn)快速啟動。
教程設計
目標
通過該新人引導教程拙徽,使新人能夠在沒有或盡可能少地提供幫助的條件下刨沦,在有限時間內自主學習,掌握項目背景知識膘怕,完成獨立工作的技術和業(yè)務儲備想诅。
這個目標不能解決所有問題,僅用于解決新人不知道自己不知道什么,或面對一切未知無處下手的問題来破。它用于儲備基礎知識裁眯,從而能夠在之后理解和參與團隊討論,閱讀和理解既有代碼讳癌,漸進地擴大自身知識領域穿稳。
層次
我和使用過現(xiàn)有引導教程的同事聊了聊,試圖了解更多痛點晌坤,發(fā)現(xiàn)了以下幾個問題逢艘。
對業(yè)務不熟悉,盡管有文檔骤菠,但數量過多需要大量時間它改,短期內難以學習和掌握
項目代碼庫太大,不了解代碼結構商乎,閱讀代碼不知從何讀起
第三方框架的文檔不完備央拖,僅靠文檔無法學會使用方法
因此,在教程設計時鹉戚,我打算增強代入感鲜戒,分層進行任務設計抹凳,
首先粹庞,將新人從現(xiàn)實生活帶入項目的業(yè)務領域。這個過程代入感十足访娶,引導新人利用自己的生活經驗以產品用戶的視角審視業(yè)務領域割笙,結合項目應用程序的使用走净,快速學習業(yè)務知識。
隨后抛虏,通過其中某個業(yè)務場景博其,指引新人完成從視覺上看到的網頁元素到理解和閱讀代碼層次的實現(xiàn)業(yè)務邏輯的完整流程。
-
最后迂猴,通過設計新的業(yè)務場景慕淡,指引新人利用此前學到的流程照貓畫虎完成代碼編寫,同時引入代碼規(guī)范沸毁,從第一行代碼開始適應項目的編碼習慣峰髓。
至此,在領域知識方面息尺,新人從自身經驗出發(fā)携兵,自主思考,理解和學習業(yè)務知識搂誉,并通過細致地講解理解業(yè)務功能是如何通過代碼實現(xiàn)徐紧,最終達成自己編寫代碼完成業(yè)務功能的成就。整個過程行云流水,符合我們的認知習慣并级,也建立了新人開始工作的信心拂檩。
分層容易,實現(xiàn)代入感卻不容易嘲碧。下面我以這個引導教程為例稻励,說明如何構建代入感。
這個項目是一個航空公司的在線售票和服務網站愈涩,領域知識中的一個重要版圖是機票的在線預訂钉迷,于是我設計了這樣一個任務:
假設你即將迎來假期,你決定去那個想去很久的地方(想想究竟是哪里)钠署,
于是來到這個網站預訂去那里的機票糠聪,這是網站的地址:http://local.xxxx.com/booking.
*說明:在本地運行的網站里,所有的支付方式都并非真正發(fā)生谐鼎,因此放心支付別害怕舰蟆。
支付的各種賬號信息見 - 這里(link).
一個人太孤單,你決定和一個朋友一起這段旅程狸棍,往返都有他/她的陪伴身害。
不過盡管假期時間已經確定,但萬一什么重要的事情發(fā)生了草戈,這次旅行還是可能取消的塌鸯。
你喜歡帶盡可能少的行李出門,而你的朋友希望旅途期間盡可能舒適唐片,如果可以丙猬,他/她甚至愿意把床都帶去。
你喜歡舒適的環(huán)境费韭。在飛機上也不想座位太狹窄茧球,連腿都伸不直。
酒店還沒有定星持,你想選個好點的抢埋,不介意在哪里訂。當地交通也是一樣督暂。
你有一只貓揪垄,溫良可愛,如果可能逻翁,你想帶它一起去饥努。
此外,你不喜歡有額外收費的支付方式卢未。如果不得不支付肪凛,你希望使用額外費用最少的那種堰汉。
最終,你會取得一個訂單號伟墙,它將用于在未來找到你的這個訂單翘鸭。
記下訂單號,并回答一下問題戳葵。
Q0. 你訂的機票滿足了你所有的期望嗎就乓?寫下來未能滿足的期望。
Q1. 列出預訂期間觀察到的所有該航空公司售賣的產品拱烁。
Q2. 回憶一下預定期間共經過多少頁面生蚁,它們分別是什么。
Q3. 這和你之前的訂票體驗有什么不同戏自,不同點是什么邦投?
作為第一層任務,它不需要新人閱讀任何專業(yè)文檔擅笔,僅從一個旅行場景開始志衣。這意味著門檻低,易于著手猛们。
場景中設定了乘客的喜好念脯,用于指引新人在訂票過程中關注相關信息,潛移默化地聚焦那些可能被一掃而過但會被乘客真實使用的功能點弯淘。場景后列出的問題進一步確認這些功能點绿店,并連接新人的個人生活經驗,啟發(fā)進一步的思考庐橙。同時假勿,網站地址選用local,要求新人完成本地的程序運行怕午,為此后的代碼任務做好準備废登。
此后繼續(xù)引入其他場景,最后列出術語表(Glossary)郁惜,擴大新人的知識范圍。
第二層任務承接上層內容甲锡,選取一個功能點兆蕉,從URL開始,逐步分解缤沦,每一步以行為所產生的結果為先虎韵,因為這是新人當下能夠看到和理解的,隨后進行內容講解缸废,說明產生這個效果的原因和流程包蓝,如有技術要點驶社,也在此一一說明,附以相關文檔外鏈测萎,但需要注意的是亡电,外鏈僅做深入學習所用,假設沒有它們硅瞧,該說明依然可以指導新人理解工作原理份乒。
這就是之前所說的“提供足夠且剛好足夠的知識”。
此后腕唧,給出另一個相似功能點或辖,要求利用例子中講解的知識講出其技術關鍵點和實現(xiàn)原理和流程。這一步是對知識的鞏固枣接。
有了第二層的知識儲備颂暇,就可以著手練習了。第三層將實現(xiàn)從閱讀到寫作的躍進但惶。如果說閱讀是理解的過程耳鸯,啟發(fā)新人對知識進行梳理和歸納,那么動手寫代碼就是演繹的過程榆骚,啟發(fā)新人運用掌握的知識片拍,從一般推演個別,完成新功能的創(chuàng)造妓肢。
這一步很容易理解捌省,其中的要義僅在于尋找一個合適的功能點,它的難度要適中碉钠,不可引入過多此前沒有導入的領域知識纲缓,而項目中的技術關鍵點則需完全包含在內。
需要注意的是喊废,本層的任務引導也應逐步進行祝高。將功能點分解為若干步驟,在每一步中定義清晰的驗收條件污筷,同時列出將實踐應用的技術要點工闺。此外,可以進一步給出示例代碼瓣蛀,展示項目中的架構設計和遵循的代碼規(guī)范陆蟆,從新人第一次動手編碼開始,養(yǎng)成遵循代碼約定的習慣惋增。如實在需要引入未知的知識叠殷,這里不妨給出代碼。
問題驅動
如上節(jié)的示例所示诈皿,在任務設計中林束,采用問題驅動像棘。這在軟件開發(fā)學習中并不常見。然而壶冒,在新人引導教程中卻能達到超出預期的效果缕题。其原因是聚焦,將問題域限制在有限范圍內依痊,從而快速掌握必備知識避除。
問題的設計需要有明確的目標,避免公式化的問題和答案胸嘁,需要緊密結合任務瓶摆,有針對性地提出。這樣問題才能不是難題性宏,而是引導群井,知識的獲得變?yōu)樗角伞?/p>
可驗證
此前的用戶訪談中提到一個問題是,任務結果難以驗證毫胜,這和快速反饋背道而馳书斜。為了克服這一點,在教程設計中做了下面幾點:
代碼完整可運行酵使。保證代碼業(yè)務知識的學習可以基于運行的應用程序進行驗證荐吉。
分支代碼庫贷掖。保證代碼的不變性歧譬,即使此后主干分支上功能點發(fā)生變化槽棍,并不影響教程的使用达传。
TDD。在代碼實踐部分引入并要求完成單元測試哨坪,確認代碼實現(xiàn)能夠包含需求中定義的場景咬腋。
細化步驟仓手。每個任務盡可能分為小的步驟攻礼,每個步驟都有驗證方法业踢,確保新人不會在學習過程中走入岔路卻不自知。
定義功能測試樣例礁扮,當新人完成所有任務時知举,可以通過功能測試驗證其完成度,保證設計的溝溝壑壑都被新人填平太伊。
有限的時間
在實踐中负蠕,存在新人因對業(yè)務和流程的不熟悉,而將很多時間放在對項目工作的輔助知識的學習倦畅,對必要知識的學習進行了延遲的情況。于是在這個教程中绣的,我們通過實驗對每個任務的完成時間進行了建議叠赐,完成時間是一個范圍欲账,定義了最少需要的時間和最長需要的時間。
對于不同角色的新人芭概,在新人指引階段的側重點可能會有所不同赛不,時間建議可以幫助buddy評估所需花費的時間及優(yōu)先級。同時罢洲,在新人進行學習的過程中踢故,可以幫助其合理安排時間。
測試和改進
好的產品不是一蹴而就的惹苗,教程也是殿较。制作好的教程需要迭代、測試和改進桩蓉。
在教程的制作中淋纲,我們進行了數次迭代和測試:
教程制作者對教程進行了完整的試用,自測
邀請項目中的新人使用該教程進行完成項目引導院究,收集反饋
邀請曾使用舊教程的同事閱讀新版教程并給出建議
在此過程中洽瞬,果然發(fā)現(xiàn)諸多問題。其中包括:
剛剛好的知識差了一點业汰,導致無法進行
沒有提供完整的功能測試樣例伙窃,使新人完成任務后自測Happy Path后認為一切都很完美,完美忽略了設計者埋的坑
外鏈的項目架構說明已經過時
修改后的教程在不久后就發(fā)布了样漆,那是一個更好的版本为障,解決了此前發(fā)現(xiàn)的所有痛點,大獲好評氛濒。
結語
隨著項目發(fā)展产场、團隊擴張,新成員的加入成為很多團隊頻繁發(fā)生的事情之一舞竿,如何高效地幫助新人完成項目引導成為亟待解決的問題京景。在這方面做得好,能大大縮減新人融入團隊和上手工作的時間骗奖,并有助于判斷發(fā)現(xiàn)其能力水平确徙,幫助制定個人成長目標。反之执桌,則可能影響團隊工作進度鄙皇,同時增加能力評估的風險。
高效的新人項目引導教程意味著更短的時間和更好的知識吸收仰挣,這顯然需要教程設計者豐富的經驗和不懈的努力伴逸。因此,可以說這是一個成本很高的事情膘壶,比如错蝴,項目的這個教程花費了5人天洲愤。那么它是否值得呢?說到收益顷锰,就要談談使用場景柬赐。對于團隊規(guī)模小,人員流動性弱或業(yè)務和技術比較簡單的團隊官紫,人工的新人引導可能是最高效的肛宋;對于團隊規(guī)模大,人員流動性強或是業(yè)務和技術復雜的團隊束世,人工的新人引導就存在差異化大酝陈、時間長、效率低的現(xiàn)象良狈,使用一致性的規(guī)范化教程則可以為團隊提供很大幫助后添。因此,是否需要制作這樣的教程薪丁,需要根據項目的實際情況靈活安排遇西。