這篇噴微軟技術平臺的文章,寫的還是比較到位的;推薦一讀,儘早解除對微軟的“迷思” - 它曾經對Li...
2008年之前,我是微軟的熱情支持者,鐵桿兒粉,後來Vista的慘敗讓我逐漸清醒,慢慢脫離其技術體系,最後變成微軟鐵桿兒的質疑者。在我多年的開發經驗、印象中,在微軟平臺上的技術積累,除了演算法、開發規範、工程經驗這些通用的知識,基本上就沒有能積累下來的。它三天兩頭的變、變、變,你只有疲於奔命的份。有興趣的朋友,可以讀讀這篇文章:行進中開火 。作者曾是微軟員工,也是stackoverflow的聯合創始人。關於微軟手機的慘敗,可以看看我這篇總結的文章:一部微軟手機的潰敗史。還有這篇:Windows Phone,愛過
Windows Phone 7的時候,IT之家開發了客戶端,等Windows Phone 8出來了,好多都要重寫一遍,從8到8.1,該完善的都完善了,結果10出來了,要開發UWP,還要重寫一遍,這個平臺不死誰死……
珍愛生命,遠離微軟!
別用微軟的東西。商業目的性太強,千萬別被微軟牽著鼻子走,血淋淋的教訓。微軟推出的垃圾多了去了。它什麼都想做,很多都沒做好:
1. MFC:Win31時代出生,Win95、98時壯大,雖然一直在更新,但是介面和概念都太老氣。你要做現代介面,大量東西要自己手工去弄。同一個介面,一個熟悉MFC的程式設計師需要開發2周,而一個剛剛學習 Qt一個月的大學生,三天就搞定了。
2. WTL:好幾個百萬 DAU量級產品都試用過,最後都放棄沒用了,微軟也不怎麼管了。
3. SilverLight:對抗 Flash,當年剛推出的時候,被微軟碰成下一代桌面/web的統一解決方案,有的人真的去用了,結果呢?傻逼了。想找點第三方控制元件,少的要死,想招人也招不到,最後切換會flash去。
4. ASP•Net:當年微軟到高校裡面忽悠大學生學,學了半天,就業了,發現網頁全部是 linux下的解決方案,傻逼了。一線的網際網路公司就沒有使用 SqlServer+ASP•Net的,都是清一色開源免費。
5. C#:這個還算好的了,十多年前照樣當年騙著大學生學,說是比 java好很多。我很多年收到的學生簡歷都是精通C#,問題是十多年都過去了,看看今天的 TIOBE排行榜,java的分值是 c#的 4倍以上,服務端開發web/非web,企業級開發,java都是完爆 c#,更別說java開發 android裝置的app了。微軟的話再次沒算數,當年學了很長時間 c#的學生,工作後碰都不會碰一下。
6. XNA:笑話一個,當年搞了好多 XNA遊戲開發大賽,告訴大家 XNA就是遊戲開發的明天,可以快速搭建小型遊戲,或者快速編寫遊戲demo供驗證。我們在評估使用什麼給新人做 Demo用,最後評估下來,Python+Panda3D,易用性比 xna強幾條街呀。
7. DirectMusic+DirectInput+DirectPlay:全都傻逼了。
8. 聲音方面: Wave介面 -> DSound介面 -> CoreAudio介面,它就穩定不下來的。
微軟的思路就是看著一個開發工具好,然後自己也要搞一套,然後藉著自己強大的影響力,哄騙所有人來用他們的東西,最後大家用下來還是覺得開源的好。
微軟的介面解決方案:GDI/Win32自己畫,MFC/GDI自己畫,基於Win32的各種介面庫,WPF,SilverLight,Direct2D,看得你都不知道選哪個,但是你要做現代流行介面的話,一個Qt直接秒殺他們所有。
再給你說個血淋淋的教訓,公司的遊戲當年用的dx8開發,開發了兩年,內測時微軟開始推所謂革命性的dx9了,但是微軟強調說,dx9相容dx8,但是dx9效能更好,而且今後不會再有dx8的大更新。好吧,先不管,遊戲先上著,但是競爭對手的遊戲馬上聲稱,完美支援dx9,充分發揮dx9的xxxx,我擦,沒辦法,既然今後趨勢是dx9,那就改,學起來也挺快的,不就是api嘛,改了三個月基本改完。但是碰到各種坑,各種文件上找不到答案,網上還沒人遇到的坑(當年dx9比較新),前前後後折騰了1年半,遊戲才算ok了。跑了沒多久,這時微軟的 dx10出來了,號稱完美相容dx9,但是dx9不會再有本質上的更新了,你們快學dx10吧,效能很好,等你學會了 dx11又來了。
試想你一個程式設計師,一大半的時間都在給微軟交學費,值得麼?人生有多少時間呀?這就叫做被微軟牽著鼻子走。再回過頭來看看 OpenGL,到現在為止,還在用著 1.2/2.0標準,ES 3.0剛出,這就叫做穩定。一旦被商業利益捆版你就傻逼了,.Net到現在好像都5.0了吧?
跨平臺:
我之前對寫一些客戶端的程式碼,用很多 VC的特性是抱容忍態度的,畢竟每個程式設計師有自己熟悉的領域。在專案時間有限的情況下,讓熟悉 Windows的程式設計師在用很多 VC Only的特性,如: DWORD, DibSection, CString, #pragma once 等東西也是可以容忍的,畢竟當年客戶端一般都是 Windows。
後來客戶端發生了變化,一份程式碼需要同時運行於多個平臺。除了vc編譯外,還需要gcc, clang編譯。當我們一份程式碼需要同時執行在 win32, 移動平臺和 flash(crossbridge) 中時,當年積累的這些 vc only的程式碼化了不少時間翻新成跨平臺的程式碼了。儘管vc有 #pragma once這些還是比較先進的語法糖,但 gcc/clang沒有的情況下,只能退而求其次。
通過這次翻新,今後客戶端也跟服務端執行一樣要求,清一色的跨平臺,再也看不到任何vc only的程式碼了。所有專案去 vs化。
答疑1:【商業目的性太強,給微軟教學費這幾句非常可笑,現在還想學一個東西保一輩子麼,學什麼不是學,網頁遊戲火,學Flash,手機來了學objectc,學android開發,遊戲引擎變成了Cocos和unity3d,做網站後來流行PHP等等,這類例子太多了,樓mfc,vb,asp,這些當年都帶來了很多就業機會,讓人入了門,樓主主觀情緒太強】
沒錯正式學了新的,才會拋棄微軟的東西,比如學了 Qt才會拋棄 MFC/WPF,學了 php才會拋棄 asp,學了 java才會拋棄 c#,學了 flash才會拋棄 silverlight,學了 MySQL才會拋棄 SqlServer。然後你會發現,我當初幹嘛學微軟的那些東西呀,浪費我時間麼?
當年很多人是靠mfc vb開發,那是因為沒有更好的,今天有那麼多的其他選擇,mfc vb已經可以退居二線了。也正是因為有那麼多平臺需要應對,特別如果是C/C++程式設計師,才不能用太多CString這些只能在vs下跑,沒法到android和服務端用gcc編譯,沒法到ios下用clang編譯的程式碼。這叫去微軟化。
再者如果你沒得選,比如你用dx,那麼你就受苦吧,它每隔兩年出一代,搞那麼多版本到底是一開始介面就沒設計好需要不斷重構呢?還是故意非要重新弄一套?當初出9我沒記錯的話就是為了推winxp的,只有xp能跑。而dx10又是為了推vista和win7,逼著你遊戲要更好效果必須dx10,而你想玩好遊戲的話你可能被迫升級你的作業系統。這就叫商業利益驅動。
反觀其他平臺開發,很多圖形工作站用ogl,遊戲主機用ogl,android用ogl,ios用ogl,mac用ogl,而ogl幾十年到今天主要版本還是2.0,包括es2.0,這就叫沒有商業利益驅動的情況。
如此類推,出一個新平臺,有微軟的 vs2015和 Qt,那麼用Qt吧。
如果你覺得vs作為ide很好用的話,在沒有更好替代的ide前,你可以用vs這個ide來寫Qt程式碼嘛。這叫逐步去微軟化。
更新:擦,本來只有一句話,推薦Qt,遠離微軟,有人追問,補充了點,有人又追問,又補充了點,然後出了趟門回來,感覺跟捅了馬蜂窩一樣。既然都說到微軟了,那就接著展開一下。
問題的本源
微軟就是戰線太長了,忙著去主導各種標準,制訂各種框架,這樣的話,才能更好的夾帶私貨,用一個你必須用的東西推進另外一個他想讓你用的東西,諸如dx和windows,諸如c#和 http://asp.net,而又因為主導了開發者,才能進一步主導使用者,而主導了使用者,大量的利潤便會隨之到來。在整個鏈條中,如果消費者沒得選擇,開發者也沒得選擇時,微軟就能想賣啥就賣啥,完全基業長青了。出個新東西沒關係,不符合我的利益我就不支援。如果新東西很有前途,那我自己搞一套,然後再把我的開發者和使用者綁架過去。
到底哪一個方向會有前途呢?微軟自己也說不清。到底哪個領域對今後的軟體生態影響比較大呢?微軟自己也道不明。只能朝著各種有苗頭的地方去努力,以前技術領域比較窄,微軟可以囊括整條產業鏈,編譯器/IDE/框架,開發者基本可以躲在微軟的圈子裡不出來。後面各個技術領域蓬勃發展,分支越來越多,微軟就有些力不從心了。但是戰略依舊沒變,任然試圖去主導任何一個技術領域的標準。利用自己的影響力去忽悠各種開發者:“跟我來吧,有美好的明天”,但技術領域每天都在推陳出新,產生新的細分。為了主導更多的新領域,稱霸完一個領域後,微軟的重心並不是完善該領域,而是繼續集中精力稱霸其他新的領域。
對於支援期的技術,微軟會利用自己強大的影響力進行各種捆版整合,告訴你:“新的革命又到來了,你準備好了麼?”,告訴你:“用了它之後,你就什麼都不愁了”,“XXX即將停止支援”,然後各種社群中,一堆mvp前撲後擁的進行推廣:“XXX大法好,MS法力無邊”;書店的櫃檯上,瞬間多出幾十本紅色封面黑色封面的寶典;CSDN的主頁裡,各種微軟 TechED, 夏令營。很多人一看,我靠,全世界都在用,我再不用是不是就要被淘汰了呀?
完成支援後,微軟進入綁架期,為了不讓你用其他的東西,微軟想盡一切你的需求,然後為滿足你可能的一切需求,開始拼命的飆版本,來相容各種各樣的東西。很多人覺得這個東西好像挺強的,什麼都能做,不用學其他了,微軟就笑開花了,覺得可以綁架大家了,於是開始瘋狂的用該技術夾帶越來越多的私貨,或者是新技術,或者是為了強迫其他人用另一個東西,為了相容這些私貨,繼續飆版本,這就叫綁架。
等到你積累了越來越多的程式碼,或者成熟框架後,你突然發現,原來你能做的事情,就是隻能在微軟給你劃定的一畝三分地裡面不斷的耕耘。想用它開發一個微軟商業上不支援的東西?沒門。依賴微軟越久,做出選擇的成本越來越高。這時會有兩種結局,第一種,微軟給你指出下一個革命的方向,你別無選擇,斬斷原有積累投入到下一個革命中。異或,微軟覺得自己在這個領域江山穩固了,競爭對手都沒了,不會再出什麼么蛾子了,於是徹底開始不思進取,你用著過時的技術乾著急。
曾任微軟副總裁的李開復回憶:“一個產品隊伍一旦失去了假想敵,就會鬆懈,蓋茨和鮑爾默也會撤回對它的投資和支援。比如說,微軟IE擊敗網景之後,微軟就降低了投資,致使它的瀏覽器多年沒有再進步,直到又出現了‘火狐’這個敵人,才又開始振作。”火狐就是網景的“遺孤”。
微軟的綁架
MFC就是一個很好的例子,當年同 VCL競爭時挺上進的,VCL一死,MFC也跟著死了,現代的介面系統都是 windowless直接繪製控制元件了,笨重的mfc還在基於系統控制元件。大量的onpaint自己做,人招不到不說,工作效率奇低,熟練的mfc工程師還比不過學習Qt一個月的學生開發效率高,你說我會選啥?mfc還需要各種奇巧淫技才能達到 qt的效果,弄那些技巧的人變動,專案就傻逼了,考慮到這一點,你說我又會選啥?最近兩年介面開發又開始指令碼化了,你會發現 Qt有各種支援指令碼(除了內嵌支援 js的 QtScript外,還有 Python的 PyQt,還有 Lua)任你選擇。核心程式碼C++,邏輯介面python,用過指令碼開發UI的人都不會想用回C++寫UI,因為介面邏輯指令碼化可以提高至少兩倍以上的生產力。微軟的策略呢?想用指令碼?沒門,因為我不推指令碼但是我推c#,所以你想方便的寫高階介面?還是跟著我去弄 .net和wpf去吧,這就叫綁架。面對綁架你別無選擇,開發者微軟系的程式碼和經驗積累越多,想離選擇非微軟的東西成本就越高,想不被微軟綁架的代價就越大。
為啥有人願意給 Qt指令碼化而不願意給微軟的介面系統指令碼化呢?並不是微軟的技術就比不過Qt,而是大家唾棄微軟的臭脾氣,外加Qt是開源的,為它實現指令碼各種方便。這裡並不是說開源的東西就一定比微軟的東西好,微軟有很多領先的技術甩開源幾條街,主要問題在於微軟的封閉性。所以我的論點並不是一定要用開源,而是建議大家有選擇的餘地下,選擇非微軟技術,比如qt, flash這種。
死也要主導行業標準
為了引導行業標準,微軟很多設計的很好的東西,各種音視訊格式,還有最近的 HD Photo圖片格式,比 jpg2000 和google的webp好多了。但是很多人由於微軟的封閉不買微軟的帳,很多框架和軟體都直接支援webp了,也沒幾個人支援wdp,在這種情況下,我寧肯選擇次一等級的 webp。
微軟的出過很多標準性的東西,比如wmv, wma格式,當年挺先進的,微軟也天天忽悠人去用這兩個格式,但是由於封閉,最終失去支援,大家選擇了更加開放的方案來代替,微軟也就不思進取了,最終視訊領域 現在是 h.264/265,音訊領域是 he-aac v2。
微軟又試圖代替 pdf,引領該領域的標準,然後自己出了一個 xps。論技術,確實高於 pdf很多,但是沒人用呀,沒軟體支援呀,連印表機都只支援掃描成pdf格式。所以我選擇 pdf並不是因為 pdf技術比微軟強,而是因為它不是微軟的。而且我估計個兩年出個 pdf2,xps也就跟 wmv一樣進棺材了。
再比如 SilverLight,微軟在沒有太大把握的情況下硬推這個東西,就是因為怕c#由於滿足不了RIA使得C#開發的開發者流失到微軟以外去,為此 .Net還逼迫大家升了幾個版本。可惜,大家都知道的,於是微軟自己對它的支援都少了很多。
你說微軟技術弱麼?不弱。那為啥這些明顯亂七八糟的東西微軟都要硬撐著試圖主導行業標準但是最終又主導不了呢?那是因為我們先前提到的微軟戰略,從幾十年前到現在都從來沒有變過,然而時代變了。
Win32 API
Win32 是系統層最穩定的介面,一切功能的基礎。這麼基礎的東西,微軟該化大力氣持續發展對不對嘛?非也,隨便舉兩個例子你就會發現其實它已經落後世界很多了。微軟是任性的,覺得我提供的開發模型可以解決一切問題,為什麼要參考其他作業系統改進呢?即便其他作業系統提供的功能很好,我也要給你挑挑刺。而按照微軟一貫的規律,系統 API領域,我完全控制了,那麼我改進的動力也就不那麼強了,庶民們豈能妄自議論 Win32 API,更別說想提交改動 patch給我了。
執行緒同步:如果你寫執行緒同步,你會發現 Win32 API缺很多關鍵的東西比如:條件變數,讀寫鎖,這兩個最基本的能夠組合成其他任何同步模型的東西,微軟直到 Vista的年代才提供支援(msdn Condition Variable),這就意味著,你如果用了,你將面臨很難在 xp下跑的情況。你問微軟 xp怎麼辦,微軟說用 event去 wait嘛。你就奇怪了,event這麼弱智的東西能代替條件變數麼,為啥不再xp年代就支援了?
單次初始化:pthread_once,沒錯,windows下面由於缺少這個東西,你再做一個全域性變數供你的介面訪問時,你需要保證該變數只被初始化一次。即便多執行緒同時呼叫訪問該變數的介面,也不會出現兩次初始化的情況,pthread_once就是做這個事情的。直接把程式碼寫成:if (inited == false) { init(); inited = true;} 執行緒又不安全,外面加一個 CriticalSection,那你又需要在更前面去 Init這個 CriticalSection,還要保證不會發生多次 Init,問題還是沒解決。於是很多人在 Windows下的解決方案是,在全域性變數宣告一個類的靜態例項,這樣 main()之前,那個類的建構函式能夠提前被呼叫,進而又引入了新的問題,及多個全域性例項又會存在誰先誰後被構造的問題,你又得用噁心的 #pragma巨集來解決,最後初始化程式碼一團亂麻。而如果微軟提供 pthread_once類似方法,那或許這一切都會變的很清爽。
網路介面:
用過 winsock介面的人都覺得簡陋,你想實現高效能的網路服務,需要控制 TCP的大量細節引數,比如 TCP_NOPUSH, TCP_CORK, 還有 QUICKACK這些控制調整 TCP面向流量優化或者面向流速進行化的基本功能,winsock上看都看不到。更別說 Google的 TCP速率優化(Kernel 3.2.12收錄的 Google patch)等現代功能了。即便是對比最基本最傳統的 posix套接字,winsock的行為也是錯亂的,比如 REUSEADDR,再比如 Win32下你監聽一個 UDP埠,給遠端傳送 UDP資料包,如果遠端沒有監聽該UDP埠,那麼你服務端收到 icmp: port unreachable後,那個udp socket就徹底被 reset了,後續什麼資料都讀不進來,持續給你報 10054,搞笑吧。除非你建立udp套接字時做一大堆 *windows獨有的* 專門的設定,否則vista之前,你都會被 10054。vista之前,預設情況下,客戶端如果拒絕收服務端的 udp包的話,服務端的 udp套接字就用不了了,這是不是在搞笑麼?還有各種基礎功能限制,比如:缺乏poll支援(強迫你用iocp代替),select最多64個fd,沒有 socketpair。當然,沒有這些也可以寫網路應用,但寫慣 unix下的網路程式碼突然來 win下寫,就會覺得這真是個玩具呀。
TLS:
TLS有數量限制也不管了,但是執行緒本地儲存這個東西是需要 destructor的,即我建立了一個本地儲存來存一個物件,我可以設定一個 destructor函式指標,線上程退出時,這個函式會被自動呼叫到。比如你想實現一個 per-thread cache(比如類jemalloc的 arena),執行緒退出時能夠被自動析構,這個最基本操作在 Win下卻可以把你彆扭死,原生TLS API沒有這個支援,你又不想所有執行緒退出都要強迫使用者呼叫一下 destructor,那麼你開一個執行緒監聽所有執行緒?還是怎麼招?看看 boost和 jemalloc這些在 win下的 destructor實現,你就會發現噁心的要死,就像要在一塊工整的電路板上,焊接一根非常礙眼的飛線一樣。
GDI/GDI+: GDI是牛逼的,出生早又承當了 GUI的基礎工作,畢竟那麼多年了,做成這樣是無可厚非的。但是XP年代的 GDI+一出生就落後於時代。比同期的同一個級別的開源專案 Cairo(gtk後端,wine用來模擬gdi/gdi+的後端,webkit/mono後端)和 Quartz(OS X圖形後端)來,GDI+除了速度卡外,影象質量差,功能簡陋,不支援抗鋸齒,對GDI的字型效果也並沒有質的改進。所以 Windows下的應用軟體,一直因為字型和影象質量受到詬病。直到後面的 Direct2D出來希望改進這個局面,也已經是好多年以後的事情了。大量相容 xp的程式還在跑在 GDI/GDI+上。
( 問題有很多,以下省略若干字)
按微軟的能力,想改進這些基礎介面,應該不是難事。但基礎介面的長期滯後,折射出的是該公司全勝時期的傲慢。
統治與分治
微軟的介面設計向來是缺乏美感的,喜歡複雜化,喜歡什麼東西都攪合在一起。什麼叫做大一統?就是什麼都能做,貌似很強大,一個東西能做的事情很多,開始是好的,但是隨著時間的推移,耦合度高,各種盤根錯節,一旦其中一個設計很 “巧妙”的東西過時了,那所有依賴它的東西將面臨死亡。什麼叫做分治?就是保證簡單性和可拆分性,每個系統專心做好一件事情。一個不行,換掉即可,整個解決方案是由若干全部可以替換的子模組組成的,這叫分治。
Windows技術棧就是一個典型的大一統設計,他有很多很巧妙,依賴性很強的東西。比如,“一切都是視窗”,這個思想,從設計上來說就是有問題的。舉個簡單例子,WSAAsynSelect 用過的人都知道,這是一個網路介面,用來判斷哪個套接字上有事件。但是卻又要傳一個視窗控制代碼過去,讓視窗來接受網路事件,這就是一個很搞笑的例子。微軟為什麼這麼設計呢?因為應用程式本身有一個訊息迴圈了,就是視窗訊息迴圈,但是如果處理網路的應用程式使用類似 unix poll的方法,去等待訊息的話,視窗訊息就得不到處理了。如果把poll放到一個執行緒裡的話,那UI執行緒要找網路執行緒做點事情,那網路執行緒在 poll的等待週期中,如果沒有新的網路資料過來,可能短時間內沒辦法理會 UI執行緒的請求。於是微軟的解決方案,就是讓網路層的事件合併到 UI的視窗事件中,這樣就比較方便了,全部在視窗訊息佇列,你要把UI和網路放到一個執行緒也可以,兩個執行緒也罷。這樣把兩個風馬牛不相及的事情攪在了一起的:“巧妙” 設計在微軟的技術棧裡數不勝數。
合理的處理方法應該是啥?應該是繼續使用 Poll,每次 poll可以設一個比較短的時間,並且可以被外面執行緒喚醒,這樣就不會出現之前的問題了,兩件事情不會攪在一起,這就叫可拆分性。結果呢,不關網路,大量的其他東西都和視窗攪起來了,等到 Windows程式要移植的時候,就會變得萬分痛苦。有人說不是有 IOCP麼?看看有多少一流的伺服器支援 iocp?再說java可以把所有不同作業系統的非同步事件模型封裝成NIO,對 Windows對的 iocp卻提供單獨的介面,而且直到 7.0以後才有,微軟總喜歡和全人類反著來。
缺乏審美的設計,才會導致 Win32 API被 GUI所束縛這樣一種結果。這在其他系統對比來說,這時聽都沒聽過的事情。這是設計上的偶合,還有商業上利益的選擇。比如網頁開發,C# 和 http://asp.net繫結太緊,http://asp.net和 iis繫結太緊,iis和 windows又繫結太緊。微軟的東西才出來都是先進的,可封閉的微軟不願意同外面合作。你要用我先進的東西,你就一個系列都要用。最終全部都攪在一起了,風險是相當大的,系統就像一個吞噬了各種化學物的怪獸一般,蹣跚前行。
而所謂簡單性和可拆分性的東西,是四處皆可替換的東西。比如你做 web開發,你選一門語言,python,語言就做好語言的事情。外部的網路框架,可以用 django,flask, web.py等等,介面可以用 fastcg / cgi / wsgi / uwsgi / apache_mod, 而外部的伺服器,可以用 apache, nginx, lighthttpd。清晰的被分成:語言層、框架層、協議層、服務層 四個不同的層次,每個層次若干備選方案,互相相容,web.py過時了,我換 flask,apache過時了,我換nginx。每個產品都專注做好自己的事情,並前後適配其他層次的方案,python出問題了,我換 ruby,換php,協議任然用 apache_mod或者 fastcgi。這就是分治,具備美感的設計。
這樣的情況在微軟的技術體系裡很難出現,這些技術執行到windows下水土不服不說,微軟自己就不讓你選:你要寫asp .net,那語言你就用 c#(vb比較小眾),用了http://asp.net你就要用iis,而iis只能跑在 windows下。外部的人很難相容進來,本來微軟就不太願意支援其他技術。那麼好,一開始可能領先,但是隨著時間推移,這麼長的鏈條中間一環出問題,可能會導致其他的跟著他一起被人拋棄。
微軟一方面出於商業考慮,生怕自己技術鏈中哪個環節被人替換,一方面有些介面設計充滿耦合,考慮不周,導致後面大量的主動升級和被動升級,什麼 ocx, com, atl, ole,dx1-7類似的東西都可以搞出那麼多來折騰人,系統核心 GUI,網路、多媒體,大量的 API偶合在一起。最終簡單的一個 Office和 Windows一樣臃腫醜陋,這就叫缺乏美感的設計。
C#
C#是一門簡潔優雅的好語言,是微軟中比較少見有品味的設計,這是因為 C#之父 Anders就是來源於微軟之外的 Borland。Anders 早年為 Borland 設計的 Turbo Pascal 和 Delphi 就以編譯速度快,使用簡單和功能強大受到大眾的喜愛,所以在設計 C# 時融入了很多早年的審美觀。C#語言層面上勝過 java不少。我經常邊用邊罵 java到9到10了,也沒想著好好的學學 C# 的一些特性。Java 這麼多年連個 get/set 都不抄一下,連個unsigned都不肯給我用用。用 C#寫程式碼比 java流暢不少,但應用範圍太窄呀,我沒辦法還得接著用 java呀,應用範圍廣呀。我用 java寫的程式隨便執行在幾乎任何平臺上,大量最新的開源成果可以直接應用。可憐的C#卻被微軟畫了一個圈,死死的呆在圈裡出不來。其實大家都是歡迎 C#的,不然也不會有 mono這個專案了,但 mono執行效率比 jvm低不少,比原生的 .Net執行時低很多,庫也不全,實在難以承當大任。
除了部分人專門從事 C#的工作外,現在網際網路企業,幾乎很難看得到 C#的身影:做移動應用,用原生的 java和 objc。做服務端用 C++/java/各種動態指令碼,做頁面用 Js 頁遊用 Flash。做PC遊戲用C++/指令碼,沒C#什麼事情。移動遊戲主要也在使用 C++/指令碼(unity只是眾多遊戲開發引擎中一個單例未來是否被代替未知,XNA就是個玩具)。唯一隻有微軟的老本行PC桌面應用,沒錯,是C#,但是現在也面臨諸多挑戰: CEF(Chromium Embedded Framework)用js直接寫Windows本地應用,如網易雲音樂用CEF效果拔群;Qt系列+指令碼(越來越多網際網路公司在用,如Wps);自己C++UI庫/指令碼(例子太多了)。這些方案你或多或少都能挑出些問題來,但不可否認的是她們正從各個方向蠶食 C#的傳統地盤。你可能說C#在客戶端能做很多非 UI的事情(比資料庫和網路還有影象),但 CEF/Qt 這些播放點流媒體、訪問下網路、弄下影象或者請求下資料庫同樣很簡單。現在 GUI開發的指令碼化程序正在席捲各種桌面開發方案, js等指令碼執行速度越來越快,C#速度上並不能體現出數量級的優勢,而且基於泛型的指令碼語言開發效率比原來高很多,同時這些解決方案全是跨平臺的。而整個程序中 C# 被排除在外了,這才是 C#真正危機的地方。
DirectX
有人奇怪我為何喜歡 OpenGL,話說白了只有一個理由,它是開放的而且它不是微軟的。如今很多人會說你看 d3d 介面不錯,相容性高,CPU佔用低而且畫面好。沒錯,但記心好點的同志們把時間拉長一點,Win95時代微軟強推 DirectX而封鎖 OpenGL很多系統呼叫的事情各位還記得到吧?那各位還記得到 DX才出來時爛成什麼樣子麼?當時業內罵聲一片,很多人看了眼介面就扔了,直到 DX5出來的時候,你稍不留神,還會把整個螢幕畫花了,或者弄宕機了。當年 OpenGL領先 DX不是一個量級。直到 DX8出來了,才算完善了一些。微軟為了商業利益,把整個行業拖後了數年之久。直到2006年,很多 3A大作還是以 OpenGL為圖形底層,不鳥微軟的 D3D。
微軟的技術架構,向來不太優雅,耦合度又高。Dx7以前,DirectDraw的表面和 D3D裝置還有紋理攪在一起,DSound的座標系統又可以和 D3D的座標系統攪在一起。大量的資料結構被定義出來,一個向量一個矩陣還要單獨定義一下,不准我跨平臺庫用自己的定義麼?你就不能用個數組麼?你強大是強大,但是你耦合度實在太高了。一個環節更新,所有環節被迫更新,然後就飆版本的原因之一。DirectX的設計就是沒有品味的,如果按照簡單性和可拆分性的思路來重新考慮,Dx軟體包中,應該隔的比較開才行,能不定義的物件和結構體,儘量不定義,用C原始的型別或者陣列來介面,這樣不會妨礙我外面靈活使用。然後遊戲開發者靠一門膠水語言把這些獨立模組根據需要粘合在一起,這樣的方式是不是更清爽一些呀?
開放的東西能自我適應性,自我修正。Real Networks估計很多人還沒忘記,當年的他開發的 RM / RMVB視訊格式,因為壓縮比高,同信噪比下位元速率能有更低的位元速率,畫面質量更好,而贏得了廣泛的支援。但是 RM / RMVB卻是一個封閉的視訊格式,雖然領先了業界數年之久,但是數年後即被開放的 H264所代替,H264雖然一開始接受度不高,但是數以萬計的人在幫他完善。學院派今天發研究出一種更有效的巨集塊搜尋方式,不出兩個月工程界就跟進了。今天有人發現一個運動估計的改進,明天有人實現個更低延遲的快取管理,或者提升下錯誤恢復能力。免費的 x264不論從延遲,效能,畫質,位元速率都直接秒殺很多商業公司的編碼器,ffmpeg又可以輕易的播放h.264視訊。最終 Real Networks抱著它的 rm/rmvb一起進了墳墓,死前還不忘叫一句它正在開發 rmvb2,超越 h.265標準的編碼格式,業內嗤之以鼻。視訊領域的玩法已經變了,H.264通過不斷髮展,最終顛覆了RMVB的商業模式,這就是一項技術自我適應,自我修正的例子。
今天的 D3D就像當年的 RMVB,就算他用商業手段狠狠惡心了 OpenGL一把,導致後面 OGL數年發展不順,但是老話說得好:理勝力為常,力勝理為變;一時之強弱在力,千古之勝負在理。隨著 OpenGL新標準的不斷完善,雖然暫時不能徹底拋棄 DX,但封閉的 Dx必然會隨著微軟 Windows 逐漸邊緣化,這就叫得道多助失道寡助。
全世界玩一套,微軟自己玩一套
還是因為微軟最初的戰略沒有改變,導致全世界一套,微軟自己玩一套;微軟看不起開源界,開源界也不理微軟。再次強調,並不是只有開源才好,而是這麼多家公司裡,只有微軟一家試圖自己從頭到尾建立一套完整的技術體系,只有微軟一家採取如此封閉的策略。然而早年微軟可以罩住整條產業鏈,並且活的很爽,但是現在大量基於開源界的最新成果都和微軟技術棧水土不服。
所以開發者會面臨:依賴微軟和不依賴微軟兩種選擇。依賴微軟,很容易和外界形成隔離。而不依賴微軟,你得到的是滿天下的選擇。前者強調高度整合統一,後者強調可拆分替換。然而,世界潮流,浩浩蕩蕩,順之者昌逆之者亡。
成也蕭何,敗也蕭何
早年的微軟,象一個潛伏在叢林裡的獵手,利用自己作業系統的優勢地位,尋找著產業鏈最高階的使用者需求。一旦一項技術可以滿足使用者某種根本需要,微軟就不惜犧牲眼前的現金流,來換取未來的行業領導地位和盈利。或快速收購,或惡意打壓,或自家出一套,任何一個領域只要有新的東西出現,微軟就試圖去控制它,並綁架獲出錢養活接受了微軟標準的軟體開發商讓他們支援,出錢扶持低端的開發者讓他們學習微軟標準,於是巨大的利潤,隨之而來。
這樣的戰略,使微軟茁壯成長,併成為接二連三的行業標準擁有者。然而這樣的戰略有一個致命的BUG,就是標準必須是與時俱進的,微軟需要不斷調整已有標準,否則越來越多的標準就會成為束縛住微軟的一條條繩索,越來越多的相容性問題象一座座大山一樣壓得微軟喘不過氣來。掌握的標準越多,微軟越難改變,隨著時間的推移,將會被微軟體系外更加迎合使用者偏好的競爭者們所取代。
有人說:“微軟錯過了移動化浪潮,錯過了雲端計算,是因為鮑爾默的誤判。智者千慮必有一失,再牛逼的人也有判斷失誤的地方”。但是通過上面的分析,我們可以看出這種說法的荒謬性,我們需要清醒的指出,就算沒有鮑爾默,微軟即便趕上了雲端計算,他也會錯過霧計算;他即便趕上了霧計算,他照樣會錯過煙計算。
這樣的戰略,使微軟早年站到了時代的風口浪尖,又使如今的微軟,變得越來越與時代背道而馳,不是微軟不想融合,而是融合的成本越來越高。世異則事異,事異則備變,理解了微軟的核心戰略,就不難理解微軟為什麼會去弄什麼 xps, silverlight;理解了微軟的戰略,就能理解為何微軟的精力總是在制定新標準,而不是改進老標準了;理解了微軟戰略,就不難理解為何進入2000年以後,微軟總是昏招迭出了。
病在肌膚,還可以醫治,病在肺腑,人就危險了。沿襲了那麼多年的戰略,成就了微軟和他的下游開發商,也害了微軟,讓微軟想改變都改變不了。就像一輛陸地上上裝甲車,裝甲越厚越堅固,然而現在要到水裡開戰了,所有裝甲一夜之間全成了負擔,要尋求救贖,除非把自己從頭到尾全拆了才行。進入2009年後,看到當年一致支援自己標準的下游開發商們,粉粉判離微軟轉投敵營時,微軟深刻的意識到,老天已經再也不像原來一樣眷顧微軟了,這真可謂是:成也蕭何,敗也蕭何!
微軟的選擇
人什麼時候會感覺到壓力?就是擁有一個東西,但是看著這個東西一天天的減少,越努力抓住他,卻又越抓流失的越快,改變意味著放棄,等待意味著死亡。在這樣的壓力下,微軟昏招迭出,這並不能怪微軟高管愚昧,也不能說微軟運氣差,而是自從步入 2000年以後,沿襲了幾十年的一家統治世界的戰略與時代變得格格不如了。早年的成功讓微軟無視各種問題,繼續靠慣性又活了15年,錯過了自我救贖的最佳時機。
核心戰略出問題,不是一朝一夕的決策對錯,很多人還不願意承認,認為換了鮑爾默就能解決,認為開源 .Net,就能救 C#,就能救微軟,其實這是一個天真的想法。微軟戰略從頭到尾就沒變過,開源其實相當於承認先前戰略是失敗的,可它卻又沒有提出一套新的思路和新的戰略。事實上早在2000年時微軟就進入了戰略迷茫期,所以東一榔頭西一棒子,沒有重點,缺乏主題。雖然如此,還是能靠慣性繼續生存,但是自我否定之後,新戰略是什麼呢?戰略層的自我否定會極大的傷害企業向心力,讓微軟在未來變得更加艱難,同時又沒有確立能夠經得住實踐驗證的新戰略,這又會使整個企業變得比原來更加迷茫。
但微軟能改變麼?不能。微軟沒有辦法提出一套和原來戰略不相容的新戰略,除非完全把自己和多年經營的生態鏈砸碎。15年前的最佳改變期被其錯過後,如今再怎麼變都只能在原有戰略框架下尋求小改變,時代的巨流,象一股巨大的引力場,吸引著身軀龐大的微軟,無可奈何的掉進自己挖的坑裡。
無可奈何的結局
直接送貨上門發達了,便利店就蕭條了。網上購物興起了,實體零售業也就死亡了。這就叫做 “新經濟體” 代替老經濟體。判斷一個經濟體是否衰落,看的從來不是它銀行裡還有多少錢,而是看它的商業模式是不是還成立。如今的微軟,就是一個核心商業模式被顛覆了的企業。這不是開源能夠救得了的,更不是蓋茨復出能夠救得了的。
聽到微軟開源,讓我想起之前 Sun公司 Solaris開源為 Open Solaris,希望用開源來挽救自己的頹勢,沒多久它就倒閉了。如今一項根本技術,比如作業系統,已經很難被一家公司所壟斷。商業模式一旦被顛覆了,開源也不能成為救命稻草。
事物強弱變換,新舊更替,本來就是自然界的基本規律。蓋茨是一個聰明人,看到了未來的局面,知道什麼叫月滿則虧,水盈則溢,在微軟最鼎盛的時候功成身退,高風亮節的做起了慈善,將最苦的差事留給了鮑爾默。所以,聰明的蓋茨也是不會復出的,所以,其實我挺同情老鮑的。
結尾故事
一開始就沒想噴微軟,我不是一個極端的人,一開始只是回答問題,建議題主用 Qt,遠離微軟的技術。但是完蛋了,一堆人上來圍攻,那我真得正兒八經的把微軟這事情說的清楚點才行了,否則我變成誤導題主了。
其實世界是歡迎微軟改變的,我們這些從小學電腦就用著盜版微軟系統的人,對微軟也還是有感情的。但是微軟這次能否迎來新生,還得看微軟自己,我們是幫不了他的。