為什麼大多數人寫程序都是調用標準庫或者自帶函數,而無法寫出像標準庫那樣的函數?
為什麼 很多 第三方庫,也僅僅是對 標準庫 的封裝,如何才能寫出 像 標準庫那樣的函數?偏底層的,比如,寫一個網路庫,謝謝
整個軟體鏈條是這樣的,農民種田有糧食,有飯吃了民工挖沙開始制矽片,有了矽片後晶元設計公司設計CPU,有了cpu開始設計操作系統,有了操作系統開始設計軟體開發平台,有了開發平台開始設計軟體,有軟體可以指揮機器,有了機器可以科學高效種田。
軟體是整個鏈條上的一環,不存在會開發底層api就比軟體本身先進厲害,這個底層是整個社會不是軟體本身,軟體的現實價值是以市場價值為準,hao133,阿里巴巴以前做html的,騰訊做icq漢化的,只要是市場認可就能成就自身價值,做彙編語言,c語言反而離應用遠很難賺錢,開發操作系統無數公司失敗了,開發資料庫無數公司失敗了,開發編譯語言無數公司失敗了,但做網站的成功很多。底層技術一山不容二虎,佔領市場後就會很快形成壟斷,現在的nosql,大數據也形成了開源軟體壟斷。
不需迷信底層技術,只是鏈條上的一環,你要把精力放在你的上一環客戶服務上,而不是下一環供應商。
軟體開發技術經多年發展己經開始成熟,不是什麼高科技只是工程量,軟體開發只要用適合的技術最大限度發揮出業務功能就是厲害,現在底層技術己經很成熟基本被壟斷了,多數軟體開發是面嚮應用,對底層技術能用別人的盡量用別人的,這樣節省成本提高利潤。
為什麼大多數人做飯都是買米,而無法種出來?
因為等一個人寫出了像標準庫那樣的函數,就會試圖把它提交給boost等准標準庫,過個幾年可能就成為了標準庫。
如果是標準庫已經有的東西,你又為什麼要再寫一遍呢?覺得自己比寫標準庫的人聰明?
這也是要靠練習,特別是STL這種東西,你多寫幾遍,寫自己的C++程序的時候不要用STL用自己的庫,覺得不好用就重構,久而久之也就會寫了。
除非你是在造輪子,否則一般情況下你是沒有必要來寫這些的。
因為大多數人的日常工作不是寫編程語言,有大牛說過庫即語言。像標準庫那些東西其實就是編程語言的一部分。
這個問題問得真是奇怪。難道大多數人應該去自己寫一套標準庫?我們是不是應該先討論一下寫程序的目標是什麼呢?是為了造輪子還是為了解決問題?
如果是做遊戲引擎,你自己寫的東西做出來的就是幻燈片,別人做出來的才叫遊戲。類似於其他偏重數學計算及高效演算法的底層庫,你和科學家中間也隔了好幾個宇宙。
標準庫也分不同的庫。例如有些答主回答的那些stl,或者有些演算法庫,都是的確自己寫出來不難的,而且很好實現的。既然如此就更沒有必要自己實現,除了特殊要求以外,用現成的何樂而不為呢?但是如果你問的是底層庫例如網路庫或屏幕列印庫,的確是很難自己寫出來。而且你能夠調用的語言介面,其實都是進一步包裝了系統暴露給你的介面,你自己實現到包裝那一步還好,再往下就是系統的底層介面,不是自己實現的問題了。
這問題其實是有意義的,有些標準庫其實是有bug的,是有重寫的意義的,有的公司評估過性價比之後還真的重寫過,當然是不公開的。
等見識的足夠多了,你會明白,程序員要證明自己,未必只有底層一條路。
構建基礎設施固然彰顯能力,
但如何組合使用,或者說在題目里被看不起的「封裝」,也是一門巨大的學問。前者易於度量,是能不能的問題,是技;
後者難以估計,是好不好的問題,是術。雖然不好直觀描述,
但實際場景走一走,差距還是很顯著的。否則架構師們薪水也不能這麼高(硬貼個架構師名頭的那種不算)因為大多數人寫程序都是為了實現業務邏輯,滿足商業需求,交付給客戶然後取得報酬。調用現有的庫函數能解決問題的話,自己去寫庫就沒有意義了。除非現有的庫無法解決問題,才有需要自己去寫。
對一些事情有了一知半解的認知之後就覺得該這樣該那樣,瞎雞吧擼一通,然後越擼越歪,然後開始谷歌stack overflow 終於有點眉頭,結果性能差了一大截,然後又酸又腐的想,看來這庫也不差嘛,居然性能比我寫的好,但是特么的花了這麼多時間搞的不能就丟了啊,我的kpi 就指望這貨了,於是性能對比造假強推給技術經理,技術經理以為撈到寶一樣趕緊切換,結果一堆的bug ,光是代碼合併就特么的一堆人在罵,結果編譯過了就趕緊丟給測試,測試用例沿用以前的那套,草草收場上線了,到了用戶手裡開始出現各種詭異事件,然後罵用戶不會操作,然後各種用戶流失,再不久,一個被用戶重現的bug 導致用戶損失了一筆錢,外加幾具屍體,結果公司因此關門,而題主繼續去下一家重寫庫個人建議,寫庫之前先把原庫通讀一遍
要積攢自己的類庫,關鍵是要有意識的總結、歸納、抽象、復用。但為什麼這麼做的少呢?我覺得有幾方面原因:
- 大多數人都是急匆匆地完成任務,沒時間琢磨怎麼積累自己的類庫,所以,只好搭積木來完成任務,怎麼快怎麼來。
- 特定的類庫需要特定的演算法知識,很多人其實不具備,比如圖像處理、視頻處理的很多演算法,大部分人都不會,只有調用開源類庫的份兒。
- 特定的類庫需要特定的底層知識,比如和GPU、寄存器、內存、硬碟、藍牙等直接打交道的底層類庫,很多人根本聞所未聞,更不用說寫這樣的類庫了。
- 重複造輪子沒必要。
標準庫也並不是很都很難寫,比如strlen,我不信會C的人有不會寫的,你覺得很難寫的可能多半是平台相關的功能
還有,一般來說你寫的代碼越長,出錯的可能性就越多,所以沒有什麼明顯的好處為什麼要這麼干
相對來說,特別是底層晶元,寫標準庫都是特別了解晶元的寄存器的大牛,寫出來的代碼穩定bug少。自己寫需要編程能力很強很有耐心。
對於碼農,組織代碼架構才是更有價值的目前正在寫日系晶元的sdk,難度相當大
代碼改了又改為什麼盡量調用標準庫函數?之前已有人詳細回答了一個原因,只需寫好自個從事環節代碼就夠你深入了。這裡再補充一個原因:為了簡單。
不管你是寫開發包還是app,都要追求一個目標:簡單、如何能更簡單。判斷一段代碼是好代碼標準,除了運行它會是好app外,還有像是否簡潔、是否易維護。代碼不是光給自已看,你要讓別人也容易看懂,代碼不能因你而「斷」掉。
因為要簡單,個人建議那些高深語法,像虛繼承、泛型,能不用的就不要用。也是為簡單,盡量不進行二次封裝。一旦進行二次封裝,意味著它人看這代碼又要學習,又要記數據結構,又要記API,這對本來學習門檻就高點的語言,像C/C++,會雪上加霜。現在開發者面對的開發環境和15年前是完全兩樣了,開源項目這麼多,腳本語言這麼方便,時刻要有「盡量不做技術創新者,做技術集成者,甘當多個知名開源項目的融合劑」的設計理念。
舉個例子,標準庫提供了std::string,用於封裝字元串操作,很多人認為這類功能不強,於是像Qt還有提供QString。不過我想說,如果你是開發sdk,那開發時還是要堅持向外提供的是std::string,至於二次封裝過的QString,盡量不要讓出現在API層。
接下是回答網路庫,強烈建議去用Google的Webrtc。
1)為好的用戶體現,從網路讀出數據不是在主線程,為此不得不和主線程同步——,Webrtc幫你解決了這個複雜的同步問題(Webrtc的多路事件分離器及網路API - 知乎專欄),你可以在主線程處理讀數據。
2)強大的多線程同步功能。網路讀數據只是它一個方面,它還可用於像處理後台任務。用這些功能時,代碼簡潔、邏輯清晰,基本告別同步變數。
3)穿透。Stun、Turn,以及融合它們的ICE(互動式連接建立(ICE) - 知乎專欄),在這方面涉及到概念多,邏輯複雜,但Webrtc幫你很好實現了,這些可說都是教學級代碼。
4)和網路安全相關的ssl,安全實時傳輸協議srtp,基於不可靠傳輸業務協議之上的可靠的數據報傳輸協議sctp,它們往往是網路編程時繞不過去協議,現在它們都有了幾近標準的開源實現,boringssl,libsrtp,libsctp,如何使用它們,請去看Webrtc。
5)你要用網路傳什麼數據?最複雜的估計就是音、視頻多媒體數據了。Webrtc知名在哪裡,就是處理這些數據,採集、編碼、發送、接收、解碼,全都開源。
6)跨平台。完美支持Window、iOS、Andorid、Linux、Mac OS X……
Webrtc是很大,是絕對值得去深入。實在沒必要自個去寫網路庫。
建議看看成熟的開源代碼,nginx,ffmpeg,redis,systemd等,都是linux下用c擼出來的較大工程,也都是各自對標準庫包裝(或者有考慮跨平台重新實現的)。至於第三方庫,像libevent,libjpeg-turbo,libusb,libyuv等,都是干各自專項功能,翻翻這些庫的git log,都是迭代了n年,並被廣泛使用(雖然還有各種bug和issue)。即使像posix標準庫,man一下,也有各種飛刀,提示過時不建議使用的,或者用完手動釋放內存的函數,只能說明當初設計欠考慮。所以實現從底層實現庫考驗功底,而且費力不討好,別人用庫就想圖個安穩,你要維護庫,就得要有及時搞定bug的態度。如果還是執意想自己寫,就先抱著學習練手的心態。
俺也在學習練手中。
為什麼很多人都是買回cpu直接使用而不是自己去挖硅礦?
標準庫有數以萬計的人去貢獻去優化去測試,你自己寫的庫有那個人力物力精力可以比擬嗎,還是說做項目的時候帶一個丑不拉幾的輪子還要讓別人額外編譯鏈接個庫很自豪。。。
C 如果在標準庫方面能爭氣點也不至於成為時代的眼淚,你可能隨便做個小工具都需要帶一堆功能相同的輪子,而且哪個的實現可能都不是最好(逃
推薦閱讀:
※求十億內所有質數的和,怎麼做最快?
※求效率的演算法?
※一棟28層的寫字樓,有8台電梯,如何能讓運行效率達到最高?
※背包問題可以通過動態規劃解決,為什麼還說背包問題是NPC的?
※有哪些好的c/c++演算法的書?