一個(gè)月前離開(kāi)呆了 9 年的中興軟創(chuàng),有不少東西值得寫(xiě)下來(lái),千頭萬(wàn)緒,不知從何寫(xiě)起,自己留下了 10 多萬(wàn)字的回憶,但這里面涉及的東西太多,不便公開(kāi),還是把這些年對(duì)工作的感悟?qū)懸幌掳?,這 9 年的工作基本都是圍繞前端框架的。
中興軟創(chuàng)的主要業(yè)務(wù)稱(chēng)為 BOSS,也就是電信行業(yè)的運(yùn)營(yíng)支撐軟件。早期的 BOSS 系統(tǒng)一般都不是 Web 化的,而是C/S架構(gòu),當(dāng)時(shí)大家做所謂的“前端”,用的是 Delphi,C++ Builder,或者 Java Swing。后來(lái)B/S流行之后,大家就逐漸往瀏覽器上遷移。
那個(gè)時(shí)期的瀏覽器,不像現(xiàn)在這么多樣化,一般指的都是 IE,而且可以具體到三個(gè)版本,5.0,5.5,6.0。第一批遷移到B/S模式的系統(tǒng),多半是那些簡(jiǎn)單表單的系統(tǒng),界面只是填值,作個(gè)簡(jiǎn)單校驗(yàn),然后提交給服務(wù)器。可以說(shuō),這個(gè)時(shí)候的 Web 前端是很乏味的,因?yàn)闆](méi)什么可做的,用 table 布局,里面放些 form,極少量的 JavaScript 代碼,更談不上用 CSS。
不久,Web 系統(tǒng)就復(fù)雜化了,在C/S里面,我們可能有大量的“控件”可用,基本的輸入框這些不談,在 HTML 里也有,時(shí)間日期這類(lèi),就要費(fèi)些周折了,更復(fù)雜的,比如 Tree,DataGrid,甚至 TreeGrid,就更折騰。當(dāng)時(shí)寫(xiě) JavaScript 的人還是有不少的,面對(duì)這種情況,也想出了一些辦法。
這些辦法的根本原理,都是用已有的 HTML 來(lái)拼湊出一個(gè)控件的樣子,再加上事件,一直到現(xiàn)在也沒(méi)有更好的辦法。比如說(shuō),日歷,就用 table 標(biāo)簽來(lái)生成一個(gè)表格,然后當(dāng)前日期加個(gè)顏色。又比如 DataGrid,也是一個(gè)表格,然后 tr 上面加點(diǎn)擊事件。有的流派是跟現(xiàn)在一樣,把控件的聲明和初始化都放在 JavaScript 代碼中,只在 HTML 里留一個(gè)容器標(biāo)識(shí),更主流的方式是用 HTC 來(lái)封裝控件。
如果仔細(xì)看過(guò)早期 ASP.net 的代碼,就會(huì)發(fā)現(xiàn)它帶了幾個(gè) htc 文件,比如 treelist,tabstrip,multiview 等等,這些控件的功能已經(jīng)基本能滿足需要了,就是有些丑,有些人在此基礎(chǔ)上作美化,04 年的時(shí)候,中興軟創(chuàng)的多數(shù)基礎(chǔ)控件就是這么來(lái)的。HTC 提供了一種擴(kuò)展 HTML 標(biāo)簽的機(jī)制,業(yè)務(wù)開(kāi)發(fā)人員用起來(lái)很方便,所以很有效地降低了開(kāi)發(fā)門(mén)檻。
再看另外一個(gè)方面,傳輸?shù)膯?wèn)題。最開(kāi)始大家都是把數(shù)據(jù)用 submit 按鈕提交給服務(wù)端的,但是提交就會(huì)刷新整頁(yè),效果不好。我們知道,AJAX 的概念是 05 年提出的,但是在此之前好幾年,就有不少用 XMLHTTP 的人了,我自己入職之前,03 年的時(shí)候,就用過(guò)這個(gè),入職之后看公司的前端框架,也一眼發(fā)現(xiàn)了這些東西。中興軟創(chuàng)的這套傳輸機(jī)制是在微軟顧問(wèn)的幫助下創(chuàng)建的,傳輸?shù)脑砭褪窃谇岸税驯韱螖?shù)據(jù)序列化成 XML,通過(guò) XMLHTTP 傳給后端的 Servlet,當(dāng)然,那時(shí)候用的是同步傳輸,傳的時(shí)候界面會(huì)卡一會(huì)。
05 年我剛?cè)肼毜臅r(shí)候,還沒(méi)看過(guò)系統(tǒng),老大問(wèn)我對(duì)前端這塊有什么看法,我說(shuō)可以考慮做組件化,把更多的東西封裝成 HTC 那樣的組件,然后組件內(nèi)部通過(guò) XMLHTTP 跟服務(wù)端通信,他聽(tīng)了之后說(shuō)我們現(xiàn)在已經(jīng)有一些 HTC 控件,通信也基本都是 XMLHTTP 了?;叵肫饋?lái),當(dāng)時(shí)我的思路是縱向的組件,端到端,每個(gè)組件實(shí)際上只通過(guò)事件和方法與其他組件交互,各組件自身就可以獨(dú)立運(yùn)行,應(yīng)該算是早期前端組件化的一種思路。
為了通用性,前端封裝了一個(gè)方法叫 callRemoteFunction,三個(gè)參數(shù),分別是后端的 Java 類(lèi)名,方法名和參數(shù)對(duì)象,用 XMLHTTP 發(fā)送到后端的 Servlet 之后,通過(guò)前兩者反射得到對(duì)應(yīng)的 Java 方法,執(zhí)行結(jié)果再返回給前端。這樣,在 JavaScript 里“調(diào)用”后端代碼,就像調(diào)用普通的 JS 函數(shù)那么方便。也有這樣調(diào)用動(dòng)態(tài) SQL 的,后來(lái)這兩者統(tǒng)一成服務(wù),只要傳入唯一的服務(wù)名和參數(shù),不用管是 Java 服務(wù)還是 SQL 服務(wù)。
有了這些東西做保障,業(yè)務(wù)系統(tǒng)的B/S化就容易多了。當(dāng)時(shí)的開(kāi)發(fā)模式是前后端分離,后端負(fù)責(zé)寫(xiě)服務(wù),前端寫(xiě)界面和 JavaScript,這種模式也帶來(lái)很多好處,比如有的業(yè)務(wù)系統(tǒng)后端從 .net 遷移到 Java,前端部分基本除了登錄之類(lèi),都沒(méi)什么要改動(dòng)的,人員的協(xié)作也是很順暢的。
在遷移系統(tǒng)的過(guò)程中,也有其他一些混雜技術(shù),比如說(shuō),處理一些監(jiān)控圖形之類(lèi)的,由于缺乏經(jīng)驗(yàn),加之為了重用之前的 Swing 代碼,搞了一些 Applet,雖然混搭的風(fēng)格不太好看,但當(dāng)時(shí)是沒(méi)什么人講究這個(gè)的,業(yè)務(wù)系統(tǒng)能用就行了。因?yàn)槲胰肼氈案氵^(guò) VML,所以極力鼓動(dòng)把各種圖形的東西搞成 VML,這個(gè)東西在當(dāng)時(shí)最大的優(yōu)點(diǎn)是不需要給瀏覽器安裝插件,其他任何方式都做不到。
后來(lái)就有了 IOM 系統(tǒng)那個(gè)很典型的自動(dòng)布局流程建模界面,核心部分有 3k 多行 JS,花了近 2 個(gè)月,期間還重構(gòu)過(guò)一次,后來(lái)陸續(xù)改需求,到 06 年下半年才不太改動(dòng)了。從此之后,公司的 Web 圖形這塊,基本都是用 VML,不再有人提 Applet 的事了,而且?guī)啄陜?nèi)也沒(méi)有用 Flash 做這類(lèi)圖形的,據(jù)我所知,業(yè)界當(dāng)時(shí)用 Flash 做圖形界面比用 VML 的還多些。
到了 07 年,F(xiàn)irefox 就占不小的市場(chǎng)比例了,而且 HTC 這個(gè)東西,微軟自己也不太看好,所以不得不未雨綢繆,考慮這些東西的替代方案。正好當(dāng)時(shí)調(diào)動(dòng)部門(mén),新部門(mén)打算徹底翻新產(chǎn)品,所以有機(jī)會(huì)考慮前端的新方案。作為前端的整合框架,有兩條道路可走,一條就是選擇別人的方案,比如早一點(diǎn)的 Bindows,還有當(dāng)時(shí)比較火的 ExtJS,另一條就是先引入一個(gè) JavaScript 基礎(chǔ)庫(kù),然后在上面自己做控件。經(jīng)過(guò)慎重考慮,還是選了后者,因?yàn)槲覀兊臉I(yè)務(wù)需求比較復(fù)雜,改控件的情況很多,要是用了 ExtJS 這類(lèi),雖然看起來(lái)什么都有,但是改東西估計(jì)就痛苦了。
接下來(lái)就是選基礎(chǔ)庫(kù)了,流行的有 Prototype,Mootools,jQuery,甚至還有萬(wàn)常華的 JSVM,在那個(gè)時(shí)候其實(shí)很難預(yù)料到后面 jQuery 這么火,就算到現(xiàn)在我也不能理解,所以我們的選擇是 Prototype,然后在它基礎(chǔ)上構(gòu)建外圍庫(kù),主要是控件。
當(dāng)時(shí)看過(guò)很多 UI 庫(kù)的機(jī)制,比較來(lái)比較去,覺(jué)得最能接受的還是 YUI 的方式,所以大致按照這種方式做下去了。我們的控件體系是比較松散的,彼此之間無(wú)任何依賴關(guān)系,可以獨(dú)立引用,控件的唯一參數(shù)就是父容器,然后傳入初始化參數(shù),加載數(shù)據(jù)之類(lèi)。
這一代控件的 DataGrid 和 TreeGrid 是我做的,跟上一代最大的區(qū)別是簡(jiǎn)化了事件。比如說(shuō),之前的控件選中行用的是點(diǎn)擊,但是鍵盤(pán)的方向鍵也可以改變選中行啊,這時(shí)候業(yè)務(wù)方需要監(jiān)聽(tīng)控件的兩種事件,在每種里面都做選中行變更的操作。這一代里面我只給業(yè)務(wù)方開(kāi)放 change 事件,不管實(shí)際是從什么事件發(fā)起的,最終需要關(guān)注的只是這個(gè) change,在控件上,行的點(diǎn)擊事件這種過(guò)于原始的事件是沒(méi)有意義的,直接拋給業(yè)務(wù)方非常不合適。剛開(kāi)始改成 change 的時(shí)候,有些業(yè)務(wù)開(kāi)發(fā)人員不太習(xí)慣,不過(guò)很快就覺(jué)得這樣方便了。
這一代的 TreeGrid 控件我作了懶加載,但實(shí)現(xiàn)的細(xì)節(jié)上有些考慮不周了,比如說(shuō),下層節(jié)點(diǎn)在未展開(kāi)的時(shí)候,DOM 不創(chuàng)建,這沒(méi)有問(wèn)題,但是我連節(jié)點(diǎn)對(duì)象都沒(méi)創(chuàng)建,當(dāng)業(yè)務(wù)方要訪問(wèn)未展開(kāi)的節(jié)點(diǎn)數(shù)據(jù)時(shí),只能從數(shù)據(jù)源上去獲取,已展開(kāi)的節(jié)點(diǎn)和未展開(kāi)節(jié)點(diǎn)的訪問(wèn)方式不同,這算是一個(gè)敗筆。
整體來(lái)說(shuō),這一代的框架運(yùn)作還是很成功的,比較穩(wěn)定,但整個(gè)版本關(guān)鍵的一點(diǎn)沒(méi)有達(dá)到,就是跨瀏覽器,也就是說(shuō),即使把控件代碼改成純 JS 的,也沒(méi)讓整個(gè)版本跨瀏覽器,這很悲劇。一個(gè)關(guān)鍵問(wèn)題是版本時(shí)間太緊,框架層從無(wú)到有三個(gè)月之后,業(yè)務(wù)側(cè)就大量啟動(dòng)開(kāi)發(fā),有不少問(wèn)題沒(méi)有來(lái)得及解決,更本質(zhì)的問(wèn)題在于當(dāng)時(shí)我們?nèi)狈?jīng)驗(yàn),沒(méi)有對(duì)業(yè)務(wù)開(kāi)發(fā)人員作約束,比如說(shuō),有些要避免的寫(xiě)法沒(méi)有列出,對(duì)于跨瀏覽器怎樣測(cè)試,也沒(méi)有時(shí)間作考慮。等到打算解決這些問(wèn)題的時(shí)候,面對(duì)海量的業(yè)務(wù)代碼,已經(jīng)無(wú)從下手了。
這個(gè)版本中,也遇到一些比較新的需求,比如說(shuō)有的監(jiān)控需求,要實(shí)時(shí)通信,那時(shí)候沒(méi)有 WebSocket 可用,就用 Flash 的 Socket,搞了一個(gè)不顯示的 Flash,專(zhuān)門(mén)用來(lái)連 Socket,然后再用 JS 跟它交互,效果還可以,只是因?yàn)?Flash 的跨域策略升級(jí)過(guò)幾次,導(dǎo)致踩了一些坑。
說(shuō)到這個(gè) Flash,又扯到另外一些話題,早期搞前端的人,多數(shù)都玩過(guò)它。Flash 內(nèi)置一些控件,比如基本表單輸入,還有調(diào)用 WSDL 格式 WebService 的通信控件,整個(gè)體系其實(shí)成熟度不比 HTML 低,只是我一直對(duì)時(shí)間軸很痛恨,所以即使搞,也都傾向直接用 AS 寫(xiě),很少用元件轉(zhuǎn) MovieClip 那些東西。后來(lái) 2004 年推出的 Flex1.0,徹底不一樣了,我研究過(guò)一陣,也想過(guò)如果在企業(yè)應(yīng)用領(lǐng)域,全部用它來(lái)構(gòu)建前端如何?
這個(gè)想法是有些激進(jìn),但對(duì)于企業(yè)應(yīng)用而言并不過(guò)分,企業(yè)應(yīng)用連 Applet 都能接受,機(jī)器上要裝 10 多M的 JRE,那用 1M 多的 FlashPlayer 不是更好嘛,而且當(dāng)時(shí)很多開(kāi)發(fā)人員寫(xiě)不好 JS,尤其是代碼規(guī)模較大的時(shí)候,但他們寫(xiě) Java 都還湊合,如果用 AS 來(lái)寫(xiě),代碼效果應(yīng)該好不少。
當(dāng)時(shí)的 Flex 是要部署到應(yīng)用服務(wù)器里的,運(yùn)行機(jī)制大致就像 JSP 那樣,文本代碼經(jīng)過(guò)一個(gè)預(yù)編譯,然后發(fā)到瀏覽器端來(lái)執(zhí)行。當(dāng)時(shí)制約 Flex 發(fā)展的主要因素是客戶端機(jī)器的配置,F(xiàn)lash 體系的界面效果較好,但比較占資源,而且在開(kāi)發(fā)階段的優(yōu)勢(shì)也體現(xiàn)不出來(lái)。
但我一直認(rèn)為,F(xiàn)lex 體系在較大一個(gè)時(shí)間段中很適合企業(yè)應(yīng)用體系,因?yàn)闉g覽器混戰(zhàn)的時(shí)期很長(zhǎng),亂象環(huán)生,老的瀏覽器遲遲不去,多少年也抹不平兼容的坎。對(duì)企業(yè)應(yīng)用而言,搞跨瀏覽器兼容這方面并非它的核心價(jià)值,如果有一種技術(shù)能暫時(shí)抹平這些瀏覽器的差異,優(yōu)勢(shì)會(huì)是很明顯的。要說(shuō)占資源大,難道 ExtJS 占資源就小了?企業(yè)應(yīng)用連 ExtJS 都可以接受,當(dāng)然更能接受 Flex。
所以從 09 年開(kāi)始,又逐步進(jìn)行 Flex 的引進(jìn),當(dāng)時(shí)的 Flex 發(fā)展到了 3.0,整體算是比較成熟了,后來(lái)陸續(xù)花了兩年時(shí)間支撐業(yè)務(wù)產(chǎn)品的開(kāi)發(fā),效果還可以,但從引入時(shí)機(jī)來(lái)說(shuō),還是略有些晚,如果再早兩年引入,狀況會(huì)更好一些。
另外一方面,BOSS 領(lǐng)域的應(yīng)用系統(tǒng)并不局限于企業(yè)應(yīng)用類(lèi),也有一些是面向個(gè)人用戶的,比如說(shuō)自服務(wù)和網(wǎng)上商城,前者類(lèi)似 10086.cn 那種模式,個(gè)人消費(fèi)者可以登錄辦理一些簡(jiǎn)單業(yè)務(wù),后者就是典型的網(wǎng)店,只是所賣(mài)的限于電信類(lèi)的實(shí)體商品(手機(jī)、上網(wǎng)卡等)或者虛擬商品(套餐,流量)等。
這個(gè)場(chǎng)景跟之前的內(nèi)網(wǎng)應(yīng)用大有不同,算是真正的互聯(lián)網(wǎng)模式了,所以它所用的前端框架就與其他的不同。由于精力所限,開(kāi)始幾年在這方面的投入很少,一般都是用 jQuery 外加一些開(kāi)源的控件,這樣整合起來(lái)用,頁(yè)面不花哨也不復(fù)雜,基本功能也是能夠滿足的,做的效果只能算是湊合,主要是沒(méi)有熟悉 CSS 的人。
在做電信業(yè)務(wù)運(yùn)營(yíng)支撐的這類(lèi)公司,UI 一直是薄弱環(huán)節(jié),不可能得到本質(zhì)上的重視。整個(gè)中興的整個(gè)體系里,軟件的重視程度并不如硬件,比如從手機(jī)上面就看得出來(lái),賣(mài)了手機(jī)之后就不太重視后續(xù)軟件升級(jí)了,還是賣(mài)老的功能機(jī)的思路。在軟件體系里面,前端也處于相對(duì)弱勢(shì)的地位,畢業(yè)生入職的時(shí)候,都會(huì)優(yōu)先讓編程水平較高的做后端,在前端里面,邏輯和業(yè)務(wù)的重視度又高于 UI,所以 UI 保持能用就不錯(cuò)了,在關(guān)鍵的一些跨瀏覽器兼容,CSS 規(guī)劃方面,基本是沒(méi)有什么進(jìn)展的。好在近兩年,由于有了 BootStrap 這樣的東西,把很多原本要做的事情做掉了,所以只要對(duì)界面沒(méi)有特別的需求,光會(huì)寫(xiě) JS 也能把界面搞得像模像樣。
這部分的前端框架,其實(shí)也不是這么搞就完事的,基于傳統(tǒng)的思維,做這些界面的時(shí)候,開(kāi)發(fā)人員仍然傾向于使用偏重量級(jí)的控件,而不是使用界面模板庫(kù)等方式來(lái)做一些數(shù)據(jù)展示的效果,這一方面帶來(lái)的是觀感的不佳,另一方面,由于引用的一些控件庫(kù)沒(méi)有很精細(xì)地隔離,往往都是整套控件一起引入,甚至在一個(gè)界面里還出現(xiàn)同時(shí)引用多種界面庫(kù)的惡劣情形,一個(gè)并不算復(fù)雜的界面,引用的壓縮之后的文本代碼就高達(dá)1-2M 之多。
所以從這個(gè)方面講,公司的多數(shù)前端人員并不專(zhuān)業(yè),專(zhuān)業(yè)與不專(zhuān)業(yè)體現(xiàn)在什么地方?是要有一個(gè)整體的優(yōu)化。前端與后端開(kāi)發(fā)方式的一個(gè)本質(zhì)差異是引入任何東西的代價(jià)都比較大,因?yàn)槟愕拇a要先經(jīng)過(guò)一次網(wǎng)絡(luò)傳輸才能執(zhí)行到,而且還要注意避免沖突。如果只要引用某個(gè)功能,就不應(yīng)把其他不相關(guān)的東西也一起引入,所以那種一個(gè)大控件庫(kù)整體打包的方式在這種面向互聯(lián)網(wǎng)終端用戶的模式下非常不合適。這個(gè)道理并不難理解,但為什么操作的時(shí)候很少有人注意避免呢?
因?yàn)閮蓚€(gè)原因:
精確控制的代價(jià)較大。這一點(diǎn)確實(shí)是個(gè)大問(wèn)題,要做精確控制,最小依賴,需要把整個(gè)框架的依賴關(guān)系理清楚,在現(xiàn)有的開(kāi)發(fā)體制下,誰(shuí)為這個(gè)時(shí)間買(mǎi)單?既然沒(méi)有,那基本上就沒(méi)人管了。
加載的字節(jié)量未作為系統(tǒng)上線的考核指標(biāo)。從反面說(shuō),如果這么做了,功能倒是能用,但系統(tǒng)加載慢了,有多慢,這個(gè)沒(méi)有預(yù)設(shè)的性能底線,一般趕時(shí)間做的系統(tǒng)也都不會(huì)太糾結(jié)在這上面,能用了按時(shí)上線了就大家都謝天謝地。
從決策層的觀念上,也有一個(gè)誤區(qū),比如認(rèn)為自服務(wù)類(lèi)系統(tǒng)不算核心系統(tǒng),對(duì)開(kāi)發(fā)技能的要求也不會(huì)多高,湊合能用就行了,事實(shí)并非如此!企業(yè)應(yīng)用型的系統(tǒng),才是不特別考驗(yàn)開(kāi)發(fā)技能的,考驗(yàn)的更多是架構(gòu)水平,它在前端的坑并不多,所以完全可以由個(gè)別架構(gòu)水平高的帶著一群偏弱點(diǎn)的開(kāi)發(fā)人員做,而網(wǎng)站類(lèi)的對(duì)每個(gè)開(kāi)發(fā)人員的前端技能水準(zhǔn)要求都更高,如果不改變以往的思維方式,后續(xù)這類(lèi)系統(tǒng)會(huì)經(jīng)常收到投訴。
近兩年,因?yàn)橐紤]未來(lái)老舊瀏覽器淘汰之后的事情,所以我花了不少時(shí)間研究了一些懶加載框架,還有一些前端 MV*框架,尤其在 AngularJS 上,花了很多精力,比如 12 年的時(shí)候打印了源碼來(lái)看,也做了各種嘗試。這些東西用在企業(yè)應(yīng)用領(lǐng)域,是極好的。第一次看到 AngularJS,是因?yàn)楫?dāng)時(shí)在尋找通過(guò) HTML 屬性實(shí)現(xiàn)數(shù)據(jù)綁定機(jī)制的方案,然后就看源碼,看同類(lèi)方案,一發(fā)不可收拾。
后來(lái)的規(guī)劃,是用它來(lái)實(shí)現(xiàn)核心邏輯,而外圍的 directive 層分為 PC 瀏覽器和移動(dòng)終端兩類(lèi),這樣可以實(shí)現(xiàn)邏輯的共享。到了該考慮移動(dòng)端的時(shí)候,又碰到了 Ionic,真是想什么來(lái)什么,也說(shuō)明我的這些路不孤單,還有一些人用同樣的思路在走。
之前公司也搞過(guò)移動(dòng)端的系統(tǒng),用了響應(yīng)式設(shè)計(jì),也碰到一些坑,從我的角度看,公司用響應(yīng)式設(shè)計(jì)還是要慎重,因?yàn)橥耆珱](méi)有熟悉 CSS 的人,要用這個(gè)風(fēng)險(xiǎn)很大。
近兩年考慮的另外一些事情是前端開(kāi)發(fā)的工程化,這個(gè)路也不孤單,各大公司都或多或少的在做,比如前端組件的管理,自動(dòng)化測(cè)試,發(fā)布等等,典型的有百度 FIS。當(dāng)系統(tǒng)規(guī)模擴(kuò)大的時(shí)候,在代碼管理和發(fā)布問(wèn)題就特別多,前幾天看到 winter 的微博,應(yīng)該也是踩到不少坑。。。所以說(shuō),架構(gòu)師要考慮的事情,一方面是系統(tǒng)自身的架構(gòu),另一方面要考慮團(tuán)隊(duì)在協(xié)同開(kāi)發(fā)時(shí)候可能遇到的問(wèn)題,從技術(shù)角度盡可能及早把這些東西化解。這方面花費(fèi)的精力很可能比真正在產(chǎn)品里花的還多,而且是很痛苦的,做了很多之后還不容易看出作用。
去年在上海一家公司面試的時(shí)候,跟面試官聊得非常投緣,他問(wèn)一句我答一句,有時(shí)候他話沒(méi)說(shuō)話我就接著說(shuō)下句,我話沒(méi)說(shuō)完他就接著說(shuō)下去,最后兩個(gè)人相對(duì)大笑,那是發(fā)自內(nèi)心的苦笑,前端架構(gòu)這個(gè)大坑啊。他說(shuō),對(duì)吧,架構(gòu)這事,比的就是你踩過(guò)多少坑,我們這一路上踩過(guò)來(lái)的坑,都是血和淚。我倆笑得像《投名狀》電影里,劉德華最后流著淚笑得樣子。
碰到的另外一個(gè)聊得很投緣的人就是支付寶的玉伯,可能因?yàn)闃I(yè)務(wù)場(chǎng)景比較接近,而且大家的努力方向都在前端的工程化方面,所以很多東西都是所見(jiàn)略同。
早些年,公司的前后端分離開(kāi)發(fā),效率很高,問(wèn)題也少,不知為什么做著做著就成了不分的模式,開(kāi)發(fā)人員從 HTML,JS,Java 一直寫(xiě)到 SQL,什么都搞,什么都不專(zhuān)業(yè),很可怕,我提了不知多少次意見(jiàn),從未得到回應(yīng)。雖然最近業(yè)界很多鼓吹全棧工程師的,但這只能讓那些個(gè)人能力較強(qiáng)的去做,作為補(bǔ)充,不能成為普遍做法,對(duì)于招聘人員水準(zhǔn)比不上互聯(lián)網(wǎng)公司的傳統(tǒng)軟件商,更是應(yīng)當(dāng)把人員分工搞好,這樣才可能真正做好產(chǎn)品。
過(guò)去的事情都過(guò)去了,回頭看看自己這些年,在工作上還是花了不少心思,每次有想法,都會(huì)說(shuō)出來(lái),哪里覺(jué)得不對(duì),都會(huì)認(rèn)真提出自己的理由。努力做一些與眾不同的事情,會(huì)寫(xiě)一些工作方面的文章,會(huì)用業(yè)余時(shí)間組織培訓(xùn)交流,會(huì)自己出錢(qián)買(mǎi)書(shū)送給同事。從未提出過(guò)讓自己團(tuán)隊(duì)任何人加班,研發(fā)過(guò)程獎(jiǎng)也從未給過(guò)自己一分錢(qián)。有時(shí)候真不知道自己的堅(jiān)持是為了什么,努力過(guò)之后,發(fā)現(xiàn)能改變的東西還是太少,很失落。
曾經(jīng)是一個(gè)缺乏勇氣的人,下棋或者打游戲碰到形勢(shì)不好就立刻認(rèn)輸,后來(lái)看我同學(xué)阿龍打星際,屢屢被人打得只剩一個(gè)農(nóng)民還到處逃竄開(kāi)礦企圖翻盤(pán),看得多了,也就比以前肯堅(jiān)持。人的一生,兩件事最重要,一是努力,二是選擇。這兩者都不容易,這次狠心選擇了新的道路,希望能堅(jiān)持下去,不知道再有 9 年之后,會(huì)是什么樣?
-
工程師
+關(guān)注
關(guān)注
59文章
1590瀏覽量
69506 -
中興
+關(guān)注
關(guān)注
6文章
2000瀏覽量
67922
發(fā)布評(píng)論請(qǐng)先 登錄


