春招:我竟然三天就拿到了offer?

1 回顧個人時間線

在本文的開頭,先分享一下本身的春招經歷吧:html

各位掘友你們好,我是練習時長快一年的Android小蔡雞,喜歡看源碼,逛掘金,寫技術文章......java

好了好,不開玩笑了OWO,本人大三,今年春招投了許多簡歷的,都是實習崗,可是被撈的只有阿里,頭條和美團,一路下來挺不容易的.node

我的認爲在春招中運氣>性格>三觀>技術.面試

1.1 阿里

  • 3月底 在阿里的學長給了內推機會,可是因爲本身以前徹底不知道有實習生招聘這種曲線進大公司的事,因此什麼都沒準備,致使直接裸奔上陣.
  • 3月27日 跟面試官約了晚上的面試時間以後,面了一個小時,從Java虛擬機聊到HashMap,再到ARouter,再聊到Dagger2,再聊到註解處理器,多進程等等,但因爲時間久遠,具體到底聊了啥基本忘了,只感受當時啥都不會不懂,回答的時候都是隻知其一;不知其二的.
  • 3月29日 原本沒報什麼但願的,但兩天後,沒想到阿里讓竟然我這菜雞給過了(心裏OS:受寵若驚).跟面試官約了二面的時間.而後接下來的這幾天,心態極差,心理負擔極重,就是那種不想輸,強烈地想贏的感受,什麼熬夜準備啊,曠課複習啊,反正你作的我都作了.
  • 3月31日 果不其然,當天面的時候我本身都以爲不對勁,一直都是我本身在說,面試官都沒怎麼得問,不到30分鐘就草草收場,至此個人阿里之行就結束了.以後的一個月基本都在複習和調整心態.

1.2 頭條

  • 4月 我其實給頭條投過兩次簡歷,第一次是頭條的一個大佬看到個人文章之後,給了我一個白金碼(很是感謝),讓我有幸參加了頭條4月初的面試.那時阿里剛掛,仍是啥都沒準備,因此也是跟阿里同樣二面就掛了,沒什麼參考價值,因此這裏說的是我第二次投頭條的經歷.
  • 4月底 在牛客網上填寫了簡歷,而後給頭條投遞了簡歷,具體時間記不清了.
  • 5月8日 一面比較順利,主要是Java併發可見性,原子性,有序性的問題,還問了同步關鍵字和Lock的優劣,MVVM等等,基本上都是照着你的簡歷上來問的,答案早已提早準備好,復讀之.
  • 5月10日 二面,一上來就是一道ACM,看到題目就有思路了,奈何實在太緊張,不過在面試官的提示下也寫出來了,二面復讀完Java併發三大特性後,問了View事件傳遞,事件攔截,事件序列的處理,自定義View,減小過渡渲染和優化渲染的N種方法,多進程,OOM問題.面試結束後就是數天漫長的等待,期間沒有任何消息告訴我到底過了仍是沒過,根我第一次投頭條面試完立刻就能收到結果比起來,這不像極了頭條.
  • 5月15日 美團一面事後打電話給頭條的HR問我二面過了沒,HR告訴我沒過以後直接掛了電話.
  • 5月16日 而後戲劇性的一幕出現了!!!早上10點過了沒多久,頭條的HR打電話過來叫我準備下一輪面試,時間安排在下星期一,並且語氣一股沒得商量的感受(心裏OS:這是什麼意思???)
  • 5月20日 我收到了美團的offer,天然就沒繼續去面頭條了.
  • 5月21日 下午HR打電話問我還考不考慮,我感受頭條對我不夠感興趣,就拒絕了,雖然真的很感謝當時該我白金碼的那位大佬,但總感受我並非頭條要找的人.

