當前位置:
首頁 > 科技 > 軟體技術雜談專欄開場白:我對技術的理解

軟體技術雜談專欄開場白:我對技術的理解

作者|周明耀

編輯|小智

寫在前面

Amazon 的 CTO Werner Vogels 博士有一句名言「All things Distributed」,我想說的是「All things are Software」。他是我的男神,我以他為榜樣、目標。

今天這篇文章是系列文章的開場篇,我不討論具體的技術問題,只是談談對於軟體開發的理解。為什麼會是雜談?因為後續的文章,我力爭每個月都有一篇發布,話題雜而力求專,很多都是針對單一技術點或者冷僻技術點的深入介紹,而這些技術點又和生活本質相結合,希望您會喜歡。

冷僻技術點

這裡說的冷僻技術點並不是真的冷僻,而是會關注到的人不多,或者國內目前沒有這一方面的文章。舉個例子,JDK 里的 HashMap,JDK7 和 JDK8 的實現有一定差異。

JDK7 中,當 HashCode() 的返回值相等時,HashMap 會在 LinkedList 里存儲對象,導致 HashMap 整體的時間複雜度在 O(1) 到 O(N) 之間波動。JDK8 更新了 HashMap 內部的實現,當複雜的 HashCode 數量超過一個臨界值後,會以紅黑樹的形式存放對象,從而將整體的時間複雜度縮小至 O(1) 到 O(log(n)) 的範圍內。

我們看一個示例。定義一個 Key 類並實現 Comparable 介面,為了比較最壞情況下的 O(n) 和 O(log(n)),重寫 HashCode() 並返回一個定值。

主調用類:

運行結果:

如果將對象數量增加到 50000,即 keyNum=50000,你會看到耗時對應增加:

如果 key 類沒有實現 Comparable 介面,Java 會通過調用 tieBreakOrder(Object a,Object b) 方法來比較鍵的順序。tieBreakOrder(Object a,Object b) 方法方法會先通過 getClass().getName() 比較類名大小,再用 System.identityHashCode 決定順序。這一過程的成本相當高,我們也做了測試,採用這種方式時,JDK7 和 JDK8 基本沒有性能差距。

為什麼會有這樣的結果差異?因為 JDK8 將 HashMap 的內部檢索實現改為了紅黑樹方式,當 Key 類實現了 Comparable 介面時,JDK8 通過紅黑樹將 HashMap 最壞情況下的時間複雜度降低為 O(log(n))。目前的臨界值為,當 HashMap 的容量大於 64,且重複的 HashCode 數量達到 8 的時候,將 LinkedList 轉變為紅黑樹。如果 Key 類不可比較,反而成本會更高。

為什麼寫專欄

當下的軟體從業者,都受過良好的計算機和軟體方面的教育,特別是近幾年,軟體開發發展到一定成熟度之後,對於從業者的學歷背景、基礎知識、動手能力、學習能力越來越看重。但是現代的計算機和軟體方面的教育,基本上都是從科學研究領域脫胎出來的,教育的目的也理所當然的主要是為科學研究領域服務。而隨著社會的發展,軟體不斷地滲透到不同的業務領域,涉及普通人生活的方方面面。以科學研究為目的的軟體教育,和日益深入人們生活的軟體應用,產生了很大的隔閡。以致很多計算機和軟體專業畢業的學生,進入企業工作後,總是感嘆學校所學習的知識排不上用場,必須得重新學起,才能夠達到企業的要求。

即便在公司站穩腳本,很多公司都有軟體工程師,有多少軟體工程師理解自己在公司的願景?我的了解是,不多。很多工程師每隔幾年,或者更短的時間,就會迷茫一次。公司有願景,並不代表軟體工程師的個人願景清晰,希望我的這些文章能夠讓大家減少迷茫,樹立技術願景,把您拉回技術情懷,不要迷茫,因為那太費時間了。

軟體工程師

軟體工程師作為一種嚴肅的職業已經存在 70 多年了(二次大戰結束後)。全球目前有至少數百萬軟體工程師,這還不包括人數眾多的學生、編程愛好者(他們非常認真地編寫程序,但不以此為謀生之道)。

Gace Hopper 在 1961 年寫下了這些文字:「軟體工程師是一個古怪的群體,他們崛起的速度很快,很快就形成了獨立的職業,並且過早地感染了不願做出改變的抗性。我曾經聽說有些軟體工程師因為客戶不願意修改自己的系統而斥責客戶,而有時走進我的辦公室,要求堅持他的想法。處於這個原因,我在辦公室懸掛了一個逆時針走動的時鐘。」。

軟體工程師是一種有趣的工作,而大多數軟體工程師都很享受工作,這樣就不難理解了,為什麼難以管理他們?如果有人付錢讓你開心地玩,你還會願意受制於人嗎?受人管制就會減少工作中的樂趣!

