爲什麼計算機專業的學生應該爲開源項目做貢獻?

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文最初發佈於acm.org網站,經原作者"},{"type":"link","attrs":{"href":"https:\/\/www.spinellis.gr\/index.html.var","title":"","type":null},"content":[{"type":"text","text":"Diomi"}]},{"type":"link","attrs":{"href":"https:\/\/www.spinellis.gr\/index.html.var","title":"","type":null},"content":[{"type":"text","text":"d"}]},{"type":"link","attrs":{"href":"https:\/\/www.spinellis.gr\/index.html.var","title":"","type":null},"content":[{"type":"text","text":"is Spinel"}]},{"type":"link","attrs":{"href":"https:\/\/www.spinellis.gr\/index.html.var","title":"","type":null},"content":[{"type":"text","text":"l"}]},{"type":"link","attrs":{"href":"https:\/\/www.spinellis.gr\/index.html.var","title":"","type":null},"content":[{"type":"text","text":"is"}]},{"type":"text","text":"授權,由InfoQ中文站翻譯並分享。作者聲明保留所有權利。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"出於許多現實的、歷史的和一些空泛的原因,編程可能是所有計算機科學、信息學、軟件工程和計算機工程課程的必修課。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數十年來,這項技能都是計算機專業畢業生與其他學科同學的典型區分點所在。本文提出的觀點認爲,在21世紀,編程熟練度既不能涵蓋市場對計算機畢業生的技能要求,也不能像過去那樣帶來強大的職業競爭力。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,我建議學校應該鼓勵計算機專業的學生通過他們的課程活動爲開源軟件項目貢獻代碼。我已經在軟件工程課程中實踐和打磨這種方法超過15年了,在我的課程裏開源貢獻是強制的打分點(注2)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基於這方面的經驗,我會在本文中解釋爲什麼做出這種貢獻的能力可以反映現代編程技能的一般水平,並介紹學生可以從這些活動中學到什麼,具體說明如何將開源貢獻練習嵌入到課程中,並總結一些在課程中獲得成功的實踐。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"貢獻是新的編程"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如今,編程技能只是軟件開發人員應掌握知識和能力的一部分。出現這種情況有兩個原因。首先,現實實踐已經遠遠超出了Fred Brooks在1970年代推廣的首席程序員\/外科醫生模型(注1)所描述的範疇,開發人員今天要面對規模大得多的系統、更先進的工具鏈、普遍的流程自動化,還要參與複雜的團隊合作、工作流程和管理方面的工作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其次,行業最佳實踐與成功的大型開源軟件項目所遵循的實踐業已趨同。企業界已經吸收並貢獻了許多開源開發實踐。因此相應的知識和技能對於志願者項目和企業項目來說是相通的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正因如此,編程教學必須從課堂實驗室教育形態轉向基於組織環境的教育方式。學生在爲開源項目做出貢獻的同時,可以在實踐中獲得廣泛的技能、知識和經驗,讓他們成爲符合現代需求、全面發展的高生產力開發人員,而不是好萊塢電影描繪的那種獨狼程序員。在傳統的編程課程中最難獲得的技能包括以下社交和組織技能:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"感知背景和氛圍的能力:瞭解如何在開發工作中融入項目的範圍、使命,如何與同事組成團隊,發展新的領導形式;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與項目涉及的全球多元化社區互動;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與團隊協商特性請求、需求和實現選項;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"處理溝通問題,例如無人響應,這在志願者運營的項目中很常見;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過問題分類和發佈計劃等實踐,體會將軟件視爲產品的理念;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接收、討論和處理代碼審查意見。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對應的技術層面學習成果涵蓋了從分析和評估到應用和創造的領域,包括以下內容:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"瀏覽項目的資產,例如軟件代碼、問題、文檔和拉取請求;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"快速評估軟件系統或組件的產品和流程質量,這在現代軟件重用實踐中是很常見的需求;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"配置、構建、運行和調試第三方代碼;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"設置和運行具有不同軟件和硬件需求的軟件密集型系統。在我開設的課程中,涉及的平臺包括手機、汽車電子、應用服務器、數據庫、容器、物聯網設備和嵌入式設備;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"選擇現實的貢獻目標。(一開始,學生往往會高估他們爲項目做出貢獻的能力。)這是敏捷開發衝刺中的一項關鍵活動;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"閱讀第三方代碼,找到需要添加或修復代碼的位置;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過添加新特性或修復錯誤來改進大型第三方系統;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"編寫測試,證明自己的貢獻在現在和將來都能按預期運行;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用由多種編程語言和工具開發的軟件系統;學生經常驚訝地發現,只掌握集成開發環境(IDE)的相關知識就想爲項目做出貢獻是遠遠不夠的;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲他們的工作編寫文檔,通常使用聲明性標記語言,例如Markdown或文檔生成器代碼註釋;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"遵循複雜的配置管理(版本控制)流程,例如處理問題分支和重新提交代碼;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過預提交和持續集成檢查和測試。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上述社交和技術學習成果都與現代行業環境息息相關——它們遠遠超出了ACM\/IEEE軟件工程課程的推薦學習範圍。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"同時,這種課程的實踐還遵循了許多ACM\/IEEE課程指南(注3)的要求,具體包括:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"個人技能的鍛鍊,例如批判性判斷、有效溝通和認識到自己的侷限性(課程指南8);培養自主學習的技能(指南9);理解解決軟件工程問題的多個維度(指南10);使用合適和最新的工具(指南12);構建一個真實世界的基礎(指南14);並通過各種教學和學習方法進行教育(指南18)。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"在軟件工程課程中融入開源開發實踐"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我的這堂必修的開源軟件貢獻課程是名爲“實踐中的軟件工程”的三年級課程的一部分。(本課程在2019年獲得了管理學院的卓越教學獎。)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們每年向大約20-50名學生教授這門課程,他們學習由雅典經濟與商業大學管理科學技術學院設置的“軟件和數據分析技術”專業。該課程也是這所大學信息學院的推薦選修課。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該課程使用了一種(輕量)翻轉課堂方法(注4)進行教學,並完全通過課程作業評價成績。開源貢獻部分佔課程成績的50%。學生可以單獨或結對完成作業。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"結對是爲了幫助可能信心不足的學生,不過在這種情況下,結對的學生必須完成比獨立學生更多的作業,而且倆人的貢獻必須分別放在不同的GitHub帳戶裏。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們根據學生在線提供的開源項目成果、他們的期末書面報告和課堂演示來評估學生的表現。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們根據學生在線提供的開源項目成果(代碼提交和交互)、他們的期末書面報告和課堂演示來評估學生的表現。三場演示分別安排在大約第4周(描述所選項目)、第8周(概述準備做出的貢獻)和第14周(總結貢獻的實現)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讓貢獻獲得項目接收並不是通過考覈的先決條件,但貢獻通過會有加分。其他考覈要素包括學生對他們選擇的項目的理解和文檔撰寫、貢獻的廣度、實現質量、代碼與項目的集成水平、測試實現、與項目開發團隊的合作過程、口頭陳述、書面報告的質量,以及在版本控制、代碼審查、問題管理和文檔編寫等活動中使用可用工具鏈的情況。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從理論上講,作弊(複製他人項目分支的貢獻,或者找別人完成作業)是可能存在的問題;爲了預防作弊,我們讓學生在課堂上展示他們的作品,並讓學生認識到他們的(公共)貢獻會成爲他們工作技能組合的一部分,還可能會被未來的潛在僱主詢問。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該課程每年都會安排一兩位專職助教,他們會開設針對關鍵工具的實驗室課程,並在辦公時間爲學生提供常見疑難答覆。他們爲支持課程付出了很多辛勤勞動,這也意味着如果要增加學生人數,就需要相應地增加助教人數。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"實現成功的開源貢獻"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"學生們都是懷着惶恐的心情開始課程學習的,到結課時都非常興奮。要讓學生爲開源項目做出有意義的貢獻,需要考慮到他們缺乏經驗的背景,並與現代開源軟件開發的快節奏與複雜性之間取得平衡。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在我教授這門課程的這些年裏,我看到爲開源項目做出貢獻變得越來越容易了。開源項目變得更具包容性。許多項目簡化了入門和指導流程,團隊也更加多樣化(女性領導更多了),公開的聯繫方式是很常見的,回覆也通常很有禮貌,並且大都支持Windows構建(儘管一些學生採用Linux以避免出差錯)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於精心設計的拉取請求工作流、持續集成的廣泛採用、多樣化的代碼檢查機器人、友好的代碼審查流程,以及使用拉取請求草案對工作進程進行增量審查的設計,對開源項目做出貢獻變得愈加輕鬆。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"學生們深入參與的開源項目環境與他們在傳統學術作業中體驗的常見環境相去甚遠。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儘管如此,學生們深入參與的開源項目環境與他們在傳統學術作業中體驗的常見環境還是相去甚遠。因此,唯一現實的目標就是隻做一些小規模的貢獻。讓課程作業取得預期效果的關鍵在於,教師對學生的貢獻不能抱(看起來很大的)指望。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於一個本科生來說,做出開源貢獻往往是一件門檻非常高的事情,所以在一個大項目中集成20行代碼就稱得上是一項成就了。我們給學生挑選項目的建議可以總結如下。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"選擇一個有多個活躍貢獻者的項目,這樣就有一個社區來指導你並回答你的問題。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"選擇一個相對流行的項目(一些GitHub明星),項目應該證明自己提供了有用的功能並且以相對合理的方式開發。你應該避開GitHub上被廢棄的那種論文項目。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"避開非常受歡迎的項目,這樣你的貢獻就不會被競爭、噪音和官僚主義淹沒。(儘管如此,我們還是有學生參與了一些衆人皆知的項目,例如Tensorflow和VisualStudioCode。)"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"做好驗證,確保你可以在自己的計算機上構建和運行項目。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"確認項目會定期接受來自外部的拉取請求,這樣你纔有機會。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"嘗試提供一個微不足道的修復作爲熱身練習,並測試你遵循項目工作流程的能力。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查找標記爲“Goodfirstissue”的項目問題,這表明項目對新貢獻者開放。(有幾個在線列表統計了包含這類問題的項目。)"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們將貢獻的選擇權完全留給學生:他們可以從項目的問題數據庫中選擇一個開放的任務,或者提出他們自己的增強或修復。學生在與項目的核心團隊互動後也經常改變策略。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儘管讓他們自由選擇自己的貢獻路線似乎讓作業變得太容易了,但我們發現這種背景下大約一半的學生貢獻都能被項目接收。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"學生在作業中面臨的最常見問題是無法構建項目(通常是由於缺乏經驗和平臺不兼容)以及項目團隊缺乏溝通(學生會產生不必要的焦慮情緒,認爲他們的貢獻必須被項目接受纔行)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另一方面,學生們發現他們的代碼集成到了被全球使用的生產軟件中時是最興奮的。在課程評估中,學生往往非常滿意他們在完成開源軟件貢獻任務後獲得的許多實踐技能和自信心。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"size","attrs":{"size":10}}],"text":"參考文獻:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"size","attrs":{"size":10}}],"text":"Brooks, F.P., Jr. The Mythical Man-Month. Addison-Wesley, Boston, MA, 1975, 32."}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"size","attrs":{"size":10}}],"text":"Spinellis, D. Future CS course already here. Commun. ACM 49, 8 (Aug. 2006), 13;"},{"type":"link","attrs":{"href":"https:\/\/bit.ly\/3bYxSJs","title":"","type":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/bit.ly\/3bYxSJs"}],"marks":[{"type":"italic"},{"type":"size","attrs":{"size":10}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"size","attrs":{"size":10}}],"text":"The Joint Task Force on Computing Curricula. Curriculum Guidelines for Undergraduate Degree Programs in Software Engineering. ACM. New York, NY;"},{"type":"link","attrs":{"href":"https:\/\/bit.ly\/3vn04NP","title":"","type":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/bit.ly\/3vn04NP"}],"marks":[{"type":"italic"},{"type":"size","attrs":{"size":10}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"size","attrs":{"size":10}}],"text":"Tucker, B. The flipped classroom. Education Next 12, 1 (Mar. 2012), 82–83."}]}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"作者介紹"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Diomidis Spinellis([email protected])是希臘雅典經濟與商業大學管理科學與技術學院軟件工程課程教授,並在荷蘭代爾夫特大學軟件技術學院教授軟件分析技術。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"原文鏈接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/cacm.acm.org\/magazines\/2021\/7\/253459-why-computing-students-should-contribute-to-open-source-software-projects\/fulltext","title":"","type":null},"content":[{"type":"text","text":"https:\/\/cacm.acm.org\/magazines\/2021\/7\/253459-why-computing-students-should-contribute-to-open-source-software-projects\/fulltext"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章