1.3 美團

  • 5月初 以前就一直想投美團,但一直以爲挺迷的,牛客和實習僧這兩個網站都被頭條刷屏了,爲何TMD中的MD還一點動靜都沒有?就算有也只有iOS崗,因此就很鬱悶,在想可能公司不缺人吧.
  • 5月5日 忽然反應過來還能夠去官網投遞啊,而後去了美團招聘的官網.當時已經很是佛繫了,心想今年美團確定不缺人吧,要否則怎麼動靜這麼小?並且在官網投簡歷,尚未內推不是等於買彩票嗎?但最後仍是抱着試一試的態度投遞了簡歷,並且上面基本啥都沒寫.
  • 5月13日 簡歷竟然被撈了???!!!老大打電話給我約了面試時間.
  • 5月15日 面了40分鐘,差很少也是照着簡從來問,仍是Java併發三大特性,還問了Activity的啓動流程,再有就是我簡歷上寫的那些多進程,MVVM之類的了.因此大概就是把以前面試的內容再復讀一次,不過感受如今復讀得已經比較熟練了,面試完後我問面試官對個人評價如何,面試官貌似很高興,問我簡歷上面怎麼什麼都不寫,還告訴我我很OK,進的機率仍是很大的(心裏OS:有點受寵若驚?)
  • 5月15日下午 老大又給我來了電話,約了下一輪的面試時間,還順便作了一個15分鐘的小面試,問了一些技術問題,基本上是一些開源項目的源碼,期間問到了Glide,我恰好沒看過,嚇得我當天晚上趕忙去把Glide的源碼掃了一遍,最後老大還加了個人微信.
  • 5月16日 沒錯,效率高到甚至沒有隔天,老大面我,面了一個小時.有一道ACM,直接秒了,而後繼續復讀,讓我詳細講了Handler,Looper,MessageQueue,Message的源碼,還有調試追蹤內存泄漏,還有計網TCP三次握手,還有操做系統的死鎖,還有AsyncTask底層和在不一樣API等級之間的區別等等,多多少少都答了,不過有一些仍是缺頁中斷了(忘了或者不會QAQ),可是直到最後都沒問Glide(QAQ跳來跳去的,我看了一夜啊),面完之後老大貌似對我挺滿意的,當場給我過了,而後幫跟我和大老闆約了面試.
  • 5月17日 沒錯,效率高到甚至沒有隔天,大老闆面我,聊了大概20到30分鐘,大老版問的都是一些比較開放性的問題,好比咱們的美團APP啓動白屏了讓你列出20種可能,最後我從各方面瞎編亂造了大概10種實在編不下去了,感受是想考察個人發散思惟能力,而後問了我爲何想去北京,我就說了個人世界觀想去見識更大的世界,感受大老闆挺開心的.面試結束後我而後私下去問老大大老闆以爲我怎麼樣?而後老大告訴我能夠等HR電話了(心裏OS:說實話有點小開心)
  • 5月20日 跟HR確認了offer,至此個人春招結束.感受本身性格缺陷挺多的,真的很感謝老大對個人幫助和包容.

1.4 小結

  • 不要輕易放棄和認爲春招已經結束了,機會其實還有不少.
  • 說句扎心的話,我的以爲其實以爲在面試中運氣真的很重要,若是你和我同樣遇到了超nice的領導,就會一路綠燈,要否則的話真的可能會把你面到自閉.
  • 從我我的主觀這次面試經從來說,感受頭條並無外界傳聞中的那麼效率高缺人.從我我的的這種要強的性格出發,是沒法接受這種你告訴我掛了以後不告訴我緣由,而後又再打電話約下一輪面試的操做的.
  • PS: 我的猜想應該是本來的候選人把頭條給鴿了,而後資格順位繼承到我身上,而後我也鴿了,最後實在沒人了,因此纔會再打電話給我問我考不考慮.可是人是情感動物啊,而情感每每是創建在反饋的基礎上的,若是別人給個人反饋太消極了,那麼我給別人的表現也確定不會積極到哪裏去.

2 把本身訓練成HashMap和復讀機

此次春招給我最大的感觸就是,當你以爲本身像復讀機能把面試題給復讀出來而且對面試官所提的問題能像HashMap同樣在常數時間內找到答案的時候,你就離成功很近了.算法

下面是我在準備面試的時候收集的一些知識點:編程

2.1 Java

2.1.1 volatile理解,JMM中主存和工做內存究竟是啥?和JVM各個部分怎麼個對應關係?

參考link數組

2.1.2 序列化

Serializable在序列化時使用了反射,從而致使GC的頻繁調用,參考link緩存

2.1.3 可見性,原子性,有序性(必考)

  • 可見性volatile,一個線程的修改對另一個線程是立刻可見的,
  • 原子性CAS操做,要麼都作要麼都不作
  • 有序性synchronized經過進入和退出Monitor(觀察器)實現,CPU可能會亂序執行指令,若是在本線程內觀察,全部操做都是有序的,若是在一個線程中觀察另外一個線程,全部操做都是無序的.參考link

2.1.4 Java鎖機制

java鎖機制實際上是鎖總線,同步關鍵字和Lock接口的優劣.安全

