怎麼區別java程序員技術級別?

作者:nonesuccess
鏈接:http://www.zhihu.com/question/20034808/answer/20457416
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

校園級別的程序員的標誌:

代碼中最多的是嵌套if(null == xxx),還要告訴你,null必須寫在前面,我靠。

防止把==寫成=,c語言時代常犯的錯誤。由於null不能做左值,在寫=的時候出現編譯錯誤。一般來講,在java中,由於boolean和其他類型不會作隱式轉換,因此這麼寫沒有意義。

寫着寫着突然想起來這麼個代碼:

Boolean b = true;

if(b=null)
{

}

順利編譯通過,也許把null寫在==的左側還是有意義的。

後臺滿是system.out.println("--------程序應該會運行到此處的。。。userId:")。

調試程序過程中,如果想在控制檯中打印什麼東西,最好用log工具,如已經在多少年前就俗到家了的log4j。好處是:打印日誌的語句和控制是否打印日誌、控制怎樣打印日誌的語句是解耦的,可以在程序中隨便寫打印log的語句,然後在正式上線後,通過某個選項,令其全部失效。

當年流行的組合是log4j+apache commons logging,在程序中引用commons logging的api,build path中放一個log4j的jar包然後再寫個log4j的配置文件並且初始化一下,實際生效的就是log4j了。這樣做的好處是,想換日誌實現類的時候,不用修改程序代碼。

今年的流行款是logback+slf4j,對應上面那兩個東西。logback的實現據說效率高了多少倍,不過除了非常關鍵的模塊外,這點開銷基本可以忽略不計。
html頁面總是對不起一兩個div的線,老用firefox去框框顯示那個div。

搞前端的都是神,我到現在也對不齊那堆div。另提一句,bootstrap是良心作,好人一生平安。
IO異常處理那個就是疊羅漢啊。

異常處理是個技術活,我當年的思路是,根本不知道有非受控異常這件事,出現受控異常未處理的編譯錯誤時,點開eclipse的自動處理選項,然後按照心情選一個。

一點經驗:

數據庫異常、io異常就直接上拋,如果框架非得搞成checked的話(譬如ibatis2.x),發現了就給封一層RuntimeException,一直拋到頂層讓這個事務掛了就好了。然後客戶會明確的知道這個程序sb了,怒不可遏的給維護打電話,然後維護遠程ssh,重啓數據庫了事。如果項目經理稍稍良心一點的話,針對這種錯誤可以做的包括:1、打異常log,2、給客戶一個明確的提示“系統掛掉了,請聯繫系統維護人員電話是13xxxxxxxxx”而不是顯示一堆異常堆棧然後再讓客戶翻電話本。想寫段代碼自動處理這些異常的想法不是不能實現,但對於業務定製類的系統來說,代價太大。

nullpointerexception、各種illegelxxxexception,其它各種開發人員懶得去學的異常,這些基本上都是程序的bug,開發測試階段出現了就調整,打各種補丁,直至所有的測試流程都走通。實際運行階段再出的話,類比上一條。

在業務基本走通,正常流程都沒問題了,而項目組又恰好有足夠的時間投入在異常架構上,可以做下面的事:分析業務,找出需要處理的業務異常,如根據身份證號查出了兩個完全不同的人等,定義處理這些異常的邏輯,定義項目級別的異常基類api,之後就可以從底層一層層的加各種if判斷,拋出異常,再向上找到該處理異常的地方,寫catch代碼。最重要的就是在拋異常的時候,把所有有意義的信息都記錄下來,比如上面說的身份證號的異常,起碼要記錄身份證號是什麼、找出的兩個人的主鍵,另外還可以記錄操作時間、操作人等信息。只要在異常拋出的時候做到這一點,隨便你決定在哪一層catch,哪怕只做個log,都會讓維護人員、後續開發人員感謝你的良心。


一般級別的程序員標誌:
會struts+spring+hibernate|mybatis,面試神器。

曾經的觀點:

怎樣用這些東西:找個文檔讀一點,都能學會。

爲什麼要用這些東西:體現真正水平的問題。

現在的觀點:

怎樣用這些東西:做到隨便給給技術,讀讀文檔就能用上的,都是水平已經不錯了的人。

爲什麼要用這些東西:網上答案一搜一大把,需要分辨是直接拿的結論,還是真被某些雷炸過然後很良心的告訴你,struts2真操蛋。