從許多方面看,軟體工程師之間的差異非常大,只有很了解程序設計的人才能完全理解這一點,事實上,軟體工程師之間的差異主要來自個人內在因素,而不是外在屬性。大多數公司的高層管理者對所有軟體工程師一視同仁 ,這種看法是片面的。微軟公司的 Bill Gates、Adobe 公司的 John Warnock、FaceBook 公司的 Mark Zuckerberg 都沒有犯這樣的錯誤,因為他們本質上也都是軟體工程師。這也是為什麼我覺得某些大型軟體企業需要變革的原因,在科技界,你最好不要讓非技術出身的人擔任 CEO。

也不是計算機專業畢業的人才能做軟體工程師。有一個同事,以前是學法律的,後來轉行寫代碼,寫出的代碼比很多寫的年份多得多的人還強的多。她對法律相關的思維的縝密,很好地就轉移到了代碼邏輯的縝密上,不學自通。這就是軟體工程師,你用正常思維理解不了他們的成長路線。

軟體是人類行為的模擬

軟體的歷史,可以說是用機器模擬人的歷史的進一步發展。在計算機出現前,人們用機器來代替人進行生產,也就是所謂的機械化生產。軟體的出現,也許很多人沒有意識到,包括這個歷史過程中的參與者,實際上是人類有意無意地在計算機上模擬自己這種原始動機的體現。人們對於時間的恐懼,導致了人們延長自身生命的努力,提升自己的生產力是其中的一種途徑。而軟體則讓人們能夠節省大量的工作時間,有更充分的時間去關注並推進自身的核心生命周期。

因此,可以認為軟體的主要目的,就是把人類生活的非核心生命周期軟體化、虛擬化,以提供更低的成本和更高效率的新生活,讓核心生命周期的運行能夠更加容易,讓非核心生命周期的處理更少地佔用人類的時間,變相地延長人類生命。

說到這裡,如果 60 年代有社交媒體,我相信大家也會在那裡驚呼:「喔!!軟體來了,我們都要失業了!」,和現在對於人工智慧的恐懼是一樣的。

技術和業務的關係

業務和架構,是壓在軟體從業人員身上的兩座大山。軟體並不是虛無縹緲的東西,它和現實生活是緊密相關的。業務和架構都是處理人的問題。而技術人員最討厭處理的就是人的問題,內心厭惡,卻又無法逃避。因為這個排斥的心理,工作中始終想避開和人有關係的地方。因此在做技術之前,還需要做一些準備工作,用來連接現實生活,讓大家知道處理人的問題並不可怕。建立了這個相關性,每個人就都可以自行思考了。

其實對於做軟體的技術人員而言,技術也可以分為兩部分:一部分是軟體技術,另一部分是業務技術。當前軟體行業所說的技術,基本上都是指軟體技術和計算機相關的技術,也就是軟體的訪問生命周期所涉及的技術,比如服務、存儲等相關技術。軟體技術大部分集中在軟體的訪問生命周期部分。業務技術這一塊,軟體工程則較少涉及。這部分主要隱藏在業務邏輯中。因此在談技術時,只談軟體技術是遠遠不夠的。而不管是軟體技術還是業務技術,均來源於對現實生活問題的解決,現實生活才是軟體工程師真正的養成來源。

時間恐懼

為什麼軟體工程師會有時間恐懼和壓力呢?其原因是他們把按時完成自己的工作當成了自己的最大利益。人對時間的壓力是與生俱來的,並且對業務的不了解也會導致他們沒有太大的把握。這一問題在其他行業的表現並不明顯,畢竟在其他行業,軟體工程師主要處理的是本行業的問題,對業務比較熟悉。軟體行業則較特殊,通常是以業務的問題是否解決為判斷標準,是在解決另一個行業的問題,這一點提高了對軟體工程師的要求。這就要求軟體工程師把完成業務的工作當成自己的最大利益,深入到業務中去。隨著對業務的熟悉,對時間的恐懼才會慢慢地消失。對業務領域理解得越深入,就越知道如何去發現問題,慢慢就成為業務專家了。只有做到這一點,才能在業務領域建立自信,成為一個合格的軟體工程師。

還有另一種很普遍的現象,做技術的軟體工程師往往看不上業務。覺得技術更高端,而業務太平凡、太低端,並且業務人員總是給技術挖坑。而業務人員則覺得做技術的眼光高,但總是理解有偏差。技術人員往往對業務一知半解,業務問題總是解決得不圓滿。但業務人員對此又無可奈何,因為自己不懂技術。做架構的人必須親身體驗業務,感受業務,才可能真正認識業務的個性,真正認識業務所面臨的的問題。在理解業務個性的基礎上,才能夠談共性。否則這個抽象就像是無根之木,局限於個人的主觀認識,很難長大。

