從去年開(kāi)始(可能更早),SOA的概念在汽車(chē)軟件行業(yè)逐漸蔓延開(kāi)來(lái),很多公眾號(hào)都發(fā)過(guò)講汽車(chē)SOA的文章,很多車(chē)廠都要開(kāi)始(或者已經(jīng)在)搞SOA。但我覺(jué)得吧,在開(kāi)搞新技術(shù)之前,是不是先花點(diǎn)時(shí)間弄明白這個(gè)技術(shù)到底是什么,它解決的是什么樣的問(wèn)題,然后再談架構(gòu),再談開(kāi)發(fā),很多時(shí)候我們連問(wèn)題是什么都沒(méi)整明白,就急著去做解決方案,最后的結(jié)果只能是一地雞毛。對(duì)個(gè)人來(lái)說(shuō),要搞SOA開(kāi)發(fā),需要夯實(shí)哪些基礎(chǔ)知識(shí),看了很多SOA文章,卻很少有人梳理這些,這段時(shí)間我陸續(xù)思考了一些,盡管可能不全面(更偏向SOC開(kāi)發(fā)涉及的技術(shù)點(diǎn)),但仍然試圖寫(xiě)出來(lái),以期逐步構(gòu)建出自己的領(lǐng)域知識(shí)體系。
①
SOA設(shè)計(jì)難點(diǎn)
個(gè)人覺(jué)得,汽車(chē)SOA的設(shè)計(jì)難點(diǎn),主要在于以下幾點(diǎn):
服務(wù)的定義和劃分,要把業(yè)務(wù)需求分析透徹,從中提煉出服務(wù)的功能,數(shù)據(jù)流向理清,定義服務(wù)的邊界,把握服務(wù)的粒度,怎么做到“低耦合,高內(nèi)聚”,我以前很討厭研究需求,覺(jué)得那些不過(guò)就是些業(yè)務(wù),沒(méi)啥技術(shù)含量,后來(lái)才慢慢認(rèn)識(shí)到,這種想法很危險(xiǎn)啊,脫離需求的軟件設(shè)計(jì)不可能很好地滿足需求,如果不能很好地服務(wù)于產(chǎn)品功能,那么再牛逼的技術(shù)都沒(méi)有機(jī)會(huì)實(shí)現(xiàn)它應(yīng)有的價(jià)值,事實(shí)上,能夠把需求文檔轉(zhuǎn)化為可實(shí)施的軟件設(shè)計(jì),也是一種能力;
不同系統(tǒng)中,要實(shí)現(xiàn)中間件框架或者底層通信基礎(chǔ)設(shè)施,Adaptive AutoSAR有ARA::COM組件,Android有Framework,但不能跨域,QNX/Linux就不用說(shuō)了。要實(shí)現(xiàn)一個(gè)中間件框架,本身并不是件容易的事,需要比較強(qiáng)的技術(shù)實(shí)力,一旦出了問(wèn)題一般都是重大問(wèn)題;
服務(wù)接口標(biāo)準(zhǔn)化,接口描述語(yǔ)言化(IDL),能夠通過(guò)工具自動(dòng)生成RPC樁的代碼(最好能夠關(guān)聯(lián)整車(chē)通信矩陣,e.g. ARXML->C++ API),能夠跨平臺(tái),支持多語(yǔ)言,畢竟UI層可能不是C++寫(xiě)的,時(shí)至今日,沒(méi)幾個(gè)應(yīng)用愿意去解析原始消息,遠(yuǎn)程調(diào)用接口不香嘛~;
如何兼容一些沒(méi)有與時(shí)俱進(jìn)的設(shè)備和模塊,如何兼容舊的傳輸通道,如何盡可能復(fù)用以前的業(yè)務(wù)邏輯,理論上任何兼容都是可以實(shí)現(xiàn)的,抽象一層不夠,那就再來(lái)一層,但兼容得越多,系統(tǒng)就越復(fù)雜,出問(wèn)題的概率就越大,維護(hù)起來(lái)就越費(fèi)勁,這意味著成本的升高,質(zhì)量卻不見(jiàn)得變好;
評(píng)估性能影響,怎么保證安全性,……,如果是基于開(kāi)源項(xiàng)目,可能還要做二次開(kāi)發(fā),來(lái)滿足這些非功能性質(zhì)的需求~;
所以,汽車(chē)SOA真不是SOME/IP,也不是DDS,更不是Adaptive AutoSAR,這些都是汽車(chē)SOA技術(shù)棧中的一環(huán),并不是全部。
很多時(shí)候,純技術(shù)的部分并不是最難的,新的架構(gòu)方案要達(dá)成共識(shí),要真正落地,需要博弈和取舍,需要天時(shí)地利人和。作為一名工程師,心態(tài)是極為重要的,要分清理想與現(xiàn)實(shí),技術(shù)與工作,所以在這里我只想談技術(shù),本來(lái)打算梳理一下做汽車(chē)SOA開(kāi)發(fā)的基礎(chǔ)知識(shí)體系,以后公眾號(hào)的內(nèi)容大致也會(huì)圍繞著這個(gè)體系去寫(xiě),沒(méi)想到寫(xiě)著寫(xiě)著這么長(zhǎng)了,于是分成上下篇了,下面先開(kāi)個(gè)頭吧。
SOA是架構(gòu),做SOA的設(shè)計(jì)和開(kāi)發(fā),其實(shí)也是做架構(gòu)的設(shè)計(jì)和開(kāi)發(fā),在這里我想引用陳皓老師為《架構(gòu)整潔之道》作的推薦序里的一段話,我常想起這段話,挺有鞭策的功效,分享給每個(gè)不想成為PPT架構(gòu)師的工程師,以共勉:
問(wèn)題:如果你要成為一名架構(gòu)師,你需要明確地區(qū)分幾組詞語(yǔ),否則你不可能成為一名合格的工程師或架構(gòu)師。這幾組詞語(yǔ)是簡(jiǎn)單vs.簡(jiǎn)陋、平衡vs.妥協(xié)、迭代vs.半成品。如果你不能很清楚地定義出其中的區(qū)別,那么你將很難做出正確的決定,也就不可能成為一名優(yōu)秀的工程師或架構(gòu)師。
陳皓,《架構(gòu)整潔之道》推薦序一
之前很長(zhǎng)一段時(shí)間,我經(jīng)常感到焦慮,一方面不想成為PPT黨,開(kāi)會(huì)黨,另一方面,除了工作還要生(帶)活(娃),留給學(xué)習(xí)的時(shí)間并不多,而想學(xué)的知識(shí)又如同汪洋大海,今天想好好梳理一下某個(gè)技術(shù)點(diǎn),明天搜到某個(gè)開(kāi)源項(xiàng)目蠻感興趣想寫(xiě)個(gè)Demo跑跑看,年輕的時(shí)候覺(jué)得日子一天天刷刷地過(guò)去,也不是什么事兒,現(xiàn)在愈發(fā)有種緊迫感。在做了一些架構(gòu)方面的設(shè)計(jì)和開(kāi)發(fā)工作以后,更是深刻體會(huì)到構(gòu)建個(gè)人的領(lǐng)域知識(shí)體系,尤其是一些基礎(chǔ)技術(shù),真的非常重要。
今年伊始,聽(tīng)了李運(yùn)華老師關(guān)于“如何打好基礎(chǔ)”的講座,核心觀點(diǎn)是:“基礎(chǔ)≠底層,基礎(chǔ)≠源碼,基礎(chǔ)≠不變”,很是醍醐灌頂~結(jié)合個(gè)人實(shí)際情況,我覺(jué)得可以這么去構(gòu)建我的領(lǐng)域知識(shí)體系:首先,定義出哪些是與我工作相關(guān)的領(lǐng)域知識(shí)(比如現(xiàn)階段是SOA);其次,進(jìn)一步細(xì)化要學(xué)習(xí)的知識(shí)范圍,也就是下篇要梳理的SOA相關(guān)知識(shí);最后,分別從廣度和深度(根據(jù)工作內(nèi)容去判別學(xué)習(xí)的深度),有針對(duì)性地學(xué)習(xí),并在實(shí)際工作和項(xiàng)目中把知識(shí)和技術(shù)串起來(lái),從而系統(tǒng)性地提升技術(shù)能力。
就像前面說(shuō)的,要分清理想與現(xiàn)實(shí),因?yàn)檫@個(gè)世界從來(lái)都不是我所能想象的,很多PPT黨開(kāi)會(huì)黨,基礎(chǔ)不扎實(shí)甚至很水,設(shè)計(jì)出焦油坑一樣的架構(gòu),坑自己,坑別人,坑項(xiàng)目,也不耽誤他們升職加薪跳槽。但是“世界上只有一種英雄主義,那就是認(rèn)清生活的真相后依然熱愛(ài)它”,不是么,于是才有了寫(xiě)公眾號(hào)的初心和決心。
②
SOA開(kāi)發(fā)梳理
今天要做的梳理,沒(méi)有思維導(dǎo)圖,沒(méi)有PDF,沒(méi)有表格,是結(jié)合了我的實(shí)際經(jīng)歷和體會(huì),總結(jié)得出的一些基礎(chǔ)知識(shí)點(diǎn),這是現(xiàn)階段的這個(gè)我所了解的所認(rèn)為的,隨著時(shí)間的流逝,我又會(huì)經(jīng)歷更多一些,現(xiàn)在梳理的可能也會(huì)跟著改變一些。這種極其個(gè)性化的梳理,對(duì)我,是梳理(其實(shí),寫(xiě)這篇比想象中艱辛,要不是前面給自己埋下了坑,都想放棄了~),對(duì)你,看看便好,就當(dāng)是聽(tīng)我絮叨絮叨,侃侃大山,輕松愉快,真心不能提供什么參考。以下梳理分為四個(gè)維度:編程,架構(gòu),網(wǎng)絡(luò),工具。
1、編程:多看,多寫(xiě),多折騰
目前,智能座艙的生態(tài)圈主要包括Android、Linux、QNX等操作系統(tǒng),因此,我認(rèn)為做SOA開(kāi)發(fā),至少需要熟練掌握C++和Java兩種編程語(yǔ)言。C++是必須要會(huì)的,Linux/QNX主要用C++開(kāi)發(fā),Android其實(shí)也涉及C++開(kāi)發(fā),尤其是對(duì)性能要求較高的模塊,通常會(huì)下沉到Native或HAL實(shí)現(xiàn)。Java也是必須要會(huì)的:第一,Android的App和Framework是用Java開(kāi)發(fā)的,需要設(shè)計(jì)和開(kāi)發(fā)SOA接口,提供給位于這兩層的應(yīng)用和服務(wù)使用;第二,設(shè)計(jì)SOA架構(gòu),要對(duì)系統(tǒng)各層級(jí)之間的接口如何設(shè)計(jì)和調(diào)用有足夠的了解,代碼都看不明白,怎么設(shè)計(jì)易用的接口;第三,寫(xiě)Demo是架構(gòu)設(shè)計(jì)過(guò)程中重要的步驟,總不能你設(shè)計(jì)的方案等著別人寫(xiě)Demo驗(yàn)證吧,更重要的是,通過(guò)寫(xiě)Demo可以發(fā)現(xiàn)很多想法上的不足,設(shè)計(jì)文檔寫(xiě)得不嚴(yán)謹(jǐn)?shù)牡胤健?
對(duì)于C++編程,要掌握的一些基礎(chǔ)知識(shí):
語(yǔ)法基礎(chǔ):構(gòu)造,繼承,虛函數(shù),內(nèi)聯(lián),多態(tài),類型轉(zhuǎn)換,STL容器,…;
C++11新特性:時(shí)至今日,應(yīng)該學(xué)會(huì)使用至少C++11常用的特性,比如:類型推導(dǎo)(auto,decltype),右值引用,智能指針,泛型/模板,type_taits,函數(shù)式編程(lambda),C++11多線程,future,promise,…,用它們使代碼更簡(jiǎn)潔,改進(jìn)代碼質(zhì)量,提升程序性能,不是為了炫技,而是用到實(shí)處;
應(yīng)用開(kāi)發(fā):Linux/QNX網(wǎng)絡(luò)編程、多線程編程、進(jìn)程間通信等編程手法,常用實(shí)現(xiàn)如無(wú)鎖,消息隊(duì)列、線程池等,常見(jiàn)開(kāi)源庫(kù)的使用,選擇感興趣的如Libevent、Muduo等,深入學(xué)習(xí)其設(shè)計(jì)和實(shí)現(xiàn);
項(xiàng)目開(kāi)發(fā):代碼結(jié)構(gòu),接口封裝方式,常用幾種設(shè)計(jì)模式的實(shí)現(xiàn)(如單例模式、觀察者模式等);
對(duì)于Java編程,要掌握的一些基礎(chǔ)知識(shí):
語(yǔ)法基礎(chǔ):包,類,接口,反射,泛型,異常,集合,注解,常用類,…;
并發(fā)編程:原子操作,Exexutor,線程池,阻塞隊(duì)列,synchronized,鎖,volatile,CompletableFuture,…,常見(jiàn)模型如Thread-Per-Message,CopyOnWrite,生產(chǎn)者-消費(fèi)者,…;
應(yīng)用開(kāi)發(fā):Java中的網(wǎng)絡(luò)編程(JDK API),Android應(yīng)用開(kāi)發(fā)基礎(chǔ)(四大組件,不研究UI,只要能整出個(gè)正常點(diǎn)兒的DemoApp就行~),Android進(jìn)程間通信機(jī)制,AIDL、JNI和HIDL接口的設(shè)計(jì)和開(kāi)發(fā);
項(xiàng)目開(kāi)發(fā):常用代碼結(jié)構(gòu),常用幾種設(shè)計(jì)模式的實(shí)現(xiàn)(如工廠模式、代理模式、門(mén)面模式、觀察者模式、策略模式等),注意,這里和前面C++說(shuō)的都是實(shí)現(xiàn),期望達(dá)到的水平:做到真正的理解,談到某種設(shè)計(jì)模式,腦子里能夠想到其適用的應(yīng)用場(chǎng)景是什么,落實(shí)到代碼上,一個(gè)大致思路是怎樣的,反之亦然;在閱讀一些開(kāi)源項(xiàng)目時(shí),能夠看出用了什么設(shè)計(jì)模式,這樣用的好處什么,不用可能會(huì)產(chǎn)生什么問(wèn)題。
2、架構(gòu):保持好奇心,平常心
架構(gòu)和編程的不同之處在于,編程是容易看見(jiàn)結(jié)果和成效的,你寫(xiě)的代碼有沒(méi)有Bug很快能被證明,你寫(xiě)的模塊擴(kuò)展性和穩(wěn)定性怎么樣,經(jīng)過(guò)一些時(shí)日,也能看出個(gè)一二。架構(gòu)不是,有多少人能在短時(shí)間內(nèi)落地幾種架構(gòu)方案的,更不用說(shuō)評(píng)價(jià)架構(gòu)設(shè)計(jì)得好不好了,就拿通信框架來(lái)說(shuō),很少聽(tīng)?wèi)?yīng)用說(shuō)滿意當(dāng)前的通信框架的,為什么擴(kuò)展個(gè)接口這么麻煩,為什么不支持同步調(diào)用,為什么沒(méi)有消息緩存,…,能被吐槽的點(diǎn)太多了。即使如此,我們還是要致力于做出好的架構(gòu),也許無(wú)法得到所有人的滿意,但設(shè)計(jì)和開(kāi)發(fā)出好的SOA架構(gòu),可以讓系統(tǒng)中每一個(gè)應(yīng)用和模塊在交互通信與數(shù)據(jù)共享的問(wèn)題上獲得不錯(cuò)收益,反之,糟糕的SOA架構(gòu)可能就是所有人必須面對(duì)的一場(chǎng)災(zāi)難。
在架構(gòu)設(shè)計(jì)這件事上,我也是剛開(kāi)始有一點(diǎn)點(diǎn)經(jīng)歷,以下所想完全沒(méi)有參考價(jià)值。
設(shè)備:跳出單個(gè)模塊的視野范圍,嘗試去了解這個(gè)通信系統(tǒng)里的每一個(gè)設(shè)備(可以是車(chē)機(jī),儀表,T-Box,網(wǎng)關(guān)等等),他們的軟件系統(tǒng),他們的硬件,硬件之間的連接,他們的功能業(yè)務(wù),他們的開(kāi)發(fā)模式,他們的數(shù)據(jù)需求,他們以往采用過(guò)的通信方案,…;
車(chē)載以太網(wǎng):了解相關(guān)知識(shí),如:CAN,LIN,診斷,標(biāo)定,CP,AP,…,重點(diǎn)關(guān)注整車(chē)以太網(wǎng)與智能座艙的對(duì)接,或者說(shuō)智能座艙未來(lái)如何接入中央計(jì)算單元。至于最近很火的AP,沒(méi)有計(jì)劃作深入研究,從編程角度來(lái)說(shuō),基礎(chǔ)是相通的,CP用的C,AP用的C++,很多東西并不是本身難度有多大,而是學(xué)習(xí)的資源和工具難以獲得,人為形成了所謂的技術(shù)壁壘,個(gè)人開(kāi)發(fā)者想要學(xué)習(xí)研究,幾乎不可能搭建環(huán)境。我覺(jué)得開(kāi)源是時(shí)代的進(jìn)步,一定會(huì)是大勢(shì)所趨,1202了,我們都要擁抱開(kāi)源呀~;
系統(tǒng):Linux/QNX系統(tǒng)調(diào)用(如輸入/輸出,存儲(chǔ),文件,網(wǎng)絡(luò),線程,進(jìn)程間),Android系統(tǒng)架構(gòu),座艙的整體架構(gòu),模塊的架構(gòu),比如,車(chē)機(jī)中Android原生模塊(如BT,WiFi,Audio,Location,…)的數(shù)據(jù)源有什么不同,車(chē)機(jī)中這些基礎(chǔ)模塊都是怎么適配的,車(chē)機(jī)中較復(fù)雜的APP如導(dǎo)航、語(yǔ)音等的架構(gòu)是什么樣的。不要覺(jué)得別人負(fù)責(zé)的模塊我了解了干嘛,說(shuō)白了,SOA就是模塊與模塊之間的交互,對(duì)每個(gè)模塊了解一下一定是有益的;
中間件:基于幾種通信模型(可參考DDS 介紹)的中間件框架,RPC技術(shù)的原理和實(shí)現(xiàn),各種開(kāi)源RPC框架:grpc,brpc,srpc,…,各種中間件架構(gòu)方案:GENIVI,ROS2,…,如何技術(shù)選型,如何驗(yàn)證可行性,如何做性能評(píng)估;
設(shè)計(jì)原則:SOLID,KISS,迪米特,…,結(jié)合具體業(yè)務(wù)的前提下追求原則,知易行難,沒(méi)有定式,如何做出正確的決策,需要在實(shí)踐中不斷思考和總結(jié);
溝通表達(dá):面向不同受眾的架構(gòu)視圖,SOA是需要傳播的,“咱們用TCP通信”和“咱們用SOMEIP通信”,對(duì)于不熟悉SOMEIP的小伙伴來(lái)說(shuō),是兩碼事。正確地傳達(dá)架構(gòu)的設(shè)計(jì),高效地溝通和解決過(guò)程中的沖突,清晰地表述技術(shù)實(shí)現(xiàn)的細(xì)節(jié),畫(huà)的UML要能指導(dǎo)開(kāi)發(fā),盡可能說(shuō)經(jīng)過(guò)驗(yàn)證的結(jié)論,即便是預(yù)估的,也要有一些數(shù)據(jù)作為依據(jù),不要說(shuō)出諸如“應(yīng)該沒(méi)問(wèn)題”這樣的結(jié)論;
項(xiàng)目+產(chǎn)品:做架構(gòu)設(shè)計(jì),可以是一個(gè)人的事,但架構(gòu)的落地,是需要一群人一起完成的,能否保質(zhì)保量完成不是項(xiàng)目經(jīng)理該去操心的事嗎?我覺(jué)得并不是,能否落地也是架構(gòu)設(shè)計(jì)中可以考慮的一個(gè)視角,適當(dāng)了解一些項(xiàng)目管理和產(chǎn)品思維的知識(shí),會(huì)使你能更好地理解這個(gè)世界,理解一個(gè)項(xiàng)目的運(yùn)作,理解一個(gè)產(chǎn)品從無(wú)到有所要經(jīng)歷的過(guò)程,理解架構(gòu)不止是一個(gè)技術(shù)問(wèn)題,這些都會(huì)幫助你設(shè)計(jì)一個(gè)好的架構(gòu)。
3、網(wǎng)絡(luò):實(shí)踐出真知,重視細(xì)節(jié)
如果說(shuō)架構(gòu)是宏觀,那么網(wǎng)絡(luò)通信的設(shè)計(jì)和開(kāi)發(fā),是件要扣細(xì)節(jié)的事兒。不要想當(dāng)然,不要把網(wǎng)絡(luò)狀況想得過(guò)于理想,不要把服務(wù)端想得過(guò)于強(qiáng)大,不要對(duì)任何錯(cuò)誤掉以輕心,試圖找到每個(gè)錯(cuò)誤背后的根源,解決的過(guò)程就是一次收獲。
網(wǎng)絡(luò)基礎(chǔ):OSI,TCP/IP,五層協(xié)議,各層作用和常見(jiàn)協(xié)議;
開(kāi)發(fā)基礎(chǔ):TCP和UDP建立連接的流程,阻塞與非阻塞Socket API,同步與異步,IO多路復(fù)用,epoll的水平觸發(fā)與邊緣觸發(fā);
通信協(xié)議:SOME/IP,DDS,HTTP/RESTful,SSL/TLS,MQTT,對(duì)于SOME/IP和DDS,準(zhǔn)備死磕:協(xié)議標(biāo)準(zhǔn),開(kāi)源項(xiàng)目的應(yīng)用,源碼剖析,二次開(kāi)發(fā),封裝接口;多媒體傳輸:AVB,RTP/RTCP/RTSP/RTMP;
序列化:JSON,Protobuf,F(xiàn)ranca IDL,MsgPack,…,各自優(yōu)缺點(diǎn)、性能效率、適用場(chǎng)景、開(kāi)源庫(kù)選型;
細(xì)節(jié):私有通信協(xié)議如何設(shè)計(jì),如何解決粘包和分片;心跳機(jī)制如何設(shè)計(jì);收發(fā)緩沖區(qū)如何設(shè)計(jì);如何優(yōu)雅地關(guān)閉連接;斷線重連機(jī)制如何設(shè)計(jì);流量控制如何設(shè)計(jì);…;
實(shí)踐:分析當(dāng)前網(wǎng)絡(luò)連接狀態(tài);定位通信鏈路中出錯(cuò)位置,分析其出錯(cuò)原因;抓包,分析數(shù)據(jù)包;如何設(shè)計(jì)Benchmark,測(cè)試和分析通信架構(gòu)的各項(xiàng)指標(biāo)如傳輸時(shí)延、CPU占用、內(nèi)存消耗、負(fù)載壓力等;
4、工具:發(fā)現(xiàn),嘗試,積累
寫(xiě)工具,會(huì)讓人覺(jué)得很Low吧,實(shí)際上,很多人低估了學(xué)會(huì)使用工具的重要性。為什么別人花一小時(shí)搭建實(shí)驗(yàn)環(huán)境,而你要一天?為什么別人花半小時(shí)定位問(wèn)題改好代碼,而你要一周?為什么別人花半天完成了某個(gè)第三方庫(kù)的平臺(tái)移植,而你要花幾天,甚至搞不定?…?其實(shí)不是別人有多厲害,而是你不善于運(yùn)用各種工具去解決問(wèn)題,也沒(méi)有注重積累,舉個(gè)栗子:一次重裝Ubuntu系統(tǒng)時(shí)遇到某個(gè)問(wèn)題,查了好幾篇CSDN文章,總算給搞定了,可什么都沒(méi)記下,下次再重裝時(shí),又遇到同樣的問(wèn)題,這個(gè)問(wèn)題我好像碰到過(guò)!然后,就沒(méi)有然后了,如果那篇之前幫到你的文章還找不到了,…,總在這樣又那樣的事情上,浪費(fèi)了太多的精力和時(shí)間,這些時(shí)間原本可以用來(lái)做更多有價(jià)值的事情啊~
開(kāi)發(fā):VSCode,IDEA,Android Studio
構(gòu)建:Shell,CMake,Gradle,Maven;
調(diào)試(測(cè)試):GDB,UT框架,靜態(tài)代碼檢測(cè),內(nèi)存泄漏檢測(cè),tcpdump,Wireshark,MQTT X,JMeter,Docker;
文檔:Markdown,PPT,Excel,筆記,Visio,EA,draw.io,錄屏,…,;
自動(dòng)化:一直覺(jué)得SOA開(kāi)發(fā)工具是值得研究的,比如API文檔自動(dòng)生成工具、API代碼自動(dòng)生成工具、回環(huán)測(cè)試工具等(在互聯(lián)網(wǎng)領(lǐng)域已經(jīng)有一些類似的工具,看過(guò)幾個(gè)開(kāi)源的,比如ShowDoc,感覺(jué)都不太能用到汽車(chē)領(lǐng)域,有好用的歡迎推薦啊~);
終于,寫(xiě)完了,好多沒(méi)有寫(xiě)進(jìn)來(lái),比如算法與數(shù)據(jù)結(jié)構(gòu)、JVM、Linux內(nèi)核、數(shù)據(jù)庫(kù)等,當(dāng)然不是說(shuō)它們不重要。但對(duì)現(xiàn)階段的我來(lái)說(shuō),上面列的這些已經(jīng)很夠我學(xué)的了,能把這些搞透徹,我已經(jīng)非常非常滿足了。術(shù)業(yè)有專攻,先把能做好的事做到最好,不是每個(gè)人都能成為技術(shù)大牛,也不是每個(gè)人的目標(biāo)都是要成為技術(shù)大牛吧,人生的路長(zhǎng)著呢,以后的事以后再想好了。有句話不是很扎心么,“以大部分人的努力程度,根本還輪不上拼天賦”,有時(shí)候只是態(tài)度就足夠拉開(kāi)差距了。
轉(zhuǎn)載汽車(chē)電子相關(guān)文章
轉(zhuǎn)自汽車(chē)電子與軟件