硬件工程師看了只會(huì)找個(gè)角落默默哭泣#硬件工程師 #MDD #MDD辰達(dá)半導(dǎo)體 #產(chǎn)品經(jīng)理 #軟件工程師
【華秋DFM】V4.6正式上線:工程師的PCB設(shè)計(jì)“好搭子”來(lái)了!

如何成為一名嵌入式軟件工程師?


一位老電子工程師的十年職場(chǎng)感悟

嵌入式軟件工程師就業(yè)好不好?

不同時(shí)期的硬件工程師,最怕發(fā)生的事 #電子工程師 #硬件工程師 #內(nèi)容過(guò)于真實(shí) #YXC晶振 #揚(yáng)興科技
RVFA 認(rèn)證賦能未來(lái):資深 IT 專(zhuān)家 Andrea Gallo 的職業(yè)轉(zhuǎn)型技術(shù)之旅


當(dāng)你的工程師朋友失聯(lián)時(shí),別氣,ta真的是在忙工作 #搞笑 #電子愛(ài)好者 #硬件工程師 #晶振 #揚(yáng)興科技

硬件工程師VS軟件工程師|硬件工程師看到這都淚目了!#硬件設(shè)計(jì) #硬件工程師 #電子工程師 #軟件工程師
Victor Labián Carro:以好奇心成就 RISC-V 職業(yè)成功之路

評(píng)論