2.1.5 Java的常量池?不一樣String賦值方法,引用是否相等?

字面值是常量,在字節碼中使用id索引,equals相等引用不必定相等,Android上String的構造函數會被虛擬機攔截,重定向到StringFactorybash

2.1.6 HashMap的實現?樹化閾值?負載因子?

數組加鏈表加紅黑樹,默認負載因子0.75,樹化閾值8,這部分比較常考,建議專門準備.(打個小廣告OWO,你也能夠關注個人專欄,裏面有一篇文章分析了HashMap和ArrayMap)

2.1.7 Java實現無鎖同步

CAS的實現如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;
    }
}
複製代碼
  • 反序列化安全,反射安全 枚舉級單例,類加載時由JVM保證單例,反序列化不會生成新對象,另一種反射安全是在構造函數中對單例進行檢查若是存在則拋出異常.

2.1.9 鎖的條件變量

信號量要與一個鎖結合使用,當前線程要先得到這個鎖,而後等待與這個鎖相關聯的信號量,此時該鎖會被解鎖,其餘線程能夠搶到這個鎖,若是其餘線程搶到了這個鎖,那他能夠通知這個信號量,而後釋放該鎖,若是此時第一個線程搶到了該鎖,那麼它將從等待處繼續執行(應用場景,將異步回調操做封裝爲變爲同步操做,避免回調地獄)

信號量與鎖相比的應用場景不一樣,鎖是服務於共享資源的,而信號量是服務於多個線程間的執行的邏輯順序的,鎖的效率更高一些.

2.1.10 ThreadLocal原理

線程上保存着ThreadLocalMap,每一個ThreadLocal使用弱引用包裝做爲Key存入這個Map裏,當線程被回收或者沒有其餘地方引用ThreadLocal時,ThreadLocal也會被回收進而回收其保存的值

2.1.11 軟引用,弱引用,虛引用

  • 軟引用內存不夠的時候會釋放
  • 弱引用GC時釋放
  • 虛引用,須要和一個引用隊列聯繫在一塊兒使用,引用了跟沒引用同樣,主要是用來跟GC作一些交互.

2.1.12 ClassLoader雙親委派機制

簡單來講就是先把加載請求轉發到父加載器,父加載器失敗了,再本身試着加載

2.1.13 GC Roots有這些

經過System Class Loader或者Boot Class Loader加載的class對象,經過自定義類加載器加載的class不必定是GC Root:

  • 處於激活狀態的線程
  • 棧中的對象
  • JNI棧中的對象
  • JNI中的全局對象
  • 正在被用於同步的各類鎖對象
  • JVM自身持有的對象,好比系統類加載器等。

2.1.14 GC算法

名稱 描述 優勢 缺點
標記-清除算法 暫停除了GC線程之外的全部線程,算法分爲「標記」和「清除」兩個階段,首先從GC Root開始標記出全部須要回收的對象,在標記完成以後統一回收掉全部被標記的對象。 標記-清除算法的缺點有兩個:首先,效率問題,標記和清除效率都不高。其次,標記清除以後會產生大量的不連續的內存碎片,空間碎片太多會致使當程序須要爲較大對象分配內存時沒法找到足夠的連續內存而不得不提早觸發另外一次垃圾收集動做
複製算法 將可用內存按容量分紅大小相等的兩塊,每次只使用其中一塊,當這塊內存使用完了,就將還存活的對象複製到另外一塊內存上去,而後把使用過的內存空間一次清理掉 這樣使得每次都是對其中一塊內存進行回收,內存分配時不用考慮內存碎片等複雜狀況,只須要移動堆頂指針,按順序分配內存便可,實現簡單,運行高效 複製算法的缺點顯而易見,可以使用的內存降爲原來一半
標記-整理算法 標記-整理算法在標記-清除算法基礎上作了改進,標記階段是相同的,標記出全部須要回收的對象,在標記完成以後不是直接對可回收對象進行清理,而是讓全部存活的對象都向一端移動,在移動過程當中清理掉可回收的對象,這個過程叫作整理。 標記-整理算法相比標記-清除算法的優勢是內存被整理之後不會產生大量不連續內存碎片問題。複製算法在對象存活率高的狀況下就要執行較多的複製操做,效率將會變低,而在對象存活率高的狀況下使用標記-整理算法效率會大大提升
分代收集算法 是java的虛擬機的垃圾回收算法.基於編程中的一個事實,越新的對象的生存期越短,根據內存中對象的存活週期不一樣,將內存劃分爲幾塊,java的虛擬機中通常把內存劃分爲新生代和年老代,當新建立對象時通常在新生代中分配內存空間,當新生代垃圾收集器回收幾回以後仍然存活的對象會被移動到年老代內存中,當大對象在新生代中沒法找到足夠的連續內存時也直接在年老代中建立

