爲什麼一些好的開發工具會被束之高閣?

{"type":"doc","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":"時過境遷,編程人員對程序合成(program synthesis)等概念已耳熟能詳,甚至已上手了某種驗證工具。以高級開發工具研發爲基礎,市場上推出了多種得到廣泛使用的產品,甚至Facebook 已經企業內部"},{"type":"link","attrs":{"href":"https:\/\/engineering.fb.com\/2018\/09\/13\/developer-tools\/finding-and-fixing-software-bugs-automatically-with-sapfix-and-sapienz\/","title":"","type":null},"content":[{"type":"text","text":"部署了"}]},{"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":"本文將淺析開發人員對高級工具的期望,以及所發生的退步。下面給出的三款工具出現於過去30年中,儘管我對它們的個人評價很高,但經我實測,均已無法正常運行。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"反射模型(Reflexion Model)"}]},{"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":"1995年,就讀於華盛頓大學的年輕研究生Gail C. Murphy提出了一種理解代碼庫的新方法,稱爲“反射模型”(reflexion model)。具體描述爲:"}]},{"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":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/80\/80ad56d6348b81b4ab57f045b6c9d615.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"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":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/b0\/b0307f7e7dffba7d9650811dc4d2cc3f.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"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":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/3b\/3b8960b6dc5935752cc398d88088f94a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"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":"大約同時,微軟的一個研究小組也在開展一項實驗。該實驗的目的是驗證是否能改造Excel代碼庫,從中抽取出部分高層組件。這需要對代碼庫具有相當深入的理解,考慮到該小組與Execl開發團隊完全沒有交集,實現此事並非易事。研究小組中有人看了Gail關於“反射模型”的宣講,深以爲然。"}]},{"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":"他用一天的時間就建立了首個Excel反射模型,通過日漸熟悉代碼而不斷修正模型。在隨後的四周時間中,他對代碼的理解達到了先前預估需兩年時間才能企及的程度。"}]},{"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":"時至今日,Gail發佈的RMTool已無法從因特網公開獲取,其所基於的AT&T C++分析工具Ciao同樣也從因特網下線。儘管有人隨後使用Java重寫並實現爲JRMTool,但其僅能用於Eclipse的早期版本,完全不適用於當前的API了。JRMTool採用Java 1.4編寫,當前的Java發行版在語法上做了徹底更改。因此,我完全放棄了嘗試獲取代碼並編譯運行的想法。"}]},{"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":"時至2021年,軟件工程依然無法超越1995年的水平。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"WhyLine"}]},{"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":"時間又過了十年,卡內基梅隆大學人機接口(HCI)研究所的Amy Ko思考着另一個問題。調試過程就像是當偵探,爲什麼程序不在完成取數(fetch)後更新緩存?其中負數起了什麼作用?爲什麼解答此類問題如此費勁?"}]},{"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":"上述想法促成Amy設計了一種稱爲WhyLine的工具。WhyLine提供交互式調試界面,用戶可提出“爲什麼某事會發生?”之類的問題。WhyLine在圖像編程工具Alice中實現了一個原型。Alice是CMU實現的圖形化編程工具,即便是兒童都可生成三維動畫,令人印象深刻。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/70\/70d6eefa0e2d64f69c14bc60d08cb31b.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"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":"Amy基於原型的成功,又歷經數年努力,建立了針對Java語言實現該功能的技術。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/31\/31c31d5d9f57791db294c9ce64710c53.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/f6\/f61ef1c31a0df10de2c210856aa4913a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"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位程序員去修復存在於ArgoUML中的兩個錯誤,這是一個15萬行Java代碼的程序。一半參試程序員使用Java WhyLine。實驗結果表明,相比未使用WhyLine的程序員,使用WhyLine程序員的成功率提高了四倍,工作速度提高了兩倍。"}]},{"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":"我在幾年前曾試圖使用現代Java字節碼平臺去運行JavaWhyLine,但是程序崩潰了。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"MatchMaker"}]},{"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":"2008年,我的導師 Armando Solar-Lezama 加入MIT,一手恢復了程序合成(program synthesis)領域的研究。他過去主要關注小型系統中的複雜問題,包括優化物理仿真和位交錯(bit-twiddling),目前正轉向解決大型系統中的簡單問題。"}]},{"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":"大多數的編程工作其實是在編寫“膠水代碼”,只需釐清如何組合使用大量的標準組件庫。要明確如何使用複雜框架執行特定操作,可能需要花數週時間深入閱讀文檔。程序合成技術是否能在其中發揮作用?這正是來自哈薩克的天才Kuat Yessenov研究去解決的問題。"}]},{"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":"使用膠水代碼的通常規則,是弄清楚需使用的具體類和方法。有時程序員能猜測得八九不離十。例如,Android中使用Container類的"},{"type":"codeinline","content":[{"type":"text","text":"addView"}]},{"type":"text","text":"方法即可在屏幕上部署小組件。但更多情況下是不容易猜到的。例如,在編寫一個能高亮顯示語法的Eclipse插件時,需要鏈接使用四個類,關聯"},{"type":"codeinline","content":[{"type":"text","text":"TextEditor"}]},{"type":"text","text":"對象與"},{"type":"codeinline","content":[{"type":"text","text":"RuleBasedScanner"}]},{"type":"text","text":",示例代碼如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"class UserConfiguration extends SourceViewerConfiguration {\n IPresentationReconciler getPresentationReconciler() {\n PresentationReconciler reconciler = new PresentationReconciler();\n RuleBasedScanner userScanner = new UserScanner();\n DefaultDamagerRepairer dr = new \n DefaultDamagerRepairer(userScanner);\n reconciler.setRepairer(dr, DEFAULT_CONTENT_TYPE);\n reconciler.setDamager(dr, DEFAULT_CONTENT_TYPE);\n return reconciler;\n }\n}\n\nclass UserEditor extends AbstractTextEditor {\n UserEditor() {\n userConfiguration = new UserConfiguration();\n setSourceViewerConfiguration(userConfiguration);\n }\n}\nclass UserScanner extends RuleBasedScanner {...}"}]},{"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":"如果能推斷出某個功能的兩個端點,哪些類使用了它,以及哪些類提供它,那麼中間過程就可交給計算機去操心。當然,還有其他一些程序能實現這樣的功能。通過運行這些程序並做分析跟蹤,就能找到作爲指針引用鏈負責“鏈接”兩個類的代碼。這樣,程序引用就能具體歸結到確切實現功能的代碼。基於這一理念,MatchMarker應運而生!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/8a\/8a4158eb2075f4b0795d8a4fa6e70369.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"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位程序員去構建一個基本的Eclipse語法高亮顯示功能,高亮顯示一種新語言中的兩個關鍵字。該研究爲半數參試程序員提供了MatchMaker及其基本教程。該教程中的確給出瞭如何去執行操作,但是其中內容繁雜,並沒有多大幫助。對照組歷經波折,平均100分鐘完成。而使用MatchMaker的一組很快就摸清了門路,平均只用了50分鐘。鑑於具有5年經驗的Eclipse專家耗時16分鐘,這一結果相當不錯。"}]},{"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":"事實上,我非常瞭解Matchmaker,因爲我讀研的第一個月就被安排參與推進該項目。我很喜歡該項目,推動了項目的擴展並支持Android。但該項目也退步了。幾年前,我的導師引進了一名暑期實習生去開發MatchMaker。但他很快就碰上麻煩,MatchMaker無法在Java 8上運行。"}]},{"type":"heading","attrs":{"align":null,"level":2},"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":"link","attrs":{"href":"https:\/\/www.eclipse.org\/mylyn\/?fileGuid=Rj6VWG3wggRcKW66","title":"","type":null},"content":[{"type":"text","text":"Mylyn"}]},{"type":"text","text":"成爲最受歡迎的Eclipse插件之一,“反射模型”這一理念仍然籍籍無名。這完全可歸因爲模型的提出者Gail C. Murphy決心投身學術界,而她的學生、Mylyn的創建者Mik Kersten,則選擇了加入工業界。"}]},{"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":"link","attrs":{"href":"http:\/\/www.pathsensitive.com\/2018\/09\/my-interview-with-future-of-coding-on.html?fileGuid=Rj6VWG3wggRcKW66","title":"","type":null},"content":[{"type":"text","text":"此前曾提出"}]},{"type":"text","text":",構建工具的難度更多地取決於編程語言的複雜性(編程語言的複雜性,由C++即可見一斑),而非取決於研究理念。在變革性理念出現之前,如果構建工具的銷售量不足以支撐其巨大的固定成本,那麼不可能推出任何新的工具。這正是我博士研究致力於簡化工具構建的初心所在,也是我對那些不夠先進但是免費工具的泛濫痛心疾首的原因。這些工具導致市場低迷,工具開發商難以收回成本。"}]},{"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":"http:\/\/www.pathsensitive.com\/2021\/03\/developer-tools-can-be-magic-instead.html?m=1&fileGuid=Rj6VWG3wggRcKW66"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章