前言
在2016年的校招過(guò)程中面試了很多大公司,做了很多套筆試題,遇到了很多算法面試場(chǎng)景。深知其中的水深火熱,筆試中絕大一部分是算法題,如果連算法基礎(chǔ)題不及格,就會(huì)失去見(jiàn)到面試官的機(jī)會(huì)。當(dāng)然,自己也不能算是精通,只能說(shuō)有一點(diǎn)個(gè)人經(jīng)驗(yàn),趁熱打鐵分享一系列校招算法基礎(chǔ)方面的東西,我會(huì)利用空閑時(shí)間不斷更新這個(gè)系列,直到完成。自己在大學(xué)階段的算法稱不上很好,只把算法與數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)過(guò),刷過(guò)一些小題目,前后Offer共有七八個(gè)吧,都是互聯(lián)網(wǎng)公司,目前入職某個(gè)互聯(lián)網(wǎng)大廠。
面試過(guò)程中也遇到了因?yàn)樗惴ㄌ钜鸬膶擂?,原本很?jiǎn)單的算法題,回答并不好,本系列主要以我的面試為線索,做一個(gè)算法筆試面試總結(jié),本系列從【筆試面試的算法和編程】開(kāi)始。
筆試面試的算法和編程
不說(shuō)雞湯了,直接上代碼,用C語(yǔ)言實(shí)現(xiàn)函數(shù)void *memmove(void *dest, const void *src, size_t n)。memmove函數(shù)的功能是拷貝src所指向內(nèi)存內(nèi)容前n個(gè)字節(jié)到dest所指的地址上。
下面寫一個(gè)錯(cuò)誤的代碼作為反例,也是最容易想到的實(shí)現(xiàn)方法
void *memove(void *dest, const void *src, size_t n)
{
char *p1 = dest;
char *p2 = src;
while (*p2 != \0)
*p1++ = *p2++
return p
}
這個(gè)函數(shù)咋一看比較正確,其實(shí)漏洞百出。
錯(cuò)誤的思路
兩個(gè)指針?lè)謩e指向dest地址、src地址,然后將src地址中值存放到dest地址中,完事。
正確的思路
先不說(shuō)指針的初始化這些小問(wèn)題,問(wèn)題比較大的是內(nèi)存重疊、臨時(shí)變量沒(méi)有釋放、沒(méi)有考慮內(nèi)存越界、指針操作錯(cuò)誤。
要結(jié)合memcpy函數(shù)的優(yōu)缺點(diǎn),它不具有內(nèi)存重疊檢查,而memove具有這個(gè)檢查特性,這也是面試經(jīng)??疾斓牡胤?,對(duì)于內(nèi)存邊界的敏感性。
正確的代碼
void *memmove(void *dest, const void *source, size_t count)
{
assert((NULL != dest) && (NULL != source));
char *tmp_source, *tmp_dest;
tmp_source = (char *)source;//注意,void*類型不能直接操作,需要進(jìn)行轉(zhuǎn)換。
tmp_dest = (char *)dest;
if((dest <source) || (source + count) <dest))
{// 如果沒(méi)有重疊區(qū)域
while(count--)
*tmp_dest++ = *tmp_source++;
}
else
{ //如果有重疊(反向拷貝)
tmp_source += count - 1;
tmp_dest += count - 1;
while(count--)
*--tmp_dest = *--tmp;
}
return dest;
}
在這份正確的代碼中就有考慮到內(nèi)存重疊問(wèn)題,做了很好的判斷,并且對(duì)指針操作的規(guī)范性做了很好的處理,比如void 類型不能直接被操作,需要進(jìn)行char轉(zhuǎn)換,還有assert斷言進(jìn)行地址是否有效的判斷。
總結(jié)
從這個(gè)簡(jiǎn)單的算法小題就分析出面試官需要什么樣子的答案,你說(shuō)第一個(gè),部分正確,可能你的面試就被減分一半,如果你能用assert考慮到空指針的情況,就對(duì)了一部分。加入還能考慮到內(nèi)存重疊問(wèn)題,那就更好了。如果你還能針對(duì)內(nèi)存重疊有各種算法的優(yōu)劣比較,和面試官討論下,就能進(jìn)BAT,因此,學(xué)會(huì)寫算法,面試算法是一個(gè)技術(shù)活。
下面是算法面試的干貨
“算法”與工作
以前自己也不重視算法,對(duì)ACM也是漠不關(guān)心,覺(jué)得公司的項(xiàng)目和算法沒(méi)有任何關(guān)系,其實(shí)錯(cuò)了,算法是一種能力的體現(xiàn),算法優(yōu)秀的話在處理很多細(xì)節(jié)問(wèn)題,更加有效率,也是求職的必經(jīng)之路
怎么進(jìn)入大公司
作為親身經(jīng)歷,算法肯定是優(yōu)先考慮的,好的算法會(huì)帶來(lái)業(yè)務(wù)的效率提升,大公司很多業(yè)務(wù)也需要優(yōu)秀的算法去設(shè)計(jì)實(shí)現(xiàn)
基礎(chǔ)差,如何提高刷題速度
首先弄清楚思路,白紙書寫,然后調(diào)試。算法歸類和總結(jié),算法沒(méi)必要很高難度,圖論,動(dòng)態(tài)規(guī)劃可以放一下
如何轉(zhuǎn)行找IT工作
首先簡(jiǎn)歷關(guān),多涉及IT方面的技能,組織和活動(dòng)能力,在某一方面有程序員的實(shí)力,找入手的崗位,不要眼高手低,如果之前是數(shù)據(jù)分析,就轉(zhuǎn)行數(shù)據(jù)庫(kù)方面的,如果之前做過(guò)美工,就轉(zhuǎn)行前端入門崗位,對(duì)服務(wù)器熟悉,就去做各種flask,django,webpy,ngix。充實(shí)簡(jiǎn)歷,盡力描述自己的技能,自己帶一些項(xiàng)目,算法基礎(chǔ)不錯(cuò),超過(guò)面試官的預(yù)期
面試過(guò)程中的交流溝通
換位思考,多交流自己的想法,不要茫然下筆,解釋想法,補(bǔ)充想法
面試過(guò)程遇到BUG
通過(guò)testcase,定位BUG,理清思路,動(dòng)手修改。
解決BUG的方式,先問(wèn)Google,再問(wèn)人,一定要強(qiáng)調(diào)debug能力
推薦算法書籍
《The Algorithm Design Manual 》
《Cracking The Coding Interview (CC150題)》
《劍指offer》
《進(jìn)軍硅谷》
在線算法資源
LeetCode OJ
我的算法之路(書籍和成長(zhǎng)經(jīng)歷)