2.2 Android

2.2.1 Handler、MessageQueue等一套東西講一下,詳細說了下源碼。爲何主線程loop不會ANR?

  • Android線程模型就是消息循環,Looper關聯MessageQueue,不斷嘗試從MessageQueue取出Message來消費,這個過程可能會被它本身阻塞.
  • 而Handler最終都調用enqueueMessage(Message,when)入隊的,延遲的實現時當前是時間加上延遲時間給消息指定一個執行的時間點,而後在MessageQueue找到插入位置,此時會判斷是否須要喚醒線程來消費消息以及更新下次須要暫停的時間.
  • Message知道要發到哪一個Handler是由於Message把Handler保存到了target.
  • Message內部使用鏈表進行回收複用

2.2.2 View事件以及View體系相關知識

建議看《Android開發藝術探索》,這玩意三言兩語講不清楚

2.2.3 Android中使用多線程的方法

  • 裸new一個Thread(失控線程,不推薦)
  • RxJava的調度器(io(優先級比低),密集計算線程(優先級比高,用於執行密集計算任務),安卓主線程, Looper建立(實際上內部也是建立了Handler))
  • Java Executor框架的Executors#newCachedThreadPool(),不會形成資源浪費,60秒沒有被使用的線程會被釋放
  • AsyncTask,內部使用FutureTask實現,經過Handler將結果轉發到主線程,默認的Executor是共用的,若是同時執行多個AsyncTask,就可能須要排隊,可是能夠手動指定Executor解決這個問題,直接new匿名內部類會保存外部類的引用,可能會致使內存泄漏
  • Android線程模型提供的Handler和HandlerThread
  • 使用IntentService
  • IntentService和Service的區別——沒什麼區別,其實就是開了個HandlerThread,讓它不要在主線程跑耗時任務

2.2.4 RecyclerView複用緩存

建議看一下,這個可能會被問,不過我運氣好沒被問到.

2.2.5 Activity啓動流程

網上有不少相關的文章,能夠本身結合源碼去看一下,若是能講個大概的話也是很加分的.

2.2.6 JNI(除非你本身說你會,不然不是很常考)

  • 可避免的內存拷貝,直接傳遞對象,到C層是一個jobject的指針,可使用jmethodID和jfiledID訪問方法和字段,無需進行內存拷貝,使用直接緩衝區也能夠避免內存拷貝.
  • 沒法避免的內存拷貝,基本類型數組,沒法避免拷貝,由於JVM不信任C層的任何內存操做,特別是字符串操做,由於Java的字符串與C/C++的字符串所使用的數據類型是不同的C/C++使用char一個字節(1字節=8位)或wchar_t是四字節.而jstring和jchar使用的是UTF-16編碼使用雙字節.(Unicode是兼容ASCII,但不兼容GBK,須要本身轉換)
  • 本身建立的局部引用必定要釋放,不然一直持有內存泄漏
  • 非局部引用方法返回後就會失效,除非建立全局引用,jclass是一個jobject,方法外圍使用時須要建立全局引用,jmethodID和jfiledID不須要.
  • JNI是經過Java方法映射到C函數實現的,若是使用這種方法,函數必須以C式接口導出(由於C++會對名字作修飾處理),固然也能夠在JNI_OnLoad方法中註冊.
  • JNIEnv是線程獨立的,JNI中使用pthread建立的線程沒有JNIEnv,須要AttachCurrentThread來獲取JNIEnv,不用時要DetachCurrentThread

2.3專業課

2.3.1 TCP和UDP的根本區別?

數據報,流模式,TCP可靠,包序不對會要求重傳,UDP無論,甚至不能保證送到

2.3.2 TCP三次握手

這個被問的概率很是的大,幾乎等於必問,建議專門花時間去看.

2.3.3 Http和Https

CA證書,中間機構,公鑰加密對稱祕鑰傳回服務端,一個明文一個加密,SSL層,中間人攻擊,參考link

2.4 ACM

對於ACM,比較常考鏈表的題,不常刷算法的同窗必定不要對其有抵觸心理.

