前言
面試別人,對(duì)我來(lái)說是一件新奇事亥鸠,以前都是別人面試我神妹。
我清楚地知道鸵荠,我在的地域與公司蛹找,難以吸引到中國(guó)的一流軟件人才庸疾。所以彼硫,我特地調(diào)低了期望拧篮,很少問什么深入的技術(shù)問題串绩,只問一些廣泛的礁凡、基礎(chǔ)的顷牌。我只要最終給Leader一句“這個(gè)人技術(shù)還行/很好/非常好”窟蓝,就行了状共。至于其它能力峡继、綜合水平碾牌,由別人把關(guān)小染。為此,在挑選唯一的一道筆試題時(shí)资盅,我特別地上心每庆。
首先缤灵,我不敢用網(wǎng)上那些廣為流傳的腮出,比如Leetcode芝薇、《程序員面試寶典》里的題——這些都太難了馋劈!正兒八經(jīng)做,其實(shí)很少有人能在1小時(shí)內(nèi)完美做出來(lái)娶吞,除非之前遇到過寝志。我本人也并非什么思維敏捷的牛人材部,不然也不會(huì)混得這么慘。正所謂己所不欲浸颓,勿施于人产上,我也不希望以后別人考我特別麻煩的算法題仪媒,所以自創(chuàng)了一道特別簡(jiǎn)單的算吩。
其次偎巢,對(duì)(Android平臺(tái)的)Java程序員來(lái)說压昼,大多數(shù)情況下不需要寫什么復(fù)雜的算法窍霞。相反官撼,Java層主要做的是界面控制傲绣、業(yè)務(wù)邏輯秃诵、數(shù)據(jù)流之類的菠净,更提倡代碼的簡(jiǎn)單和可讀牵咙,盡量用既有的公共類庫(kù)洁桌,不惜損失一些運(yùn)行效率另凌。拿一道復(fù)雜的算法題吠谢,考一個(gè)Java程序員工坊,多少有點(diǎn)刁難人栅组。
最后,還是那個(gè)薪資待遇和人才梯度問題醒叁。沒有Google的工資把沼,就別考Google的題饮睬;沒有Google的向心力捆愁,就別期待有Google級(jí)別的人才來(lái)面試昼丑。
亮題
以下有一個(gè)static method,類外會(huì)調(diào)用它咖城,一個(gè)個(gè)地插入一些元素進(jìn)入一個(gè)List∥沾。可以改變這個(gè)List內(nèi)容的弓候,只有這一個(gè)method菇存,要求任何時(shí)候這個(gè)List都是有序的亥至。
比如贱迟,依次插入3茶敏、2惊搏、1恬惯、2酪耳,我希望List的順序是1碗暗、2讹堤、2洲守、3梗醇。
class Solution {
private static List<Integer> sSorted = new LinkedList<>();
public static void addElement(int e) {
// TODO: Insert e to sSorted and make sure sSorted is always sorted.
}
}
我會(huì)給出15分鐘的時(shí)間温鸽,而其實(shí)往往會(huì)再多給10分鐘手负。
(有興趣蝠猬,你可以停在這試試榆芦。相信在看文章這種輕松的環(huán)境下喘鸟,理清這道題的思路也就10~30秒什黑。)
(為什么下限是10秒呢凯力?唉……一不小心暴露了我智商的峰值。我實(shí)際問過一些同事圣絮,他們通常在理解的同時(shí)扮匠,就立刻給出了正確的思路棒搜,過程不足5秒力麸,其中甚至包括一個(gè)硬件工程師闺鲸,和一個(gè)只負(fù)責(zé)溝通和文檔的妹子摸恍。)
提示
在過程中,我會(huì)逐步給出一些提示媚媒,從接口到思路欣范,都會(huì)主動(dòng)提供恼琼,其它也基本有問必答晴竞。
如果單純考算法噩死,C語(yǔ)言才是最合適的已维,因?yàn)樗鼪]有什么高級(jí)的工具類,什么復(fù)雜點(diǎn)的都得自己寫。而Java,則有一些“基礎(chǔ)”類庫(kù)是難以記憶的哥纫。比如前面出現(xiàn)的java.util.List
蛀骇,就沒有多少人能在紙上寫出它的常用接口。
我并不想考察什么死記硬背雕欺,在這個(gè)時(shí)代,斷網(wǎng)后本來(lái)就沒幾個(gè)程序員能正常編程伞矩。所以我會(huì)主動(dòng)提供一份List
的不完全接口列表苛让。
public interface List<E> extends Collection<E> {
public void add(int location, E object);
public void add(E object);
public void clear();
public boolean contains(Object object);
public boolean equals(Object object);
public E get(int location);
public int indexOf(Object object);
public boolean isEmpty();
public E remove(int location);
public E set(int location, E object);
public int size();
}
我沒有給出完全的接口,因?yàn)榻o多了無(wú)疑是誤導(dǎo)人仿畸。真正能用上的接口其實(shí)也就3個(gè),但我也總不能只給3個(gè)千埃,提示得太明顯,也限制了對(duì)方的思路忆植。所以镰禾,給出了可能用得上的這幾個(gè)皿曲。我也沒給出注釋唱逢,因?yàn)橛新暶骶鸵呀?jīng)夠了吴侦。而且如果對(duì)方問起,我也會(huì)給出解釋坞古。
一開始我想备韧,考一個(gè)排序算了痪枫。但是轉(zhuǎn)念一想,這也太不負(fù)責(zé)任了徐勃。對(duì)面要是背一道冒泡排序的解法上來(lái)臀脏,達(dá)不到考察技術(shù)水平的目的窃植,Boss也不會(huì)認(rèn)可延塑。本著“放水不能太明顯”的原則,我想考插入排序,并且把題目弄得沒多少人見過。
排序是一類基本算法诗良,合格的程序員至少會(huì)一種壹罚。大多數(shù)人都只會(huì)入門級(jí)的冒泡排序虱岂,而我更喜歡插入排序试溯,原因……你會(huì)明白的摹闽。
插入排序,其實(shí)就是把數(shù)組或列表在邏輯上分成兩部分拍谐,一部分是待排序的晕翠,一部分是有序的樊卓。一開始,有序的部分只有一個(gè)元素(或者一個(gè)都沒有),然后從待排序的部分里一個(gè)個(gè)抽出來(lái)毕箍,插入到有序的部分。等元素都插入到了有序的部分,排序過程也就完成了胰耗。
你看旱幼,也就抽插N次的事忙灼。而我這道題,就是只考插入排序算法的一半泣特,會(huì)插就行颗搂。
在面試過程中比驻,我甚至常常親自解釋插入排序是怎么回事——放水到這個(gè)份上堤撵,我都不忍心再退步了礁哄。
真正的考察點(diǎn)
這是一份Android平臺(tái)的開發(fā)工作烁竭,Boss要求的是能干活、干好活幔戏。我給出的建議要求是:
- 熟悉Java想暗。
- 有良好的溝通、表達(dá)能力。
- 學(xué)習(xí)能力強(qiáng),喜歡不斷拓展計(jì)算機(jī)領(lǐng)域的知識(shí)义图。
- 有良好的編碼習(xí)慣,愿意為代碼的簡(jiǎn)潔蒸痹、優(yōu)雅而反復(fù)修改鳖孤。
我建議Boss放棄學(xué)歷和工作年限的要求腿准,技術(shù)崗位就應(yīng)該只考察技術(shù)(和其它基本能力),不應(yīng)該考察技術(shù)的間接證明尽狠。
Java是Android的基本功(我們不玩Kotlin、Scala悍及、React Native等新花樣)闽瓢,這門語(yǔ)言如果不扎實(shí),那至少得帶半年心赶。
我沒有在Android崗明確地要求考察Android扣讼,是因?yàn)锳ndroid的那些東西相對(duì)來(lái)說容易學(xué)習(xí)。即便是毫無(wú)經(jīng)驗(yàn)的新手缨叫,要搞清楚什么“四大組件”“五大布局”椭符,也就一兩天的事。而如果Java不夠扎實(shí)耻姥,各種肉眼可見的大小bug就會(huì)層出不窮销钝,知識(shí)盲點(diǎn)一兩年都補(bǔ)不完。
溝通是職場(chǎng)基本功琐簇。如果話都說不清蒸健,那么會(huì)顯著降低團(tuán)隊(duì)的溝通效率。而且婉商,我個(gè)人認(rèn)為似忧,話說不清的人,代碼一定寫不好丈秩。語(yǔ)言條理清晰盯捌,邏輯層次分明,體現(xiàn)到代碼上蘑秽,就是簡(jiǎn)潔饺著、明朗。
學(xué)習(xí)能力肠牲、求知欲瓶籽,是作為一個(gè)程序員的基本素養(yǎng)。因?yàn)楣〔模蟛糠秩说墓ぷ鳎愃朴谠谝欢寻粹o中汤求,找到合適的那個(gè)按下去俏险;而程序員的工作,往往是閉著眼睛這么干扬绪。開發(fā)工程師通常是在一堆未知(沒讀過的代碼竖独、不知道的接口)中,把一小部分變成已知(讀懂了的代碼或接口)挤牛,進(jìn)行一些增刪改莹痢,最后達(dá)成外界(產(chǎn)品經(jīng)理、設(shè)計(jì)師、測(cè)試工程師)賦予的業(yè)務(wù)目標(biāo)竞膳。
一些職業(yè)賣口水航瞭,一些職業(yè)賣口才。一些職業(yè)賣青春坦辟,一些職業(yè)賣肉體(咳咳刊侯,我說的是空姐和搬磚,想歪的去面壁)锉走。一些職業(yè)賣知識(shí)滨彻,一些職業(yè)賣能力。
程序員挪蹭,或者說軟件開發(fā)工程師亭饵,賣的是學(xué)習(xí)能力(其實(shí)也包括青春和肉體),快速學(xué)會(huì)各種知識(shí)梁厉,找到那些藏在屏幕外的按鈕辜羊,并且正確的按下去。
比如懂算,像Bash這類Command line工具只冻,就是自己敲命令出來(lái)執(zhí)行,而不是去界面上找功能對(duì)應(yīng)的按鈕计技;而程序設(shè)計(jì)喜德、實(shí)現(xiàn),就是去發(fā)現(xiàn)垮媒、或者創(chuàng)造一種解決問題的辦法舍悯,然后用代碼表達(dá)出來(lái)——你看,都是在干一些反UI睡雇、UX設(shè)計(jì)的事萌衬。唯有不斷地學(xué)習(xí),才能提高效率它抱,把自己從加班中解脫出來(lái)秕豫,把項(xiàng)目從bug中拯救出來(lái)。
所以观蓄,厭學(xué)的人當(dāng)不了好程序員混移,也干不長(zhǎng)。
編碼習(xí)慣侮穿,相對(duì)次之歌径。部分觀點(diǎn)認(rèn)為,這東西伴隨一生亲茅,如果一開始沒有好習(xí)慣回铛,這輩子都沒辦法改了狗准。Boss就是這么認(rèn)為的,我倒是不這么認(rèn)為茵肃。我相信編碼習(xí)慣的可塑性是很高的——你不按規(guī)范寫腔长,我不給你merge,改不改免姿?
但是饼酿,編碼習(xí)慣作為程序員的軟技能,還是可以一定程度上看出其技術(shù)素養(yǎng)胚膊、代碼質(zhì)量的故俐。至于優(yōu)雅什么的,我其實(shí)沒有真的敢這么期待紊婉。
所以药版,我這道題其實(shí)是考察這四點(diǎn)。
- 能寫出來(lái)喻犁,并且無(wú)明顯問題槽片,代表Java基本功扎實(shí)。
- 理解我對(duì)題目的描述肢础,和我確認(rèn)清楚題目的細(xì)節(jié)还栓,這是看溝通能力。
-
List
接口不知道传轰,我給你笆:小;插入排序不會(huì)慨蛙,我教你傲闪摹;其它還有什么不會(huì)期贫,你問啊——這是在考察學(xué)習(xí)能力跟匆。 - 代碼的字里行間,可以明顯看出編碼習(xí)慣通砍。
面試結(jié)果
總體來(lái)說玛臂,我很傷心。
第一位就讓我很傷心封孙,當(dāng)我看了他前兩行代碼垢揩,就不忍心接著往下看:
private static List<Integer> sSorted = new LinkedList<>();
public static void addElement(int e) {
if (null == sorted) {
sorted.add(e);
}
// I couldn't read more!
第一行就編譯不過。如果他對(duì)Java的一些命名規(guī)范有一定的了解敛瓷,就絕不會(huì)把sSorted
寫成sorted
。(當(dāng)然斑匪,sSorted
也許并不是合適的命名方式呐籽,因?yàn)閟和m這類前綴有些冗余锋勺。我通常遵守Android源碼的通用規(guī)范,它是有這類前綴的狡蝶。)
第二行必然拋出NullPointerException庶橱,而不知道是該慶幸還是悲傷的是,它永遠(yuǎn)執(zhí)行不到贪惹。根據(jù)我已經(jīng)給出的一個(gè)接口addElement
苏章,和可以猜到或者問出來(lái)的讀取接口,都是不會(huì)把sSorted
變成null
的奏瞬。這體現(xiàn)了溝通枫绅、理解能力的一點(diǎn)問題。
此外硼端,即使sSorted
因?yàn)槭裁碽ug而變成null
并淋,這里也不應(yīng)該做處理,而是任其拋出NullPointerException珍昨,或者轉(zhuǎn)義一下县耽,主動(dòng)拋出IllegalStateException。否則镣典,此處將變成一個(gè)不會(huì)crash的隱藏bug兔毙。不能用正常處理,代替異常處理兄春;當(dāng)然澎剥,也不能用異常處理,代替流程控制神郊。
另外肴裙,更令我失望的是,有一位是這么寫的:
for (int i = 0; i < sSorted.size(); i++) {
if (e == sSorted.get(i)) {
sSorted.add(i, e);
}
}
我問他涌乳,如果這個(gè)元素不在這個(gè)List里存在怎么辦蜻懦?如果這個(gè)List是空的怎么辦?他頓時(shí)一囧夕晓,我也一起囧宛乃,心想自己是不是太壞了。
還有一位蒸辆,仿佛聽見了我這幾個(gè)問題征炼,他竟然一一作答:
if (sSorted.size == 0) {
sSorted.add(e);
return;
}
if (e >= sSorted.get(sSorted.size - 1)) {
sSorted.add(e);
return;
}
if (e <= sSorted.get(0)) {
sSorted.add(0, e);
return;
}
if (sSorted.contains(e)) {
sSorted.add(sSorted.indexOf(e), e);
return;
}
// more...
他想干什么呢?也許是優(yōu)化性能吧躬贡,只能這么幫腔了谆奥。另外,他對(duì)size
的理解拂玻,和數(shù)組的length
相同酸些。
這位算是經(jīng)驗(yàn)比較豐富(30歲)宰译,對(duì)Java的理解比較深入的了。他說排序不需要手寫魄懂,Java里有現(xiàn)成的接口沿侈。我說,是這樣沒錯(cuò)市栗,但接口我沒給出缀拭,如果你記得,那就寫出來(lái)吧填帽。
于是他在剛才那一大段“優(yōu)化”的后面蛛淋,這么寫了:
sSorted.add(e);
sSorted.sort(new Comp...able() {
public boolean ?(left, right) {
return right >= left;
}
});
思路上,插入后再排序盲赊,我先不吐槽铣鹏。我明明說了“記得”再寫,這Comparable
及其接口int compareTo(T another)
如果記不清哀蘑,我就當(dāng)看lambda表達(dá)式了诚卸。可是绘迁,他這個(gè)?
分明是Comparator
的int compare(T lhs, T rhs)
接口呀合溺!
不過,其實(shí)這些我都可以捏著鼻子認(rèn)了缀台,因?yàn)槲乙彩謱懖怀鰜?lái)棠赛。但List
是沒有sort
方法的呀!
Arrays
和Collections
才有各自的sort
方法膛腐,它倆算是銀彈型工具類睛约,而Array
和Collection
是沒有的。這個(gè)細(xì)節(jié),誰(shuí)用誰(shuí)知道,知道了就絕不會(huì)記錯(cuò)葱峡,盡管就差一個(gè)s
。
還有一位怔揩,他先插入、再冒泡排序脯丝,是這么寫的:
sSorted.add(e);
for (int i = 0, sSorted.size(i) > sSorted.get(e), i++) {
temp = sSorted.get(e);
sSorted.get(e) = sSorted.size(i);
sSorted.size(i) = temp;
}
- 你沒看錯(cuò)商膊,
for()
里面是,
分隔的。 - 你沒看錯(cuò)宠进,
temp
是從石頭縫里蹦出來(lái)的晕拆。 - 你沒看錯(cuò),
List.get(e)
是可以對(duì)其賦值的材蹬。 - 你沒看錯(cuò)实幕,
List.size(i)
是可以傳參數(shù)進(jìn)去的阱高。
還有兩位,直接交白卷放棄了茬缩。
其中一位還比較認(rèn)真,思考了一會(huì)兒吼旧,說“我不想浪費(fèi)時(shí)間”凰锡。
我沒亂用詞,他確實(shí)“比較認(rèn)真”圈暗。另一位在我遞過去后掂为,直接看兩眼就遞回來(lái),“排序我不會(huì)”员串,然后看手機(jī)去了勇哗。
o(╯□╰)o
參考答案
我自己在紙上寫的時(shí)候,花了大概5分鐘去思考細(xì)節(jié)寸齐,再花5分鐘寫出來(lái)欲诺。(唉……一不小心,又暴露了自己奇慢無(wú)比的思維渺鹦,以及奇慢無(wú)比的寫字速度扰法。)這比我此前預(yù)計(jì)的時(shí)間多了好幾倍!
不過毅厚,以我給的15~25分鐘塞颁,應(yīng)該不算太難為人……吧?
class Solution {
private static List<Integer> sSorted = new LinkedList<>();
public static void addElement(int e) {
int i;
for (i = 0; i < sSorted.size(); ++i) {
if (e <= sSorted.get(i)) {
break;
}
}
sSorted.add(i, e);
}
}
這是我自己在紙上寫的答案吸耿。
(如果有興趣祠锣,可以停在此處,考慮下這是否是最優(yōu)算法咽安。)
@Override
public E get(int location) {
if (location >= 0 && location < size) {
Link<E> link = voidLink;
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
return link.data;
}
throw new IndexOutOfBoundsException();
}
這是java.util.LinkedList
在Android(API 23)上的實(shí)現(xiàn)伴网,而反編譯Oracle JDK 1.8的實(shí)現(xiàn)也大同小異。
也就是說板乙,我寫的答案雖然看似簡(jiǎn)潔是偷,但其最壞時(shí)間復(fù)雜度與先插入再排序也沒太大區(qū)別,都是O(n2)募逞。
終日打燕蛋铆,反而被燕啄了眼!(暴露了真實(shí)水平放接。)
我后來(lái)又寫了一個(gè)參考答案刺啦,算是勉強(qiáng)在臉上摸了些防曬霜。
(大家有興趣可以想想為什么這是一個(gè)改進(jìn)纠脾。當(dāng)然玛瘸,一定還有更好的方案蜕青。)
class Solution {
private static List<Integer> sSorted = new LinkedList<>();
public static void addElement(int e) {
int i = 0;
for (int j : sSorted) {
if (e <= j) {
break;
}
++i;
}
sSorted.add(i, e);
}
}
(我沒有在提示列表中給出迭代器,結(jié)果自己也被晃過去了糊渊。)
隱藏的殺手锏
面試官在出題考察應(yīng)聘者時(shí)右核,應(yīng)聘者也在通過這道題考察這家公司。
為了避免讓人覺得這家公司考題太簡(jiǎn)單渺绒、工作內(nèi)容太無(wú)趣贺喝、里面的員工(我)水平太低,我還準(zhǔn)備了一些后續(xù)問題宗兼,由淺入深躏鱼,作為殺手锏。
- 為什么
LinkedList
可以賦值給List
殷绍?
考察多態(tài)(polymorphism)染苛。 - 為什么
List<Integer>
要寫<>
內(nèi)的內(nèi)容,而LinkedList<>()
可以不寫主到?
考察泛型(generic)茶行。 - 為什么
List
里面是Integer,但放進(jìn)去和拿出來(lái)的都是int镰烧?
(此處有坑拢军,其實(shí)拿出來(lái)的還是Integer。)
考察基本數(shù)據(jù)類型的自動(dòng)裝箱怔鳖、拆箱(auto boxing/unboxing)茉唉。 - 如何在外面有多線程調(diào)用時(shí),保證這個(gè)唯一的
List
的正確性结执?
考察synchronized
和volatile
度陆。 - 如何在多線程狀態(tài)下的每一個(gè)線程,各保持一個(gè)獨(dú)立的
List
献幔?
考察ThreadLocal
懂傀。
(當(dāng)然,還有一些和Android相關(guān)的問題蜡感。)
我真心是沒想考算法蹬蚁,所以連算法復(fù)雜度的評(píng)估都沒打算問。
實(shí)際情況是郑兴,我往往沒有機(jī)會(huì)問這些問題犀斋,因?yàn)闆]幾個(gè)人寫出來(lái)。
吐槽與建議
首先情连,噴一下大學(xué)擴(kuò)招……算了叽粹,不扯這么遠(yuǎn)了。
那兩位放棄做題的,一個(gè)是計(jì)算機(jī)學(xué)院的虫几,一個(gè)是軟件工程學(xué)院的锤灿。排序?qū)懖怀鰜?lái),竟然也是能畢業(yè)的辆脸!
有兩位是某App的開發(fā)者但校。我把他們的App下載下來(lái),發(fā)現(xiàn)了一堆bug后啡氢,本來(lái)想忍忍始腾、就當(dāng)沒看見、碼農(nóng)何苦為難碼農(nóng)空执,然后手機(jī)發(fā)熱、卡頓穗椅、滅屏后幾乎點(diǎn)亮不了(內(nèi)存泄露吃光了RAM辨绊,導(dǎo)致系統(tǒng)進(jìn)程沒有內(nèi)存可用)。過了一陣最終好了匹表,我查看耗電排行门坷,運(yùn)行10分鐘就高居榜首,耗了17%的電——我嚇得立刻卸載了袍镀。一個(gè)第三方App能把系統(tǒng)給卡成這樣默蚌,一般人還真做不到。
還有兩位是“相關(guān)專業(yè)”的苇羡,非計(jì)算機(jī)绸吸、軟件工程專業(yè),反而表現(xiàn)最佳设江,雖然還是沒寫出來(lái)锦茁。
他們無(wú)一例外,都是在大學(xué)以外叉存,又參加過某些Java码俩、Android培訓(xùn)的。這些培訓(xùn)班的水平歼捏,可見一斑稿存。問題倒不一定是培訓(xùn)班的教學(xué)質(zhì)量,而是這種大規(guī)模提供人才轉(zhuǎn)型服務(wù)的形式本身——這個(gè)世界上瞳秽,本來(lái)就不是誰(shuí)瓣履,都能當(dāng)一個(gè)好碼農(nóng),哪怕工作要求只是復(fù)制粘貼寂诱。
現(xiàn)在拂苹,很多碼農(nóng)都戲稱自己是在“搬磚”、復(fù)制粘貼,但實(shí)際上程序員的工作不可能僅止于此瓢棒。使用別人寫好的基本算法浴韭,參考別人的實(shí)現(xiàn)代碼,只是為了集中精力去解決抽象層次更高的業(yè)務(wù)問題脯宿。
“我們不寫代碼念颈,我們只做代碼的搬運(yùn)工。”——萬(wàn)萬(wàn)不可把這句話當(dāng)做信條连霉。
還有很多人榴芳,在沒有Demo的情況下,無(wú)論給多么詳細(xì)的API或其它資料跺撼,仍然無(wú)法寫代碼窟感。他們只能在既有的基礎(chǔ)上,修修補(bǔ)補(bǔ)歉井,無(wú)法憑空創(chuàng)作柿祈。
我推薦三本Java的基礎(chǔ)書:
- 《Java編程思想》(Think in Java)
這本是最合適的Java語(yǔ)言入門書。其它很多語(yǔ)法書都是從C/C++的角度來(lái)講Java的變化哩至,或者從C++的思路來(lái)討論Java怎么用躏嚎,而這本書的英文名則直接告訴你,請(qǐng)用Java來(lái)思考菩貌、解決問題卢佣。 - 《Effective Java》
Java中有很多坑,Java中也有很多糖箭阶。如果沒有看過這本書虚茶,那么不知不覺就會(huì)犯很多大忌。 - 《代碼整潔之道》(Clean Code)
我是在獨(dú)立寫一個(gè)小項(xiàng)目的時(shí)候開始看的仇参∠蔽#看到一半時(shí)項(xiàng)目也寫到一半,頓時(shí)連代碼都不會(huì)寫了冈敛!每天都在寫自己看不下去的代碼待笑,而不知道怎么寫能看得過眼的。加速看完后抓谴,重新開始會(huì)寫代碼暮蹂。最終,項(xiàng)目后半部分的代碼癌压,和前半部分完全不同仰泻,不像一個(gè)人寫的,我后來(lái)又重構(gòu)了一遍滩届。
(為什么我不多推薦點(diǎn)書呢集侯?一來(lái),是我本人也沒看過多少,囧棠枉;二來(lái)浓体,三本是極限,根據(jù)我的經(jīng)驗(yàn)辈讶,推薦三本可以讓人看一本命浴,推薦三本以上,受眾一本也不會(huì)看贱除。)
我有一個(gè)朋友生闲,也是一個(gè)前同事,好學(xué)如好色月幌。他周末都在找一個(gè)大學(xué)教室看書碍讯,甚至有時(shí)請(qǐng)年假去教室看書。一本《Java編程思想》扯躺,逐行精讀三遍以上冲茸。工作經(jīng)驗(yàn)不足兩年,跳槽三次缅帘,現(xiàn)在在一家百億級(jí)上市公司,年薪三十萬(wàn)难衰,統(tǒng)率十人钦无。
究其原因,無(wú)非基礎(chǔ)知識(shí)扎實(shí)盖袭,口水噴死面試官爾失暂。
后記
我作為一個(gè)面試別人的初哥,一心只想著自己喜歡的抽插……呃不鳄虱,插入排序算法弟塞,給別人造成了不必要的麻煩,只能說抱歉了拙已。
和我一起面試的决记,還有一個(gè)負(fù)責(zé)文檔和規(guī)范的妹子(前面提到過的那個(gè))。她也是有一票否決權(quán)的倍踪,而且用得比我更頻繁系宫!
我最多只給交白卷的,和那個(gè)耗電超恐怖的App建车,這幾個(gè)人直接否決扩借。而這個(gè)妹子,考察對(duì)方的其它綜合能力缤至。
在實(shí)際工作中潮罪,她是需求的接口人,我們需要和她溝通,實(shí)現(xiàn)各方對(duì)我們團(tuán)隊(duì)的需求嫉到。所以沃暗,只要她說一句“我和這個(gè)人難以溝通”,那么Boss基本上就直接拒絕了屯碴。
下次我還是換一道更簡(jiǎn)單的吧描睦,碼農(nóng)何苦為難碼農(nóng)。