struts1、2、spring mvc這一層,用的並不多。由於沒做過什麼訪問量特別高的項目,因此對struts2的效率並沒有太多吐槽。現在的選擇標準:1、是否提供了足夠的語法糖讓一般水平的人也能夠快速開發 2、是否沒有提供不恰當的語法糖,從而大幅度的增加維護難度。annotation、零配置這些東西,個人覺得最好用於元屬性設置,而不要用於流程控制。曾經有個同事發現前臺傳進來的參數莫名其妙的會丟一個,後來發現在引用的某個jar包中有一個annotation方式定義的filter。儘管實際上的問題是架構組沒有寫完善的文檔,沒有做培訓,但是經過那件事之後我也同意,這種東西放在一個統一的配置文件裏面看着會更清楚一點,控制粒度也更細一點。

當年實訓初學spring就覺得這東西很蛋疼,迄今爲止一直沒遇到複雜度高到有大批量屬性需要注入的地方。aop的應用場景倒是遇到幾個,不過出於對龐大的spring以及配置文件膨脹的恐懼,我寧願改變整個的框架,定一個抽象層然後用各種各樣的strategy模式。倒是覺得有完善annotation支持的輕量級aop應該是個不錯的選擇。

hibernate用的也不多,我好像對主流的s2sh有本能的抗拒……一直對sql的結構化有深深的執着,因爲你真的不想沒事總給別人調那一堆動輒五六行變量名很奇怪大小寫都有的sql語句。所以在看到hibernate做某些複雜查詢必須用hql的時候就放棄了這門技術了,sql本身就不想看,再發現這sql實際上是在java裏面用String拼起來的……

ibatis/Mybatis一系用的比較多的原因是,職業生涯用到的首套一站式框架的作者就用的這玩意兒,屬於馬屁股性質的事情。這東西的好處就是把sql和java代碼分離開了,程序看起來比較乾淨。但是讓每個模塊的程序員都去決定要寫哪些sql,怎樣寫,同樣是個很可怕的事情。所以當年我定義了一套針對每張表的標準sql列表,幾項最基本的CRUD操作。select操作只支持id查詢和各個屬性的and相等查詢。這個基本上已經可以滿足80%的需求了,剩下20%,定好了配置文件分割策略後,找個sql好點的人慢慢寫就是了。另外,這東西的一大槽點是隻支持假分頁,我們的處理方式一般是忽悠客戶買個內存大點的機器就得了,不具備這種忽悠機制的同行們請慎重選擇,ibatis想解決這個問題需要hack jar包,mybatis也需要自己寫個插件支持,大概有個半天到一天的工作量。

再後來覺得配置文件有些繁瑣,所以又在apache commons dbutils基礎上封裝了一套,不用寫配置文件,定義好列名和屬性名的映射關係後,自動生成CRUD操作並作db訪問操作。在封裝複雜的select操作時發現了nutz這個東西,覺得思路基本一致,就懶得再繼續寫了。

nutz提供的dao工具實現了用比較結構化的方法拼sql語句,試了試,用着還不錯。事務管理機制據說有槽點,沒細看。

決定我沒有實際使用的槽點:1、不支持手動配置db和java的名稱映射,而我給項目組定的映射規則又比較奇葩,給每個屬性都寫個annotation有點蛋疼。2、貌似是用反射方式直接讀寫java屬性,而不是用java bean規範的get、set方法,而我的很多工具類都是做的虛擬屬性,只有兩個無比複雜的get/set方法,沒有實際的屬性。當發現annotation只能加在字段上時,欲哭無淚只好放棄了。

現在項目中用着的還是mybatis,用官方提供的mybatis generator生成配置文件,單表操作支持得很完善,多表操作自己寫sql解決。


能分清楚group和having的區別。

關於db另一個要說的問題:複雜的東西儘量別放sql裏面。orm層提供基本操作就夠了,剩下的邏輯交給java層表達。做好封裝,實在有效率問題,再專門進行優化。好吧,我承認我不知道這哥倆到底有什麼區別。


數據庫裏的字段必須只能2個長度,不能32個長度,性能問題。表名要以T開頭,蛋快碎了。

長度問題沒看懂要說什麼。前兩天遇到一個問題,在oracle中如果用char類型的,而實際內容又不正好等於char長度的時候,select出來的數據是帶空格的……各種trim都感覺不太好使之後,果斷varchar2了。反正這點效率差異,早就被各種奇葩的業務邏輯給抵消了,還是那句話,有問題的時候再優化。

表名問題,我覺得加前綴還是爲了跟視圖進行區分。當表只有幾張時,什麼區分也不用做,當表有一百七十張時,什麼區分都不管用。所以,戰略上看需求決定就行了……

一點經驗:通通加T跟沒加是一個效果。現在項目中的做法:數據庫中大部分的表都是對應了一個業務實體,這些類直接寫名字就行,在這些表上建的視圖統一加一個V_前綴,也就能起到區分效果了。一般來講,一百七十張表中至少有一百五十五張以上都是這種表。其他的表,則大多對應了某些特殊場景或算法,實際開發中一般由專門的核心人員負責,可以按照權限控制、事務控制等實際用途,加個什麼前綴,誰負責哪個模塊就關注哪個前綴就好了。