軟體技術的發展

從馮. 諾依曼結構開始,程序邏輯開始脫離硬體,採用二進位編碼。軟硬體兩者結合,一個可編程的大腦出現了,這也是為什麼我們把計算機叫做電腦的原因。在硬體上運行的程序就是軟體,用來控制硬體的行為。通過軟體的編寫,可以製造出各種各樣具備不同能力的「人」,而說花的時間比培訓一個真正的人少。

隨著半導體技術的進步,硬體的成本越來越低,性能越來越高,摩爾定律:當價格不變時,集成電路上可容納的元器件數目,約每隔 18-24 個月增加一倍,性能提升一倍。軟體方面,為了簡化難度,開始採用彙編語言,進一步出現了類似於人類語言的高級語言,比如 C/C++/Java 等,這使得人類可以用類似於人的語言,把人類的知識傳遞給計算機,訓練計算機掌握某種技能。記得 20 年前我剛開始學習編程的時候,學習的是類似於 Basic 的高級語言,等我讀大學時,首先接觸的是 C 語言,使用 Turbo C 編寫 C 語言調試不太方便,後來逐漸學習了 Java、.NET、GO,每一樣都更加方便、抽象,學習起來更快。

軟體危機之前,我們是沒有軟體工程理論支撐的,那時出現了對於行業的質疑,也為後續美國的「登月計劃」帶來了技術上的困難。因此,逐漸出現了瀑布式軟體開發流程,並隨著時間的推移,形成了 SDLC 等實踐性方案,為大公司提供完整的軟體開發體系流程。但是隨著互聯網的出現,中小型的軟體公司不斷湧現,我們發現瀑布式管理流程已經不符合我們的實際需求,現實世界要求更快的思維變換,因此逐漸出現了迭代開發、敏捷開發、XP,因為他們能夠支撐業務對於技術輸出、產品實現的需求。

編碼的理解

計算機專家在問題求解時非常重視表達式簡潔性的價值。Unix 的先驅者 Ken Thompson 曾經說過非常著名的一句話:「丟棄 1000 行代碼的那一天是我最有成效的一天之一。」這對於任何一個需要持續支持和維護的軟體項目來說,都是一個當之無愧的目標。早期的 Lisp 貢獻者 Paul Graham 甚至將語言的簡潔性等同為語言的能力。這種對能力的認識讓我們把可以編寫緊湊、簡介的代碼作為許多現代軟體項目選擇語言的首要標準。

軟體技術的相通性

Java 語言有自己的垃圾回收器,為了加快 GC 的回收速度,HotSpot 的歷代 GC 都有自己的不同的設計方案,Java9 會使用為默認 GC 的是 G1 GC。G1 GC 的 Region 設計方案。區間概念在軟體設計、架構領域並不是一個新名詞,關係型資料庫、列式資料庫最先使用這個概念提升數據存、取速度,軟體架構設計時也廣泛使用這樣的分區概念加快數據交換、計算。

看看 HBase 的 RegionServer 設計方式。在 HBase 內部,所有的用戶數據以及元數據的請求,在經過 Region 的定位,最終會落在 RegionServer 上,並由 RegionServer 實現數據的讀寫操作。RegionServer 是 HBase 集群運行在每個工作節點上的服務。它是整個 HBase 系統的關鍵所在,一方面它維護了 Region 的狀態,提供了對於 Region 的管理和服務;另一方面,它與 Master 交互,上傳 Region 的負載信息上傳,參與 Master 的分散式協調管理。

1

HRegionServer 與 HMaster 以及 Client 之間採用 RPC 協議進行通信。HRegionServer 向 HMaster 定期彙報節點的負載狀況,包括 RS 內存使用狀態、在線狀態的 Region 等信息,在該過程中 HRegionServer 扮演了 RPC 客戶端的角色,而 HMaster 扮演了 RPC 伺服器端的角色。HRegionServer 內置的 RpcServer 實現了數據更新、讀取、刪除的操作,以及 Region 涉及到 Flush、Compaction、Open、Close、Load 文件等功能性操作。

Region 是 HBase 數據存儲和管理的基本單位。HBase 使用 RowKey 將表水平切割成多個 HRegion,從 HMaster 的角度,每個 HRegion 都紀錄了它的 StartKey 和 EndKey(第一個 HRegion 的 StartKey 為空,最後一個 HRegion 的 EndKey 為空),由於 RowKey 是排序的,因而 Client 可以通過 HMaster 快速的定位每個 RowKey 在哪個 HRegion 中。HRegion 由 HMaster 分配到相應的 HRegionServer 中,然後由 HRegionServer 負責 HRegion 的啟動和管理,和 Client 的通信,負責數據的讀 (使用 HDFS)。每個 HRegionServer 可以同時管理 1000 個左右的 HRegion。