你可能會問爲何要ACM?網上答案說的什麼提升代碼質量,可以更好地閱讀別人的代碼這些理由有必定道理,但對於咱們去面試的人而言最重要的是ACM是面試官考察你編碼能力的最直接的手段,因此不用說這麼多廢話刷題就夠了.

刷題的話,建議去刷leetcode,題號在200之內的,簡單和中等難度,不建議刷困難,由於面試的時候基本就不會出,沒人願意在那裏等你想一個半個小時的.

在面試官面前現場白板編程時,能夠先把思路告訴面試官,寫不寫得出來是另一回事,時間複雜度和空間複雜度是怎麼來的必定要搞清楚.在編碼時也不必定要寫出最佳的時間和空間的算法,但推薦你寫出代碼量最少,思路最清晰的,這樣面試官看得舒服,你講得也舒服.

下面是我在網上收集或者是在實際中遇到過的ACM題,基本上在leetcode上也都有相似的.

2.4.1 數組、鏈表

  • 鏈表逆序(頭條几乎是必考的)
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;
    }
複製代碼
  • 刪除排序數組中的重複項
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;
    }
複製代碼
  • 數組中找到重複元素
  • n個長爲n的有序數組,求最大的n個數
  • 用O(1)的時間複雜度刪除單鏈表中的某個節點 把後一個元素賦值給待刪除節點,這樣也就至關因而刪除了當前元素,只有刪除最後一個元素的時間爲o(N)平均時間複雜度仍然爲O(1)
public void deleteNode(ListNode node) {
          ListNode next = node.next;
          node.val = next.val;
          node.next = next.next;
      }
複製代碼
  • 刪除單鏈表的倒數第N個元素 兩個指針,第一個先走N步第二個再走,時間複雜度爲O(N),參考link
public ListNode removeNthFromEnd(ListNode head, int n) {
          if (head == null)
          {
              return null;
          }
          if (head.next == null)
          {
              return n == 1 ? null : head;
          }
          int size = 0;
          ListNode point = head;
          ListNode node = head;
          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 ? null : node.next;
          return head;
      }
複製代碼
  • 從長序列中找出前K大的數字
  • 用數組實現雙頭棧
public static class Stack<T>
      {
          
          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;
          }
      }
複製代碼
  • 兩個鏈表求和,返回結果也用鏈表表示 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;
      }
複製代碼
  • 交換鏈表兩兩節點
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;
      }
複製代碼
  • 找出數組中和爲給定值的兩個元素,如:[1, 2, 3, 4, 5]中找出和爲6的兩個元素。
public int[] twoSum(int[]mun,int target)
      {
          Map<Integer, Integer> 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 樹

  • 二叉樹某一層有多少個節點

2.4.3 排序

  • 雙向鏈表排序(這個就比較過度了,遇到了就自求多福吧)
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;
  	}
  	
  	/**
  	 * 使用如內部實現使用雙向鏈表的LinkedList容器實現的快排 
  	 */
  	public static void quickSort(List<Integer> list) {
  		if (list == null || list.isEmpty()) {
  			return;
  		}
  		quickSort(list, 0, list.size() - 1);
  	}
  	
  	private static void quickSort(List<Integer> 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<Integer> 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;
  	}
複製代碼
  • 常見排序,如堆排序,快速,歸併,冒泡等,還得記住他們的時間複雜度.

2.5 項目

2.5.1 視頻聊天使用什麼協議?

不要答TCP,答RTMP實時傳輸協議,RTMP在Github也有不少開源實現,建議面這方面的同窗能夠去了解一下.

2.5.2 你在項目中遇到的一些問題,如何解決,思路是什麼?

這一塊比較抽象,根據你本身的項目來,着重講你比較熟悉,有把握的模塊,通常面試官都會從中抽取一些問題來向你提問.

2.6 提問

不要問諸如:

  • 面試官是哪一個組的?

這種問題一點價值都沒有,由於你即便問了也不能從他那裏得到額外的信息,也不可以影響他對你的判斷,要問就要問面試官對你的感覺與評價,還要體現出你想要加入的心情以及你問題的深度.

  • XXX今年是否真的缺人?招聘策略是什麼?
  • 面試官認爲我存在哪些不足(從性格和技術兩方面)?
  • 若是面試沒經過能不能告訴我掛掉個人緣由,這樣既能夠幫助到我也能夠幫助到我帶的學弟學妹們,並且在我分享個人面經的時候也能幫助XX招到更好的人.
  • XXX須要我這樣的同窗嗎?