會用jquery.ajax獲取數據,不知道ajax的同步鎖。

我也不知道。對於一切鎖,我的意見都是,上個最大粒度的,保證數據一致性。出現的所有問題具體分析,逐個減小鎖的粒度。


一會顯示的表格有數據,一會又沒數據啊,太生氣了。

遇到此類抱怨時:1、告訴他,工業界沒有玄幻故事,2、再提同樣的問題的話,辭了他。讓這種人覺得自己還有混在程序員界的錯覺是對他的不負責。

詳細記錄當時的運行環境,一般都會找到原因的。


騷年級別的程序員標誌:

懂div的float,clear的含義。

1、上一套bootstrap,解決80%的問題。2、剩下20%的問題,找個跟你關係不錯的前端,沒事多請人家吃吃飯,然後就解決了。


數據庫超過n記錄表橫向縱向分表。

問題在於,n等於幾。高估n無所謂,反正要出現的問題肯定會出現。低估n的話,造成的進度損失會讓你有自殺的衝動,造成的數據損失會讓項目經理有殺了你的衝動。


知道oracle的用with,這個sql寫起來看起就舒服了。

這個也不會,粗略google了一下,確實有點用途。


看到aop能說一大堆廢話,又是代理又是反射,就是沒寫過。

你的錯誤在於,不知道用途就研究實現原理。


DateUtil一定寫過好多次,簡直太複雜了,非常多的格式定義,那個static格式變量,必須要深刻理解才能知道。

1、有句評價說的好:把一個工具包的幾乎所有方法都寫到標記過時,這是得有多仇視這個社會。

2、自從有了JodaDate,媽媽再也不擔心我的日期處理了。當一個同事又一次熬通宵寫出一個DateUtil然後我拿出了JodaDate之後……


砥柱級別的程序員標誌:

會架構程序,能用extjs或者easyui寫個框架frame,還能寫個遞歸menu。

所有的知識點都很基礎,但是能把這一切都完整寫出來,完成debug之後讓項目組用上,一段時間之後還能維護或者添加點新功能的,都是中流砥柱。說白了,這是個情商要求大於智商要求的活。業務系統定製開發,實際上都是這種類型的活。你並不需要有特別高深的技術,也不會突然面對多麼巨大的困難,只會在一個個看似不起眼的bug中,把所有激情都消磨殆盡。

會用ps處理圖片,還能寫上幾個字,XXXX系統beta版本。

會ps的都是神,不解釋。


基本上util包的作者,用log或者攔截器記錄日誌。

並且,願意跟一切動過你util包的人玩命。


能用fiter或者Interceptor處理權限,但是搞不懂如何處理button的權限。

在業務級別去掉button權限的需求就好了。

真正的解決方案沒有實際執行過,只是一個想法:系統建模的時候,權限模型直接建到操作級,比方說每個Action處理函數對應一個操作,針對這個操作定義每個角色的權限。button在概念上同樣映射到權限就可以了。至於怎麼針對函數做權限控制,隨便你用xml或者annotation定義一下就行。


明白了異常處理轉換成RuntimeExcetion太好了,不會丟失而且好處理。

異常處理真是個技術活。當我說,我也不知道我的方案好在哪,只是覺得你們的方式不優雅時,我清楚的聽到了對方心裏的嗤笑聲。往往我的結論都會在大概三個模塊開發週期之內被確認。


page分頁裏代碼和css樣式和類class都在jsptag裏,認爲沒法分啊,這個是典型。

前端用於提交參數,目測所說的代碼是計算page、rowperpage這些屬性的。隨便找套js grid控件,看看他們的參數提交方式,前端不依賴任何jsp,分到那個份上我覺得就足夠了。



小牛級別的程序員:

知道url資源樹和menu的區別。

不明覺厲。這種概念性的東西其實挺多人都挺不重視的,曾經很反對這種不重視,但是重視了很多年還真沒重視到什麼收穫。現在的觀點就是,用到了再說。


能手寫css,懂important能拿來做啥,這個好玩得很。

又是前端,上bootstrap吧


能夠理解數據庫必須用主外鍵,否則那幫傢伙一定會亂寫程序。

只要是實體類,必須有主鍵,並且一定要有物理主鍵,不能只依賴於邏輯主鍵。id這東西,找不到其他用途的話就簡單的當個快速查詢定位的工具就行。隨着業務複雜度的增加,你會發現它的表現力越來越強。在大部分依賴於持久化的業務類系統中,可以簡單的定義,有id就代表這東西存在,沒id就代表不存在,順着這條思路往下想,很多業務都會簡化。