2

再來看看軟體系統架構方面的分區設計。以任務調度為例,假設我們有一個中心調度服務,那麼當數據量不斷增多,這個中心調度服務一定會遇到性能瓶頸,因為所有的請求都會最終指向它。為了解決這個性能瓶頸,我們可以將任務調度拆分為多個服務,即這多個服務都可以處理任務調度工作,那麼問題來了,每個任務調度服務處理的源數據是否需要完全一致?根據某通信大廠公布的專利發明,顯示他們對於每一個任務調度服務有數據來源區分的操作,即按照任務調度數量對源數據進行劃分,比如 3 個任務調度服務,那麼源數據按照行號對 3 取余的方式劃分,如果運行了一段時間之後,任務調度服務出現了數量上的增減,那麼這個取余劃分需要重新進行,要按照那個時候的任務調度數量重新劃分區間。

這裡舉這三個貌似不同領域的示例,為的是說明三者的設計思路其實是相同的,或者說是源於同一種演算法。

我的理解

我自己從事軟體開發行業已經 13 年,真正接觸編程是 16 歲,這麼算下來就超過 20 年的編程經驗。在這 20 年之間里,軟體開發方式發生了巨大的變化。瞬息萬變是這個時代的特徵,固守經驗、一成不變是錯誤的行為。我們看一看雲計算的出現就知道了,雲計算定義了一種按需索取、實時供應的特性,它本身就是敏捷的,它為軟體工程注入了新的活力,如果軟體開發人員可以快速、自由地獲取開發過程中所需的各種資源,那麼軟體開發必將迎來一次飛躍式的發展。這也就是為什麼公有雲服務、Serverless 計算會開始流行的原因。

寫在最後

公交車有起點有終點,對我來說,為人民服務只有起點沒有終點,對他 (馬雲) 來講,美國上市不是終點,也只是一個新的起點。

這句話是杭州公交公司的孔勝東師傅說的。從 1986 年開始,他在中山北路和百井坊巷四岔路口設立義務修車點,無論酷暑嚴寒,颳風下雨,每個周六晚上 7 點到 10 點,他都在那裡。因此孔師傅成了全國勞動模範、浙江道德模範。其實他還有另外的身份,17 大代表、馬雲同學。無論哪個標籤,都沒能阻止他繼續在路邊幫人免費修車,這是出於內心的熱愛,無論您怎麼看,我覺得他的內心是為人民服務,所以才能堅持。這也是我開這個專題的目的,因為熱愛,所以選擇。

下一篇寫什麼,我想針對 Apache Cassandra 內部的一些實現演算法寫一篇文章,為什麼是 Cassandra,因為它在 3.X 版本發布後做了較大程度的改進,而國內缺少這一方面的資料,導致國內技術人員對它的映像不好,我開這個雜談專欄,就是為了找到燈下黑。

作者介紹

周明耀,2004 年畢業於浙江大學,工學碩士。13 年軟體研發經驗,近 10 年技術團隊管理經驗,4 年分散式計算、大數據技術經驗。著有《大話 Java 性能優化》、《深入理解 JVM&G1 GC》、《技術領導力 - 如何帶領一支軟體研發團隊》,InfoQ 專欄作家、IBM 開發者論壇專欄作家,個人提交發明專利 16 項。個人微信號 michael_tec,個人公眾號「麥克叔叔每晚 10 點說」。

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 InfoQ 的精彩文章:

這是一份詳細的Apollo自動駕駛平台上手指南
如何面試工程師?
Pivotal 劉偉光:微服務帶熱 Spring 我們也該走到台前了
想轉行做資料庫工作?這些你必須了解!
gRPC 服務端創建和調用原理解析

TAG:InfoQ |

您可能感興趣

軟體技術必看
染髮技術蓋白髮技術原理
技術相對論之軟體架構
農產品:核桃栽培技術及幼苗的管理技術
技術語硬碟的物理結構和原理
農業技術:檸檬種植管理修剪技術
在技術層面上,如何理解書法術語——「顏筋柳骨」?
應用軟體智能分析技術
技術消費品的研究體會
對於新媒體,傳播技術比製作技術更重要
舞蹈軟開度練習——踢腿的技術技巧
農業技術:盆栽草莓管理技術
生物技術中的變魔術——魔法剪刀
麻省理工的一個研究小組已經開發出人造突觸技術用於腦晶元技術
農業種植技術:觀賞型鳳梨生長期管理技術
氣派科技CPC封裝技術專題
專業鋸片的研發設計與實用技術的研究 博野精密工具
突破!科學家開發的綿羊-人類雜交技術解決器官供體短缺問題
蘋果自動技術專利技術曝光 開車像在打遊戲
電裝與軟體產品開發商合作 加速信息技術的發展