3 最後說一些我的認爲比較重要的事

3.1 積極準備、不斷試錯

  • 機會都是留給有準備的人的,千萬不要想着不許備上戰場就能成功.
  • 多看面經,面經就是面試官們的招聘導向,透過閱讀大量的面經,你可以感覺獲得面試官想要找到什麼樣的人,而且你能夠有針對性地去準備.
  • 由於咱們做爲學生,每每沒有什麼實際的項目經驗,因此操做系統,計算機網絡,數據結構與算法,計算機組成原理這四大基礎就是春招考察的重點.
  • 《Android開發藝術探索》這本書之於Android求職者的重要性,我以爲全世界都應該知道了,若是你尚未看過,建議真的好好看一下吧.
  • 不斷地去面試,若是你此次面試失敗了,那必定要好好總結其中的緣由,必定要千方百計地從面試官口中套出本身的不足,這樣你下次面試成功的機率就會增長.

3.2 真正重要而且最容易忽視的一些問題

每每有不少同窗明明以爲本身已經準備得很好了已經很復讀了,可最後仍是不沒拿到offer,那麼你可能須要考慮如下的問題了.

就像我一開始說的,春招是運氣>性格>三觀>技術的,項目與基礎當然很重要,可是想在短短的數小時能徹底掌握一我的全部的基本狀況實在是太難了,面試官看到的每每只是你的冰山一角,因此在面試的時候,你可能還要在乎如下的問題:

  • 隨機應變: 準備一些圓場的話,好比在講原碼時,若是以爲本身講得不徹底對,最後就補充一句——可能我說得不徹底準確,可是我以爲看源碼不是背書,而是學習他的一種思想並用到本身的代碼中去.
  • 知己知彼: 深刻地瞭解目標公司的企業文化,並準備一些誇他們的話,最好可以讓對方會心一笑,這樣絕對加分.
  • 堅持到底: 有時候可能會被問道一些形而上學的問題,這種問題每每沒有標準答案,求生欲必定要強,不會也要編出來,由於每每面試官問你這些問題,其目的並非看你能不能答對,而是想看看你的發散思惟,看看你能給出多少種的答案,這個過程當中你的嘗試,會被面試官當成你的價值
  • 三觀要正: 世界觀要開闊,敢於迎接挑戰,但不是當舔狗,不能沒有底線,除非是你本身提出,不然當公司讓你曠課去實習的時候我想你應該拒絕,由於若是延畢,可能會影響轉正,最後必定是得不償失,理性大於一切.
  • 端正姿態: 咱們是去求職的,不是去當大爺的,你去實習這三個月打算給公司創造多少價值?因此姿態要放低,當面試官讓你作選擇的時候,先觀察這個問題是不是你可以決定的,若是不是,就說公司怎麼安排我就服從安排,我願意接受新的挑戰讓本身成長.
  • 儒雅隨和: 面試的時候語速可慢但必定不能快,要儒雅隨和,不要貪婪地說話,適可而止,即便你知道的東西真的不少.由於你準備了面試,面試官同樣也準備了面試你,他也有問題想問你的,若是你一直說,他都沒機會問,那他確定不爽.不要搶別人的話頭,遇事不要輕易下結論,就算他說得不對也不能直接衝臉,要委婉一點.
  • 別太誠實: 固然這並非叫你去說謊,該說不懂的仍是得說不懂,不要不懂裝懂.我想說的是不要主動暴露本身的缺點,由於就像我以前說的,面試官面試你的時間是很是短的,每每他對你的瞭解十分有限,你要儘量的表現出本身的優勢而不是缺點.
  • 手握籌碼: 當我去頭條面試的時候,我手裏握有的籌碼就是我可能有很大的機會到某國企實習(校企合做項目),當我去美團面試的時候,個人籌碼就是我頭條也到了三面,你的籌碼間接地證實了你的價值,也能影響面試官對你的判斷.

3.3 結語

透露一下,本人是雙非二本,自從高考失利之後還覺得本身要一直這麼平凡下去QAQ,沒想到過了三年終於又給我一個機會讓我從新證實了本身,能有機會去到美團這樣的大廠工做,真的倍感榮幸.最後的最後仍是慣例啦,若是喜歡個人文章別忘了給我點個贊,拜託了這對我來講真的很重要.

相關文章
相關標籤/搜索