只用id做外鍵,不要用神馬身份證號、訂單編號之類的東西。然後你的程序隨便怎麼寫都能寫得下去。


會設計數據庫模型,幾百張表的小意思。

針對真實世界,只作抽象,不作修改,保持整個系統概念上的一致性。然後你會發現,設計的模型會恰好符合數據庫設計的各種準則。這時候這個數據庫結構就能用了。

如果你設計出一張自認爲很有用的關係表,卻起不出合適的名字來;或者數據庫中有一個不是純粹爲了效率問題而設置的冗餘字段,相信我,你終將遇到一個你的模型無法表現的業務需求。


註釋用//只有一行,不用/**多行,因爲程序即註釋。

jdk標準註釋都不用,那javadoc咋辦?

好吧,程序即註釋這東西,幾個水平相當、思路相近的人,通過不定期的結對編程、互相重構代碼,還是可以做到的。如果是大規模的開發,還是建議通過架構層面合理的分層解決。


知道struts模型驅動代替屬性注入,方便太多事了。

又一個語法糖。有了實際需求再用,到底用不用不要爭論起來沒完,遵循這兩點就行了。這個真心不是核心問題。


用過this做參數傳遞,哈好多人都沒用見過。

哈真神奇!這話真有人對我說過。

技術上this就是個指向自身的引用。某些具體的場景確實用起來很有意思,高層面的意義還沒太想清楚,只有一個模模糊糊的印象,大概就是做了一件把自身委託給其他對象的事,封裝了某個參數傳遞的過程,也就是封裝了自身和被委託類的關係。


SE級別的程序員:

研究過struts,hibernate的源代碼,ui裏有顏色互補概念,看起來是要舒服點啊。

學源代碼要跟寫代碼結合起來執行,學到了新的模式之後,多想想有什麼應用場景,但是真的實際使用要慎重。譬如說看到struts2的層層wrapper模式後就用了一次,被噴了好長時間

覺得struts,hibernate,spring,要扔掉一個框架,一定是spring,這個廢啊。

讓我選的話,我扔hibernate。


寫過mvc,知道前端攔截器,中心分發器,後置處理,bean映射。

要知道就算沒有這些概念,代碼層面也一定會實現mvc的全部功能。然後找到沒有這些概念的代價,哪些東西就耦合了,哪些變更就應對不了了等等。最後你的水平就提高了。


會用模型驅動user.save(),代替dao。

少傳一個參數,概念上優雅了一些。模型驅動太考驗建模能力,一定要在一個範圍內把所有問題想清楚再使用。建議把DDD那本書看個兩三遍再說。

不過這東西看上去真的很吸引人。


能用metadata生成一堆亂七八雜的代碼,這下爽多了。

metadata的解釋是“描述數據的數據”,比方說數據庫的表結構定義可能就算是一種metadata。在寫代碼過程中能正確的抽象出元數據之後,眼光會提高一個層次,至於是不是要搞生成代碼的工具,因項目而異。

曾經用過一段時間的freemarker,寫一些輕量級的代碼生成工具還是挺好用的。


研究過Annotation,用Annotation寫過註解,知道Annotation如何繼承,太複雜搞不懂。

拿Annotation實現過一套Model工具,沒有深入瞭解過ejb,可能有點entity bean的思路在裏面把。

前面說過一部分annotation了。這東西的好處就是把元數據跟java代碼放到一起了,於是好找也好改了,壞處也是放在一起所以耦合了。如果代碼量大到一定程度之後,最好把所有主力都集合到一塊兒商量一下,到底是xml好還是annotation好。

在代碼量沒大到一定程度,或者annotation配置的數據僅僅是annotation所在的類自己用的話,可以在開發效率上考慮一下這個問題。jdk提供了語言層面的annotation操作工具,使用簡單,有一部分的編譯期檢查,寫起來比xml要舒服。另外,個人認爲annotation的語法不太適合定義層次太深的結構,在類前面寫上四層annotation再用ide做個formatter,說實話挺愁人的。


BOSS級別的程序員:

仰慕一下。。。。

以上經驗建立在如下基礎上:

我做的項目是大部分是技術要求特別簡單,業務要求中等複雜,需求變更特別頻繁,開發人員平均素質不足,工期不是很緊的類型,所以關注點集中在如何通過分層隔離業務複雜度,以及如何通過語法糖來降低開發複雜度。bug方面,比較關注的是影響數據一致性的bug,只要不影響數據一致性,哪怕系統直接掛了,都不是影響項目的生死因素。

在做技術方案的時候,比較傾向於:

1、通過各種設計模式封裝複雜度,提供儘量簡單,甚至無腦開發的接口

2、忽略一切效率問題,在業務打通之後再想優化的事

3、能在編譯器做的事就不往運行期放,哪怕會影響開發的靈活性

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章