摘要:算法名稱描述優(yōu)點(diǎn)缺點(diǎn)標(biāo)記清除算法暫停除了線程以外的所有線程算法分為標(biāo)記和清除兩個(gè)階段首
1 回顧我的時(shí)間線在本文的開頭,先分享一下自己的春招經(jīng)歷吧:
各位掘友大家好,我是練習(xí)時(shí)長(zhǎng)快一年的Android小蔡雞,喜歡看源碼,逛掘金,寫技術(shù)文章......
好了好,不開玩笑了OWO,今年春招投了許多簡(jiǎn)歷的,但是被撈的只有阿里,頭條和美團(tuán),一路下來挺不容易的.
個(gè)人認(rèn)為在春招中運(yùn)氣>性格>三觀>技術(shù).
1.1 阿里3月底 在阿里的學(xué)長(zhǎng)給了內(nèi)推機(jī)會(huì),但是由于自己之前完全不知道有實(shí)習(xí)生招聘這種曲線進(jìn)大公司的事,所以什么都沒準(zhǔn)備,導(dǎo)致直接裸奔上陣.
3月27日 跟面試官約了晚上的面試時(shí)間之后,面了一個(gè)小時(shí),從Java虛擬機(jī)聊到HashMap,再到ARouter,再聊到Dagger2,再聊到注解處理器,多進(jìn)程等等,但由于時(shí)間久遠(yuǎn),具體到底聊了啥基本忘了,只感覺當(dāng)時(shí)啥都不會(huì)不懂,回答的時(shí)候都是一知半解的.
3月29日 本來沒報(bào)什么希望的,但兩天后,沒想到阿里讓居然我這菜雞給過了(內(nèi)心OS:受寵若驚).跟面試官約了二面的時(shí)間.然后接下來的這幾天,心態(tài)極差,心理負(fù)擔(dān)極重,就是那種不想輸,強(qiáng)烈地想贏的感覺,什么熬夜準(zhǔn)備啊,曠課復(fù)習(xí)啊,反正你做的我都做了.
3月31日 果不其然,當(dāng)天面的時(shí)候我自己都覺得不對(duì)勁,一直都是我自己在說,面試官都沒怎么得問,不到30分鐘就草草收?qǐng)?至此我的阿里之行就結(jié)束了.之后的一個(gè)月基本都在復(fù)習(xí)和調(diào)整心態(tài).
1.2 頭條4月 我其實(shí)給頭條投過兩次簡(jiǎn)歷,第一次是頭條的一個(gè)大佬看到我的文章以后,給了我一個(gè)白金碼(非常感謝),讓我有幸參加了頭條4月初的面試.那時(shí)阿里剛掛,還是啥都沒準(zhǔn)備,所以也是跟阿里一樣二面就掛了,沒什么參考價(jià)值,所以這里說的是我第二次投頭條的經(jīng)歷.
4月底 在牛客網(wǎng)上填寫了簡(jiǎn)歷,然后給頭條投遞了簡(jiǎn)歷,具體時(shí)間記不清了.
5月8日 一面比較順利,主要是Java并發(fā)可見性,原子性,有序性的問題,還問了同步關(guān)鍵字和Lock的優(yōu)劣,MVVM等等,基本上都是照著你的簡(jiǎn)歷上來問的,答案早已提前準(zhǔn)備好,復(fù)讀之.
5月10日 二面,一上來就是一道ACM,看到題目就有思路了,奈何實(shí)在太緊張,不過在面試官的提示下也寫出來了,二面復(fù)讀完Java并發(fā)三大特性后,問了View事件傳遞,事件攔截,事件序列的處理,自定義View,減少過渡渲染和優(yōu)化渲染的N種方法,多進(jìn)程,OOM問題.面試結(jié)束后就是數(shù)天漫長(zhǎng)的等待,期間沒有任何消息告訴我到底過了還是沒過,根我第一次投頭條面試完馬上就能收到結(jié)果比起來,這不像極了頭條.
5月15日 美團(tuán)一面過后打電話給頭條的HR問我二面過了沒,HR告訴我沒過之后直接掛了電話.
5月16日 然后戲劇性的一幕出現(xiàn)了!!!早上10點(diǎn)過了沒多久,頭條的HR打電話過來叫我準(zhǔn)備下一輪面試,時(shí)間安排在下星期一,而且語氣一股沒得商量的感覺(內(nèi)心OS:這是什么意思");
5月20日 我收到了美團(tuán)的offer,自然就沒繼續(xù)去面頭條了.
5月21日 下午HR打電話問我還考不考慮,我感覺頭條對(duì)我不夠感興趣,就拒絕了,雖然真的很感謝當(dāng)時(shí)該我白金碼的那位大佬,但總感覺我并不是頭條要找的人.
1.3 美團(tuán)5月初 之前就一直想投美團(tuán),但一直覺得挺迷的,牛客和實(shí)習(xí)僧這兩個(gè)網(wǎng)站都被頭條刷屏了,為什么TMD中的MD還一點(diǎn)動(dòng)靜都沒有");
5月5日 突然反應(yīng)過來還可以去官網(wǎng)投遞啊,然后去了美團(tuán)招聘的官網(wǎng).當(dāng)時(shí)已經(jīng)非常佛系了,心想今年美團(tuán)肯定不缺人吧,要不然怎么動(dòng)靜這么小");
5月13日 簡(jiǎn)歷居然被撈了");
5月15日 面了40分鐘,差不多也是照著簡(jiǎn)歷來問,還是Java并發(fā)三大特性,還問了Activity的啟動(dòng)流程,再有就是我簡(jiǎn)歷上寫的那些多進(jìn)程,MVVM之類的了.所以大概就是把之前面試的內(nèi)容再?gòu)?fù)讀一次,不過感覺現(xiàn)在復(fù)讀得已經(jīng)比較熟練了,面試完后我問面試官對(duì)我的評(píng)價(jià)如何,面試官貌似很高興,問我簡(jiǎn)歷上面怎么什么都不寫,還告訴我我很OK,進(jìn)的概率還是很大的(內(nèi)心OS:有點(diǎn)受寵若驚");
5月15日下午 老大又給我來了電話,約了下一輪的面試時(shí)間,還順便做了一個(gè)15分鐘的小面試,問了一些技術(shù)問題,基本上是一些開源項(xiàng)目的源碼,期間問到了Glide,我剛好沒看過,嚇得我當(dāng)天晚上趕緊去把Glide的源碼掃了一遍,最后老大還加了我的微信.
5月16日 沒錯(cuò),效率高到甚至沒有隔天,老大面我,面了一個(gè)小時(shí).有一道ACM,直接秒了,然后繼續(xù)復(fù)讀,讓我詳細(xì)講了Handler,Looper,MessageQueue,Message的源碼,還有調(diào)試追蹤內(nèi)存泄漏,還有計(jì)網(wǎng)TCP三次握手,還有操作系統(tǒng)的死鎖,還有AsyncTask底層和在不同API等級(jí)之間的區(qū)別等等,多多少少都答了,不過有一些還是缺頁中斷了(忘了或者不會(huì)QAQ),但是直到最后都沒問Glide(QAQ跳來跳去的,我看了一晚上啊),面完以后老大貌似對(duì)我挺滿意的,當(dāng)場(chǎng)給我過了,然后幫跟我和大老板約了面試.
5月17日 沒錯(cuò),效率高到甚至沒有隔天,大老板面我,聊了大概20到30分鐘,大老版問的都是一些比較開放性的問題,比如我們的美團(tuán)APP啟動(dòng)白屏了讓你列出20種可能,最后我從各方面瞎編亂造了大概10種實(shí)在編不下去了,感覺是想考察我的發(fā)散思維能力,然后問了我為什么想去北京,我就說了我的世界觀想去見識(shí)更大的世界,感覺大老板挺開心的.面試結(jié)束后我然后私下去問老大大老板覺得我怎么樣");
5月20日 跟HR確認(rèn)了offer,至此我的春招結(jié)束.感覺自己性格缺陷挺多的,真的很感謝老大對(duì)我的幫助和包容.
1.4 小結(jié)不要輕易放棄和認(rèn)為春招已經(jīng)結(jié)束了,機(jī)會(huì)其實(shí)還有很多.
說句扎心的話,個(gè)人覺得其實(shí)覺得在面試中運(yùn)氣真的很重要,如果你和我一樣遇到了超nice的領(lǐng)導(dǎo),就會(huì)一路綠燈,要不然的話真的可能會(huì)把你面到自閉.
從我個(gè)人主觀的此次面試經(jīng)歷來說,感覺頭條并沒有外界傳聞中的那么效率高和缺人.從我個(gè)人的這種要強(qiáng)的性格出發(fā),是無法接受這種你告訴我掛了之后又再打電話約下一輪面試的操作的.個(gè)人猜測(cè)應(yīng)該是原本的候選人把頭條給鴿了,然后資格順位繼承到我身上,然后我也鴿了,所以才會(huì)再打電話給我問我考不考慮.但是人是情感動(dòng)物啊,而情感往往是建立在反饋的基礎(chǔ)上的,如果別人給我的反饋太消極了,那么我給別人的表現(xiàn)也肯定不會(huì)積極到哪里去.
2 把自己訓(xùn)練成HashMap和復(fù)讀機(jī)這次春招給我最大的感觸就是,當(dāng)你覺得自己像復(fù)讀機(jī)能把面試題給復(fù)讀出來并且對(duì)面試官所提的問題能像HashMap一樣在常數(shù)時(shí)間內(nèi)找到答案的時(shí)候,你就離成功很近了.
下面是我在準(zhǔn)備面試的時(shí)候收集的一些知識(shí)點(diǎn):
2.1 Java 2.1.1 volatile理解,JMM中主存和工作內(nèi)存到底是啥?和JVM各個(gè)部分怎么個(gè)對(duì)應(yīng)關(guān)系?參考link
2.1.2 序列化Serializable在序列化時(shí)使用了反射,從而導(dǎo)致GC的頻繁調(diào)用,參考link
2.1.3 可見性,原子性,有序性(必考)可見性volatile,一個(gè)線程的修改對(duì)另外一個(gè)線程是馬上可見的,
原子性CAS操作,要么都做要么都不做
有序性synchronized通過進(jìn)入和退出Monitor(觀察器)實(shí)現(xiàn),CPU可能會(huì)亂序執(zhí)行指令,如果在本線程內(nèi)觀察,所有操作都是有序的,如果在一個(gè)線程中觀察另一個(gè)線程,所有操作都是無序的.參考link
2.1.4 Java鎖機(jī)制java鎖機(jī)制其實(shí)是鎖總線,同步關(guān)鍵字和Lock接口的優(yōu)劣.
2.1.5 Java的常量池?不同String賦值方法,引用是否相等?字面值是常量,在字節(jié)碼中使用id索引,equals相等引用不一定相等,Android上String的構(gòu)造函數(shù)會(huì)被虛擬機(jī)攔截,重定向到StringFactory
2.1.6 HashMap的實(shí)現(xiàn)");數(shù)組加鏈表加紅黑樹,默認(rèn)負(fù)載因子0.75,樹化閾值8,這部分比較常考,建議專門準(zhǔn)備.(打個(gè)小廣告OWO,你也可以關(guān)注我的專欄,里面有一篇文章分析了HashMap和ArrayMap)
2.1.7 Java實(shí)現(xiàn)無鎖同步CAS的實(shí)現(xiàn)如AtomicInteger等等
2.1.8 單例模式雙重檢查
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
反序列化安全,反射安全 枚舉級(jí)單例,類加載時(shí)由JVM保證單例,反序列化不會(huì)生成新對(duì)象,另外一種反射安全是在構(gòu)造函數(shù)中對(duì)單例進(jìn)行檢查如果存在則拋出異常.
2.1.9 鎖的條件變量信號(hào)量要與一個(gè)鎖結(jié)合使用,當(dāng)前線程要先獲得這個(gè)鎖,然后等待與這個(gè)鎖相關(guān)聯(lián)的信號(hào)量,此時(shí)該鎖會(huì)被解鎖,其他線程可以搶到這個(gè)鎖,如果其他線程搶到了這個(gè)鎖,那他可以通知這個(gè)信號(hào)量,然后釋放該鎖,如果此時(shí)第一個(gè)線程搶到了該鎖,那么它將從等待處繼續(xù)執(zhí)行(應(yīng)用場(chǎng)景,將異步回調(diào)操作封裝為變?yōu)橥讲僮?避免回調(diào)地獄)
信號(hào)量與鎖相比的應(yīng)用場(chǎng)景不同,鎖是服務(wù)于共享資源的,而信號(hào)量是服務(wù)于多個(gè)線程間的執(zhí)行的邏輯順序的,鎖的效率更高一些.
2.1.10 ThreadLocal原理線程上保存著ThreadLocalMap,每個(gè)ThreadLocal使用弱引用包裝作為Key存入這個(gè)Map里,當(dāng)線程被回收或者沒有其他地方引用ThreadLocal時(shí),ThreadLocal也會(huì)被回收進(jìn)而回收其保存的值
2.1.11 軟引用,弱引用,虛引用軟引用內(nèi)存不夠的時(shí)候會(huì)釋放
弱引用GC時(shí)釋放
虛引用,需要和一個(gè)引用隊(duì)列聯(lián)系在一起使用,引用了跟沒引用一樣,主要是用來跟GC做一些交互.
2.1.12 ClassLoader雙親委派機(jī)制簡(jiǎn)單來說就是先把加載請(qǐng)求轉(zhuǎn)發(fā)到父加載器,父加載器失敗了,再自己試著加載
2.1.13 GC Roots有這些通過System Class Loader或者Boot Class Loader加載的class對(duì)象,通過自定義類加載器加載的class不一定是GC Root:
處于激活狀態(tài)的線程
棧中的對(duì)象
JNI棧中的對(duì)象
JNI中的全局對(duì)象
正在被用于同步的各種鎖對(duì)象
JVM自身持有的對(duì)象,比如系統(tǒng)類加載器等。
2.1.14 GC算法名稱 | 描述 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|---|---|---|
標(biāo)記-清除算法 | 暫停除了GC線程以外的所有線程,算法分為“標(biāo)記”和“清除”兩個(gè)階段,首先從GC Root開始標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成之后統(tǒng)一回收掉所有被標(biāo)記的對(duì)象。 | 標(biāo)記-清除算法的缺點(diǎn)有兩個(gè):首先,效率問題,標(biāo)記和清除效率都不高。其次,標(biāo)記清除之后會(huì)產(chǎn)生大量的不連續(xù)的內(nèi)存碎片,空間碎片太多會(huì)導(dǎo)致當(dāng)程序需要為較大對(duì)象分配內(nèi)存時(shí)無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動(dòng)作 | |
復(fù)制算法 | 將可用內(nèi)存按容量分成大小相等的兩塊,每次只使用其中一塊,當(dāng)這塊內(nèi)存使用完了,就將還存活的對(duì)象復(fù)制到另一塊內(nèi)存上去,然后把使用過的內(nèi)存空間一次清理掉 | 這樣使得每次都是對(duì)其中一塊內(nèi)存進(jìn)行回收,內(nèi)存分配時(shí)不用考慮內(nèi)存碎片等復(fù)雜情況,只需要移動(dòng)堆頂指針,按順序分配內(nèi)存即可,實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效 | 復(fù)制算法的缺點(diǎn)顯而易見,可使用的內(nèi)存降為原來一半 |
標(biāo)記-整理算法 | 標(biāo)記-整理算法在標(biāo)記-清除算法基礎(chǔ)上做了改進(jìn),標(biāo)記階段是相同的,標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成之后不是直接對(duì)可回收對(duì)象進(jìn)行清理,而是讓所有存活的對(duì)象都向一端移動(dòng),在移動(dòng)過程中清理掉可回收的對(duì)象,這個(gè)過程叫做整理。 | 標(biāo)記-整理算法相比標(biāo)記-清除算法的優(yōu)點(diǎn)是內(nèi)存被整理以后不會(huì)產(chǎn)生大量不連續(xù)內(nèi)存碎片問題。復(fù)制算法在對(duì)象存活率高的情況下就要執(zhí)行較多的復(fù)制操作,效率將會(huì)變低,而在對(duì)象存活率高的情況下使用標(biāo)記-整理算法效率會(huì)大大提高 | |
分代收集算法 | 是java的虛擬機(jī)的垃圾回收算法.基于編程中的一個(gè)事實(shí),越新的對(duì)象的生存期越短,根據(jù)內(nèi)存中對(duì)象的存活周期不同,將內(nèi)存劃分為幾塊,java的虛擬機(jī)中一般把內(nèi)存劃分為新生代和年老代,當(dāng)新創(chuàng)建對(duì)象時(shí)一般在新生代中分配內(nèi)存空間,當(dāng)新生代垃圾收集器回收幾次之后仍然存活的對(duì)象會(huì)被移動(dòng)到年老代內(nèi)存中,當(dāng)大對(duì)象在新生代中無法找到足夠的連續(xù)內(nèi)存時(shí)也直接在年老代中創(chuàng)建 |
Android線程模型就是消息循環(huán),Looper關(guān)聯(lián)MessageQueue,不斷嘗試從MessageQueue取出Message來消費(fèi),這個(gè)過程可能會(huì)被它自己阻塞.
而Handler最終都調(diào)用enqueueMessage(Message,when)入隊(duì)的,延遲的實(shí)現(xiàn)時(shí)當(dāng)前是時(shí)間加上延遲時(shí)間給消息指定一個(gè)執(zhí)行的時(shí)間點(diǎn),然后在MessageQueue找到插入位置,此時(shí)會(huì)判斷是否需要喚醒線程來消費(fèi)消息以及更新下次需要暫停的時(shí)間.
Message知道要發(fā)到哪個(gè)Handler是因?yàn)镸essage把Handler保存到了target.
Message內(nèi)部使用鏈表進(jìn)行回收復(fù)用
2.2.2 View事件以及View體系相關(guān)知識(shí)建議看《Android開發(fā)藝術(shù)探索》,這玩意三言兩語講不清楚
2.2.3 Android中使用多線程的方法裸new一個(gè)Thread(失控線程,不推薦)
RxJava的調(diào)度器(io(優(yōu)先級(jí)比低),密集計(jì)算線程(優(yōu)先級(jí)比高,用于執(zhí)行密集計(jì)算任務(wù)),安卓主線程, Looper創(chuàng)建(實(shí)際上內(nèi)部也是創(chuàng)建了Handler))
Java Executor框架的Executors#newCachedThreadPool(),不會(huì)造成資源浪費(fèi),60秒沒有被使用的線程會(huì)被釋放
AsyncTask,內(nèi)部使用FutureTask實(shí)現(xiàn),通過Handler將結(jié)果轉(zhuǎn)發(fā)到主線程,默認(rèn)的Executor是共用的,如果同時(shí)執(zhí)行多個(gè)AsyncTask,就可能需要排隊(duì),但是可以手動(dòng)指定Executor解決這個(gè)問題,直接new匿名內(nèi)部類會(huì)保存外部類的引用,可能會(huì)導(dǎo)致內(nèi)存泄漏
Android線程模型提供的Handler和HandlerThread
使用IntentService
IntentService和Service的區(qū)別——沒什么區(qū)別,其實(shí)就是開了個(gè)HandlerThread,讓它不要在主線程跑耗時(shí)任務(wù)
2.2.4 RecyclerView復(fù)用緩存建議看一下,這個(gè)可能會(huì)被問,不過我運(yùn)氣好沒被問到.
2.2.5 Activity啟動(dòng)流程網(wǎng)上有很多相關(guān)的文章,可以自己結(jié)合源碼去看一下,如果能講個(gè)大概的話也是很加分的.
2.2.6 JNI(除非你自己說你會(huì),否則不是很常考)可避免的內(nèi)存拷貝,直接傳遞對(duì)象,到C層是一個(gè)jobject的指針,可以使用jmethodID和jfiledID訪問方法和字段,無需進(jìn)行內(nèi)存拷貝,使用直接緩沖區(qū)也可以避免內(nèi)存拷貝.
無法避免的內(nèi)存拷貝,基本類型數(shù)組,無法避免拷貝,因?yàn)镴VM不信任C層的任何內(nèi)存操作,特別是字符串操作,因?yàn)镴ava的字符串與C/C++的字符串所使用的數(shù)據(jù)類型是不一樣的C/C++使用char一個(gè)字節(jié)(1字節(jié)=8位)或wchar_t是四字節(jié).而jstring和jchar使用的是UTF-16編碼使用雙字節(jié).(Unicode是兼容ASCII,但不兼容GBK,需要自己轉(zhuǎn)換)
自己創(chuàng)建的局部引用一定要釋放,否則一直持有內(nèi)存泄漏
非局部引用方法返回后就會(huì)失效,除非創(chuàng)建全局引用,jclass是一個(gè)jobject,方法外圍使用時(shí)需要?jiǎng)?chuàng)建全局引用,jmethodID和jfiledID不需要.
JNI是通過Java方法映射到C函數(shù)實(shí)現(xiàn)的,如果使用這種方法,函數(shù)必須以C式接口導(dǎo)出(因?yàn)镃++會(huì)對(duì)名字做修飾處理),當(dāng)然也可以在JNI_OnLoad方法中注冊(cè).
JNIEnv是線程獨(dú)立的,JNI中使用pthread創(chuàng)建的線程沒有JNIEnv,需要AttachCurrentThread來獲取JNIEnv,不用時(shí)要DetachCurrentThread
2.3專業(yè)課 2.3.1 TCP和UDP的根本區(qū)別?數(shù)據(jù)報(bào),流模式,TCP可靠,包序不對(duì)會(huì)要求重傳,UDP不管,甚至不能保證送到
2.3.2 TCP三次握手這個(gè)被問的幾率非常的大,幾乎等于必問,建議專門花時(shí)間去看.
2.3.3 Http和HttpsCA證書,中間機(jī)構(gòu),公鑰加密對(duì)稱秘鑰傳回服務(wù)端,一個(gè)明文一個(gè)加密,SSL層,中間人攻擊,參考link
2.4 ACM對(duì)于ACM,比較常考鏈表的題,不常刷算法的同學(xué)一定不要對(duì)其有抵觸心理.
你可能會(huì)問為什么要ACM");
刷題的話,建議去刷leetcode,題號(hào)在200以內(nèi)的,簡(jiǎn)單和中等難度,不建議刷困難,因?yàn)槊嬖嚨臅r(shí)候基本就不會(huì)出,沒人愿意在那里等你想一個(gè)半個(gè)小時(shí)的.
在面試官面前現(xiàn)場(chǎng)白板編程時(shí),可以先把思路告訴面試官,寫不寫得出來是另外一回事,時(shí)間復(fù)雜度和空間復(fù)雜度是怎么來的一定要搞清楚.在編碼時(shí)也不一定要寫出最佳的時(shí)間和空間的算法,但推薦你寫出代碼量最少,思路最清晰的,這樣面試官看得舒服,你講得也舒服.
下面是我在網(wǎng)上收集或者是在實(shí)際中遇到過的ACM題,基本上在leetcode上也都有類似的.
2.4.1 數(shù)組、鏈表鏈表逆序(頭條幾乎是必考的)
public ListNode reverseList(ListNode head)
{
if (head == null)
{
return null;
}
if (head.next == null)
{
return head;
}
ListNode prev = null;
ListNode current = head;
while (current != null)
{
ListNode next = current.next;
current.next = prev;
prev = current;
current = next;
}
return prev;
}
刪除排序數(shù)組中的重復(fù)項(xiàng)
public int removeDuplicates(int[] nums)
{
int length = nums.length;
if (length == 0 || length == 1)
{
return length;
}
int size = 1;
int pre = nums[0];
for (int i = 1; i < length; )
{
if (nums[i] == pre)
{
i++;
} else
{
pre = nums[size++] = nums[i++];
}
}
return size;
}
數(shù)組中找到重復(fù)元素
n個(gè)長(zhǎng)為n的有序數(shù)組,求最大的n個(gè)數(shù)
用O(1)的時(shí)間復(fù)雜度刪除單鏈表中的某個(gè)節(jié)點(diǎn) 把后一個(gè)元素賦值給待刪除節(jié)點(diǎn),這樣也就相當(dāng)于是刪除了當(dāng)前元素,只有刪除最后一個(gè)元素的時(shí)間為o(N)平均時(shí)間復(fù)雜度仍然為O(1)
public void deleteNode(ListNode node) { ListNode next = node.next; node.val = next.val; node.next = next.next; }
刪除單鏈表的倒數(shù)第N個(gè)元素 兩個(gè)指針,第一個(gè)先走N步第二個(gè)再走,時(shí)間復(fù)雜度為O(N),參考link
public ListNode removeNthFromEnd(ListNode head, int n) {
if (head == null)
{
return null;
}
if (head.next == null)
{
return n == 1 ");do
{
if (size >= n + 1)
{
point = point.next;
}
node = node.next;
size++;
} while (node != null);
if (size == n)
{
return head.next;
}
node = point.next;
point.next = node == null ");return head;
}
從長(zhǎng)序列中找出前K大的數(shù)字
用數(shù)組實(shí)現(xiàn)雙頭棧
public static class Stack
{
public Stack(int cap)
{
if (cap <= 0)
{
throw new IllegalArgumentException();
}
array = new Object[cap];
left = 0;
right = cap - 1;
}
private Object[] array;
private int left;
private int right;
public void push1(T val)
{
int index = left + 1;
if (index < right)
{
array[index] = val;
}
left = index;
}
@SuppressWarnings("unchecked")
public T pop1()
{
if (left > 0)
{
return (T)array[left--];
}
return null;
}
public void push2(T val)
{
int index = right - 1;
if (index > left)
{
array[index] = val;
}
right = index;
}
@SuppressWarnings("unchecked")
public T pop2()
{
if (right < array.length)
{
return (T)array[right++];
}
return null;
}
}
兩個(gè)鏈表求和,返回結(jié)果也用鏈表表示 1 -> 2 -> 3 + 2 -> 3 -> 4 = 3 -> 5 -> 7
public ListNode addTwoNumbers(ListNode node1, ListNode node2)
{
ListNode head = null;
ListNode tail = null;
boolean upAdd = false;
while (!(node1 == null && node2 == null))
{
ListNode midResult = null;
if (node1 != null)
{
midResult = node1;
node1 = node1.next;
}
if (node2 != null)
{
if (midResult == null)
{
midResult = node2;
} else
{
midResult.val += node2.val;
}
node2 = node2.next;
}
if (upAdd)
{
midResult.val += 1;
}
if (midResult.val >= 10)
{
upAdd = true;
midResult.val %= 10;
}
else
{
upAdd = false;
}
if (head == null)
{
head = midResult;
tail = midResult;
} else
{
tail.next = midResult;
tail = midResult;
}
}
if (upAdd)
{
tail.next = new ListNode(1);
}
return head;
}
交換鏈表兩兩節(jié)點(diǎn)
public ListNode swapPairs(ListNode head)
{
if (head == null)
{
return null;
}
if (head.next == null)
{
return head;
}
ListNode current = head;
ListNode after = current.next;
ListNode nextCurrent;
head = after;
do
{
nextCurrent = after.next;
after.next = current;
if (nextCurrent == null)
{
current.next = null;
break;
}
current.next = nextCurrent.next;
after = nextCurrent.next;
if (after == null)
{
current.next = nextCurrent;
break;
}
current = nextCurrent;
} while (true);
return head;
}
找出數(shù)組中和為給定值的兩個(gè)元素,如:[1, 2, 3, 4, 5]中找出和為6的兩個(gè)元素。
public int[] twoSum(int[]mun,int target)
{
Map table = new HashMap<>();
for (int i = 0; i < mun.length; ++i)
{
Integer value = table.get(target - mun[i]);
if (value != null)
{
return new int[]{i, value};
}
table.put(mun[i], i);
}
return null;
}
2.4.2 樹
二叉樹某一層有多少個(gè)節(jié)點(diǎn)
2.4.3 排序雙向鏈表排序(這個(gè)就比較過分了,遇到了就自求多福吧)
public static void quickSort(Node head, Node tail) {
if (head == null || tail == null || head == tail || head.next == tail) {
return;
}
if (head != tail) {
Node mid = getMid(head, tail);
quickSort(head, mid);
quickSort(mid.next, tail);
}
}
public static Node getMid(Node start, Node end) {
int base = start.value;
while (start != end) {
while(start != end && base <= end.value) {
end = end.pre;
}
start.value = end.value;
while(start != end && base >= start.value) {
start = start.next;
}
end.value = start.value;
}
start.value = base;
return start;
}
/**
* 使用如內(nèi)部實(shí)現(xiàn)使用雙向鏈表的LinkedList容器實(shí)現(xiàn)的快排
*/
public static void quickSort(List list) {
if (list == null || list.isEmpty()) {
return;
}
quickSort(list, 0, list.size() - 1);
}
private static void quickSort(List list, int i, int j) {
if (i < j) {
int mid = partition(list, i, j);
partition(list, i, mid);
partition(list,mid + 1, j);
}
}
private static int partition(List list, int i, int j) {
int baseVal = list.get(i);
while (i < j) {
while (i < j && baseVal <= list.get(j)) {
j--;
}
list.set(i, list.get(j));
while (i < j && baseVal >= list.get(i)) {
i++;
}
list.set(j, list.get(i));
}
list.set(i, baseVal);
return i;
}
常見排序,如堆排序,快速,歸并,冒泡等,還得記住他們的時(shí)間復(fù)雜度.
2.5 項(xiàng)目 2.5.1 視頻聊天使用什么協(xié)議?不要答TCP,答RTMP實(shí)時(shí)傳輸協(xié)議,RTMP在Github也有很多開源實(shí)現(xiàn),建議面這方面的同學(xué)可以去了解一下.
2.5.2 你在項(xiàng)目中遇到的一些問題,如何解決,思路是什么");這一塊比較抽象,根據(jù)你自己的項(xiàng)目來,著重講你比較熟悉,有把握的模塊,一般面試官都會(huì)從中抽取一些問題來向你提問.
2.6 提問不要問諸如:
面試官是哪個(gè)組的?
這種問題一點(diǎn)價(jià)值都沒有,因?yàn)槟慵词箚柫艘膊荒軓乃抢铽@得額外的信息,也不能夠影響他對(duì)你的判斷,要問就要問面試官對(duì)你的感受與評(píng)價(jià),還要體現(xiàn)出你想要加入的心情以及你問題的深度.
XXX今年是否真的缺人?招聘策略是什么?
面試官認(rèn)為我存在哪些不足(從性格和技術(shù)兩方面)?
如果面試沒通過能不能告訴我掛掉我的原因,這樣既可以幫助到我也可以幫助到我?guī)У膶W(xué)弟學(xué)妹們,而且在我分享我的面經(jīng)的時(shí)候也能幫助XX招到更好的人.
XXX需要我這樣的同學(xué)嗎"); 3 最后說一些個(gè)人認(rèn)為比較重要的事 3.1 積極準(zhǔn)備、不斷試錯(cuò)
機(jī)會(huì)都是留給有準(zhǔn)備的人的,千萬不要想著不準(zhǔn)備上戰(zhàn)場(chǎng)就能成功.
多看面經(jīng),面經(jīng)就是面試官們的招聘導(dǎo)向,透過閱讀大量的面經(jīng),你能夠感受得到面試官想要找到什么樣的人,并且你可以有針對(duì)性地去準(zhǔn)備.
因?yàn)槲覀冏鳛閷W(xué)生,往往沒有什么實(shí)際的項(xiàng)目經(jīng)驗(yàn),所以操作系統(tǒng),計(jì)算機(jī)網(wǎng)絡(luò),數(shù)據(jù)結(jié)構(gòu)與算法,計(jì)算機(jī)組成原理這四大基礎(chǔ)就是春招考察的重點(diǎn).
《Android開發(fā)藝術(shù)探索》這本書之于Android求職者的重要性,我覺得全世界都應(yīng)該知道了,如果你還沒有看過,建議真的好好看一下吧.
不斷地去面試,如果你這次面試失敗了,那一定要好好總結(jié)其中的原因,一定要想方設(shè)法地從面試官口中套出自己的不足,這樣你下次面試成功的概率就會(huì)增加.
3.2 真正重要并且最容易忽視的一些問題往往有很多同學(xué)明明覺得自己已經(jīng)準(zhǔn)備得很好了已經(jīng)很復(fù)讀了,可最后還是不沒拿到offer,那么你可能需要考慮以下的問題了.
就像我一開始說的,春招是運(yùn)氣>性格>三觀>技術(shù)的,項(xiàng)目與基礎(chǔ)固然很重要,但是想在短短的數(shù)小時(shí)能完全掌握一個(gè)人所有的基本情況實(shí)在是太難了,面試官看到的往往只是你的冰山一角,所以在面試的時(shí)候,你可能還要在意以下的問題:
隨機(jī)應(yīng)變: 準(zhǔn)備一些圓場(chǎng)的話,比如在講原碼時(shí),如果覺得自己講得不完全對(duì),最后就補(bǔ)充一句——可能我說得不完全準(zhǔn)確,但是我覺得看源碼不是背書,而是學(xué)習(xí)他的一種思想并用到自己的代碼中去.
知己知彼: 深入地了解目標(biāo)公司的企業(yè)文化,并準(zhǔn)備一些夸他們的話,最好能夠讓對(duì)方會(huì)心一笑,這樣絕對(duì)加分.
堅(jiān)持到底: 可能會(huì)被問道一些形而上學(xué)的問題,這種問題往往沒有標(biāo)準(zhǔn)答案,求生欲一定要強(qiáng),不會(huì)也要編出來,因?yàn)橥嬖嚬賳柲氵@些問題,其目的并不是看你能不能答對(duì),而是想看看你的發(fā)散思維,看看你能給出多少種的答案,這個(gè)過程中你的嘗試,會(huì)被面試官當(dāng)成你的價(jià)值
三觀要正: 世界觀要開闊,勇于迎接挑戰(zhàn),但不是當(dāng)舔狗,不能沒有底線,除非是你自己提出,否則當(dāng)公司讓你曠課去實(shí)習(xí)的時(shí)候我想你應(yīng)該拒絕,因?yàn)槿绻赢?可能會(huì)影響轉(zhuǎn)正,最后一定是得不償失,理性大于一切.
端正姿態(tài): 我們是去求職的,不是去當(dāng)大爺?shù)?所以姿態(tài)要放低,當(dāng)面試官讓你做選擇的時(shí)候,先觀察這個(gè)問題是否是你能夠決定的,如果不是,就說公司怎么安排我就服從安排,我愿意接受新的挑戰(zhàn)讓自己成長(zhǎng).
儒雅隨和: 面試的時(shí)候語速可慢但一定不能快,要儒雅隨和,不要貪婪地說話,適可而止,即使你知道的東西真的很多.因?yàn)槟銣?zhǔn)備了面試,面試官一樣也準(zhǔn)備了面試你,他也有問題想問你的,如果你一直說,他都沒機(jī)會(huì)問,那他肯定不爽.不要搶別人的話頭,遇事不要輕易下結(jié)論,就算他說得不對(duì)也不能直接沖臉,要委婉一點(diǎn).
別太誠(chéng)實(shí): 當(dāng)然這并不是叫你去說謊,該說不懂的還是得說不懂,不要不懂裝懂.我想說的是不要主動(dòng)暴露自己的缺點(diǎn),因?yàn)榫拖裎抑罢f的,面試官面試你的時(shí)間是非常短的,往往他對(duì)你的了解十分有限,你要盡可能的表現(xiàn)出自己的優(yōu)點(diǎn)而不是缺點(diǎn).
手握籌碼: 當(dāng)我去頭條面試的時(shí)候,我手里握有的籌碼就是我可能有很大的機(jī)會(huì)到某國(guó)企實(shí)習(xí)(校企合作項(xiàng)目),當(dāng)我去美團(tuán)面試的時(shí)候,我的籌碼就是我頭條也到了三面,你的籌碼間接地證明了你的價(jià)值,也能影響面試官對(duì)你的判斷.
3.3 結(jié)語透露一下,本人是雙非二本,自從高考失利以后還以為自己要一直這么平凡下去QAQ,沒想到過了三年終于又給我一個(gè)機(jī)會(huì)讓我重新證明了自己,能有機(jī)會(huì)去到美團(tuán)這樣的大廠工作,真的倍感榮幸.最后的最后還是慣例啦,如果喜歡我的文章別忘了給我點(diǎn)個(gè)贊,拜托了這對(duì)我來說真的很重要.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/6954.html
摘要:面經(jīng)因?yàn)槲彝耆珱]有面試經(jīng)驗(yàn),從來沒有經(jīng)歷過面試,于是想著在去這類大公司面試之前先找成都的小公司練練手,積累點(diǎn)面試經(jīng)驗(yàn)。于是三月份開始就有成都的小公司開始約我面試。 前序 從我高考成績(jī)出來那一刻開始,從我在高考志愿上填上計(jì)算機(jī)科學(xué)與技術(shù)這幾個(gè)當(dāng)時(shí)在心中堪稱神圣的幾個(gè)字開始,我就已經(jīng)把進(jìn)入中國(guó)互聯(lián)網(wǎng)最高殿堂BAT作為我整個(gè)大學(xué)奮斗的目標(biāo),哪怕我就讀的是一所位于內(nèi)陸的雙非一本大學(xué)我也認(rèn)為我能...
摘要:春招結(jié)果五月份了,春招已經(jīng)接近尾聲,因?yàn)榈搅酥芪逋砩蟿偤糜锌眨院?jiǎn)單地記錄一下自己的春招過程。我的春招從二月初一直持續(xù)到四月底,截止今天,已經(jīng)斬獲唯品會(huì)電商前端研發(fā)部大數(shù)據(jù)與威脅分析事業(yè)部京東精銳暑假實(shí)習(xí)生的騰訊的是早上打過來的。 春招結(jié)果 五月份了,春招已經(jīng)接近尾聲,因?yàn)榈搅酥芪逋砩蟿偤糜锌眨院?jiǎn)單地記錄一下自己的春招過程。我的春招從二月初一直持續(xù)到四月底,截止今天,已經(jīng)斬獲唯品...
摘要:具體的時(shí)間線從月中旬,我開始關(guān)注牛客網(wǎng)的秋招內(nèi)推信息。直至十月中下旬結(jié)束秋招。之前也寫過自己在廣州找實(shí)習(xí)的經(jīng)歷,那次把面試的過程都具體貼出來了。我今年就完美錯(cuò)過了春招實(shí)習(xí)經(jīng)歷。 前言 只有光頭才能變強(qiáng) 離上次發(fā)文章已經(jīng)快兩個(gè)月時(shí)間了,最近一直忙著秋招的事。今天是2018年10月22日,對(duì)于互聯(lián)網(wǎng)行業(yè)來說,秋招就基本結(jié)束了。我這邊的流程也走完了(不再筆試/面試了),所以來寫寫我的秋招經(jīng)歷...
摘要:月初,那時(shí)候人還在百度北京實(shí)習(xí),當(dāng)時(shí)參加了騰訊網(wǎng)易的校招內(nèi)推,結(jié)果有點(diǎn)呵呵。月份開始一直到月底,內(nèi)推正式校招,前后三個(gè)月時(shí)間拿到今日頭條融鏈家網(wǎng)的測(cè)試開發(fā)崗位。 引言 本人武漢大學(xué)碩士研究生三年級(jí)在讀,90后。由于2017年6月要畢業(yè),于是乎參加了2016年的秋招。8月初,那時(shí)候人還在百度(北京)實(shí)習(xí),當(dāng)時(shí)參加了騰訊、網(wǎng)易的校招(內(nèi)推),結(jié)果有點(diǎn)呵呵。8月份開始一直到10月底,內(nèi)推+正...
摘要:春招前端實(shí)習(xí)面試記錄從就開始漸漸的進(jìn)行復(fù)習(xí),月末開始面試,到現(xiàn)在四月中旬基本宣告結(jié)束。上海愛樂奇一面盒模型除之外的面向?qū)ο笳Z言繼承因?yàn)槭且曨l面試,只記得這么多,只感覺考察的面很廣,前端后端移動(dòng)端都問了,某方面也有深度。 春招前端實(shí)習(xí)面試記錄(2019.3 ~ 2019.5) 從2019.1就開始漸漸的進(jìn)行復(fù)習(xí),2月末開始面試,到現(xiàn)在四月中旬基本宣告結(jié)束。在3月和4月經(jīng)歷了無數(shù)次失敗,沮...
閱讀 1106·2021-11-23 10:05
閱讀 1784·2021-11-12 10:36
閱讀 1853·2019-08-30 15:56
閱讀 1684·2019-08-29 12:32
閱讀 3043·2019-08-28 18:04
閱讀 3428·2019-08-26 12:17
閱讀 2502·2019-08-26 11:35
閱讀 1240·2019-08-23 15:11