2017年高頻率的網際網路校園招聘面試題
本文由碼農網 – 陳小波原創,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
前言
參加了2017年校招,面試了阿里、百度、騰訊、滴滴、美團、網易、去哪兒等公司,個人是客戶端 Android 方向,總結了面試過程中頻率出現較高的題目,希望對大家有所幫助。
Java 一些知識點
Object 有哪些方法
public
方法:getClass
、equals
、hashCode
、toString
、wait
、notify
protected
方法:clone
、finalize
private
方法:registerNatives
,該方法作用是將不同平臺C/C++實現的方法對映到Java中的native
方法
public class Object { private static native void registerNatives(); // 宣告後有緊接靜態程式碼塊 static { registerNatives(); } }
自動裝箱
public static void main(String[] args) { int i = 0; Integer j = new Integer(0); System.out.println(j == i); System.out.println(j.equals(i)); }
上述程式碼的輸出是
true true
Java 虛擬機器 GC 根節點的選擇
Java通過可達性分析來判斷物件是否存活。基本思想是通過一系列稱為”GC roots”的物件作為起始點,可以作為根節點的是:
- 虛擬機器棧(棧幀中的本地變數表)中引用的物件
- 本地方法棧中 JNI(即一般說的 Native 方法)引用的物件
- 方法區中類靜態屬性引用的物件
- 方法區中常量引用的物件
筆者這麼理解,作為GC Roots的節點主要在全域性性的引用(例如常量或類靜態屬性)與執行上下文(例如棧幀中的本地變數表)中。
虛擬機器棧、本地方法棧這都是區域性變數,某個方法執行完,某些區域性使用的物件可以被回收。
類載入機制
- 啟動類載入器( Bootstrap ClassLoader)啟動類載入器無法被 java 程式設計師直接引用, 這個類載入器負責把存放在
<JAVA_HOME>\lib
目錄中的, 或者被-Xbootclasspath
引數指定路徑中的, 並且是被虛擬機器識別的類庫載入到虛擬機器記憶體中. - 擴充套件類載入器(Extension ClassLoader)負責載入在
<JAVA_HOME>\lib\ext
目錄中的, 或者被java.ext.dirs
系統變數所指定的路徑中的所有類庫。 - 應用程式類載入器( Application ClassLoader )這個類載入器是
ClassLoader
中的getSystemClassLoader()
方法的返回值, 一般稱其為系統類載入器, 它負責載入使用者類路徑(ClassPath
)上所指定的類庫
從 java 虛擬機器的角度而降, 只存在兩種不同的類載入器:
- 一個是啟動類載入器(
Bootstrap ClassLoader
), 這個類載入使用 C++ 語言實現, 是虛擬機器自身的一部分; - 另一種是其他所有的類載入器, 他們由 java 語言實現, 獨立於虛擬機器之外, 並且全部繼承自
java.lang.ClassLoader
載入類的尋找範圍就是 JVM 預設路徑加上Classpath
, 類具體是使用哪個類載入器不確定。
類載入主要步驟
- 載入 把 class 檔案的二進位制位元組流載入到 jvm 裡面
- 驗證 確保 class 檔案的位元組流包含的資訊符合當前 jvm 的要求 有檔案格式驗證, 後設資料驗證, 位元組碼驗證, 符號引用驗證等
- 準備 正式為類變數分配記憶體並設定類變數初始值的階段, 初始化為各資料型別的零值
- 解析 把常量值內的符號引用替換為直接引用的過程
- 初始化 執行類構造器
<clinit>()
方法 - 使用 根據相應的業務邏輯程式碼使用該類
- 解除安裝 類從方法區移除
雙親委派模型
除了頂層的啟動類載入器之外, 其餘的類載入器都應當有自己的父類載入器, 父子關係這兒一般都是以組合來實現。
工作過程: 如果一個類載入器收到了類載入的請求, 它首先不會自己去嘗試載入這個類, 而是把這個請求委派給父類載入器去完成, 最終所有的載入請求都會傳送到頂層的啟動類載入器中, 只有當父類載入器反饋自己無法完成這個請求時候, 才由子載入器來載入。
例如類Object
,它放在rt.jar
中,無論哪一個類載入器要載入這個類,最終都是委派給啟動類載入器進行載入,因此Object
類在程式的各種類載入器環境中都是同一個類。
對於任何一個類, 都需要由載入它的類載入器和這個類本身一同確定其在 java 虛擬機器中的唯一性。
ClassLoader.loadClass()
的程式碼如下,先檢查是否已經被載入過,如果沒有則parent.loadClass()
呼叫父載入器的loadClass()
方法,如果父載入器為空則預設使用啟動類載入器作為父載入器。如果父類載入器載入失敗,丟擲ClassNotFoundException
,再呼叫自己的findClass()
方法進行載入。
另外,如果我們自己實現類載入器,一般是Override
複寫 findClass
方法,而不是loadClass
方法。
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); //可以Override該方法 } } if (resolve) { resolveClass(c); } return c; } }
Java 後臺的一點知識
JSP 與 Servlet 的關係
- Tomcat 等 Web 容器最終會把 JSP轉化為 Servlet
- Jsp更擅長表現於頁面顯示, Servlet更擅長於邏輯控制
- Servlet是利用
System.out.println()
來輸出 html 程式碼,由於包括大量的HTML標籤、大量的靜態文字及格式等,導致Servlet的開發效率低下 - JSP通過在標準的HTML頁面中嵌入Java程式碼,其靜態的部分無須Java程式控制,Java 程式碼只控制那些動態生成的資訊
- 最終 JSP 被容器解釋為 Servlet,其中Html 程式碼也是用
System.out.println()
等拼接輸出的 - JSP 第一次訪問的時候,要轉化為 java 檔案,然後編譯為 class 檔案,所以第一次訪問 JSP 速度會比較慢,後面會快很多
Servlet 生命週期
主要是java.servlet.Servlet
介面中的init()
、service()
、和destroy()
3個方法。
- 初始化階段,web容器通過呼叫
init()
方法來初始化Servlet
例項,在Servlet的整個生命週期類,init()
方法只被呼叫一次 - 客戶請求到來時,容器會開始一個新執行緒,並呼叫servlet的
service()
方法,service()
方法根據請求的http方法來呼叫doget()
或dopost()
- 終止階段呼叫
destroy()
方法,銷燬一些資源
GET 請求 vs POST 請求
GET
用於資訊獲取,是安全的和冪等的,GET
一般是對後臺資料庫的資訊進行查詢POST
表示可能修改變伺服器上的資源的請求,一般是對後臺資料庫進行增、刪、改的操作GET
請求的引數會跟在URL後進行傳遞,請求的資料會附在URL之後,以?
分割URL和傳輸資料,引數之間以&
相連,一般瀏覽器對 URL 的長度會有限制POST
請求,提交的資料則放置在是HTTP包的包體中,用類似Key-Value
的格式傳送一些資料,相對來說,GET
請求會把請求的引數暴露在 URL 中,安全性比POST
差一些
HTTP 請求的基本格式
- <
request line>
請求行 <headers>
請求頭(引數頭)<blank line>
空白行[<request-body>]
請求實體(GET沒有, POST有
)
資料庫
索引的分類
主要分為聚集索引和非聚集索引:
- 聚集索引儲存記錄物理上連續,而非聚集索引是邏輯上的連續,物理儲存並不連續
- 聚集索引一個表只能有一個,而非聚集索引一個表可以存在多個
ResultSet 統計記錄數目
Java 中使用JDBC
連線資料庫,最後都會得到一個 ResultSet,比如如下的程式碼
Connection con = DriverManager.getConnection(url, username, password); Statement sta = con.createStatement(); String sql = "select * from student"; ResultSet resultSet = sta.executeQuery(sql);
那麼如何根據得到的ResultSet
統計一共有多少條記錄呢?注意:ResultSet
沒有提供類似size()
、length
的 API 來直接獲取總記錄數。
方法1:利用迴圈
int sum = 0; while(resultSet.next()){ sum++; }
方法2:利用ResultSet的getRow方法來獲得ResultSet的總行數
resultSet.last(); //移到最後一行 int rowCount = resultSet.getRow(); //得到當前行號,也就是記錄數
設計模式
單例模式
單例模式中必須保證只有一個例項存在。有時候單例是為了避免重複建立多個例項造成資源浪費,有時候也是為了避免多個不同的例項導致系統不一致的行為。
Android 中,App啟動時系統會建立一個Application
物件,用來儲存系統的一些資訊,這兒的Application
就是是單例模式的應用。可以通過Context.getApplicationContext()
獲取唯一的Application
例項。
class Singleton { private volatile static Singleton instance; private Singleton() { } public static Singleton getInstance() { //第一重判斷 if (instance == null) { //鎖定程式碼塊 synchronized (Singleton.class) { //第二重判斷 if (instance == null) { instance = new Singleton(); //建立單例例項 } } } return instance; } }
為什麼synchronized
裡面需要加一次判斷if (instance == null)
,是考慮這樣的特殊情形:比如執行緒A、B都到達第一個if (instance == null)
,執行緒A進入synchronized
程式碼中建立例項,執行緒B排隊等待。但當A執行完畢時,執行緒B進入synchronized
鎖定程式碼,它並不知道例項已經建立,將繼續建立新的例項,導致產生多個單例物件。
也可以用內部類的方式建立,
public class Singleton(){ private static class Inner { private static Singleton instance = new Singleton(); } private Singleton() { } public static Singleton getInstance(){ return Inner.instance; } }
模板方法模式
在父類中實現一個演算法不變的部分,並將可變的行為留給子類來實現。
比如AsyncTask
裡面的四個方法onPreExecute
、doInBackground
、onProgressUpdate
、onPostExecute
還有Activity
也應用了模板方法模式
onCreate
、onStart
、onResume
、onPause
、onStop
、onDestroy
、onRestart
介面卡模式
分為兩種:類的介面卡模式、物件的介面卡模式
Android 裡的 ListView
和 RecyclerView
的setAdapter()
方法就是使用了介面卡模式。
觀察者模式
在 GUI 中,不管是 Windows 桌面應用、或者 Android、IOS,都會給某個按鈕 Button 設定監聽事件,這兒就是使用了觀察者模式。Android 中設定 Button 的監聽事件程式碼如下:
final Button button = (Button) findViewById(R.id.button_id); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Perform action on click } });
筆試程式設計題
執行緒 VS 程式
關於執行緒和程式,不正確的描述是__。(選 D 棧是執行緒私有, 儲存其執行狀態和區域性變數 )
A. 程式的隔離性要好於執行緒
B. 執行緒在資源消耗上通常要比程式輕量
C. 不同程式間不會共享邏輯地址空間
D. 同一個程式的執行緒之間共享記憶體,包括堆和棧
E. 程式間有途徑共享大量記憶體中的資料
F. 執行緒間通訊可以通過直接訪問全域性變數,或者使用程式間通訊的機制(IPC)
找出未打卡的員工
題目:輸入兩行資料,第一行為全部員工的 id,第二行為某一天打卡的員工 id,已知只有一個員工沒有打卡,求出未打卡員工的 id。(員工 id 不重複,每行輸入的 id 未排序)
輸入:
1001 1003 1002 1005 1004
1002 1003 1001 1004
輸出:
1005
分析:可以用兩個 List,第一個 List 儲存所有員工的 id,第二個 List 儲存打卡員工的 id,從第一個List 中把第二個 List 的資料都刪除,最終剩下的就是未打卡員工的 id。
更好的方法:異或,兩行資料中未打卡員工的 id 出現了一次,其餘員工的 id 都出現了2次,兩個相同的數異或為0。
public static void main(String[] args) { Scanner scan = new Scanner(System.in); while (scan.hasNext()) { String[] ids = scan.nextLine().split(" "); String[] marks = scan.nextLine().split(" "); int result = 0; for (int i = 0; i < ids.length; i++) { result ^= Integer.parseInt(ids[i]); } for (int i = 0; i < marks.length; i++) { result ^= Integer.parseInt(marks[i]); } System.out.println(result); } }
手寫程式碼題
快速排序
排序是經典面試題,公司也希望通過手寫快排來考察面試者的程式設計習慣和基本功。
// 排序範圍 [start, end], 包含 end public void sort(int[] arr, int start, int end) { if (start < end) { int p = partition(arr, start, end); quickSort(arr, start, p - 1); quickSort(arr, p + 1, end); } } // 一次劃分程式碼,返回被劃分後的基準位置 public static int partition(int[] arr, int left, int right) { int pivot = arr[left]; while (left < right) { while (left < right && arr[right] >= pivot) right--; if (left < right) arr[left++] = arr[right]; while (left < right && arr[left] <= pivot) left++; if (left < right) arr[right--] = arr[left]; } arr[left] = pivot; return left; }
Note:快排是不穩定的,常見的穩定排序是:冒泡、插入、歸併
括號字串是否合法
某個字串只包括(
和)
,判斷其中的括號是否匹配正確,比如(()())
正確,((())()
錯誤,不允許使用棧
。
這種類似題的常見思路是棧,對於左括號入棧,如果遇到右括號,判斷此時棧頂是不是左括號,是則將其出棧,不是則該括號序列不合法。
面試官要求不能使用棧,可以使用計數器,利用int count
欄位。
public static boolean checkBrackets(String str) { char[] cs = str.toCharArray(); int count = 0; for (int i = 0; i < cs.length; i++) { if (cs[i] == '(') count++; else { count--; if (count < 0) { return false; } } } return count == 0; }
撲克牌隨機發牌
對於52張牌,實現一個隨機打算撲克牌順序的程式。52張牌使用 int
陣列模擬。
該演算法的難點是如何保證隨機性?有個經典演算法shuffle
,思路就是遍歷陣列,在剩下的元素裡再隨機取一個元素,然後再在剩下的元素裡再隨機取一個元素。每次取完元素後,我們就不會讓這個元素參與下一次的選取。
To shuffle an array a of n elements (indices 0..n-1): for i from n − 1 downto 1 do j ← random integer with 0 ≤ j ≤ i exchange a[j] and a[i]
注意這兒是0 ≤ j ≤ i
,包括j=i
的情況,因為可能洗牌後某個牌未發生交換,比如第51張牌還是原來的第51張牌。
public void randomCards() { int[] data = new int[52]; Random random= new Random(); for (int i = 0; i < data.length; i++) data[i] = i; for (int i = data.length - 1; i > 0; i--) { int temp = random.nextInt(i+1); //產生 [0,i] 之間的隨機數 swap(data,i,temp); } }
智力題
金條付費
你讓工人為你工作7天,回報是一根金條,這個金條平分成相連的7段,你必須在每天結束的時候給他們一段金條,如果只允許你兩次把金條弄斷,你如何給你的工人付費?
答案:切成一段,兩段,和四段.
第1天: 給出1.
第2天: 給出2,還回1.
第3天: 給出1.
第4天: 給出4,還回1+2.
第5天: 給出1.
第6天: 給出2,還回1.
第7天: 給出1.
賽馬
25匹馬,速度都不同,但每匹馬的速度都是定值。現在只有5條賽道,無法計時,即每賽一場最多隻能知道5匹馬的相對快慢。問最少賽幾場可以找出25匹馬中速度最快的前3名?
答案:
- 25匹馬分成5組,先進行5場比賽
- 再將剛才5場的冠軍進行第6場比賽,得到第一名。按照第6場比賽的名詞把前面5場比賽所在的組命名為 A、B、C、D、E 組,即 A 組的冠軍是第6場第一名,B 組的冠軍是第二名 …
- 分析第2名和第3名的可能性,如果確定有多於3匹馬比某匹馬快,那它可以被淘汰了。因為 D 組是第6場的第四名,整個D 組被淘汰了,同意整個 E 組被淘汰。剩下可能是整體的第2、3名的就是C組的第1名、B組的1、2名、A組的第2、3名。取這5匹馬進行第7場比賽
-所以,一共需要7場比賽
本文連結:http://www.codeceo.com/article/it-interview-question-2017.html
本文作者:碼農網 – 陳小波
[ 原創作品,轉載必須在正文中標註並保留原文連結和作者等資訊。]
相關文章
- 校園網-真實的校園網路社群
- 大學創業,何不從網際網路+校園開始創業
- 請查收:2020網際網路大廠高頻面試題!面試題
- 智慧校園如何讓移動網際網路和教育相融合?
- 校園招聘的思考
- 大學校園IP網路廣播-基於校園區域網的大學校園IP廣播方案設計指南
- 網際網路校招面試必備——計算機網路 | 掘金技術徵文面試計算機網路
- 網際網路公司面試必問的Redis題目面試Redis
- 各大網際網路公司面試流程及面試題彙總面試題
- 大型網際網路公司必考java面試題與面試技巧Java面試題
- 網際網路 Java 工程師面試題(Spring 面試題一)Java工程師面試題Spring
- 百度2015校園招聘面試題(成功拿到offer)面試題
- 知名網際網路公司校招中常見的演算法題演算法
- 2017下半年,一二線網際網路公司Android面試題彙總Android面試題
- 網校程式原始碼:網校頻頻倒閉的背後原因原始碼
- 網際網路公司面試必問的mysql題目(上)面試MySql
- 網際網路公司面試必問的mysql題目(下)面試MySql
- eMarketer:巴西網際網路概況,網際網路普及率和社交網路
- 突破Java面試(01)-看看現代網際網路java工程師的招聘JDJava面試工程師
- [面試專題]一線網際網路大廠面試總結面試
- 網際網路校招面試必備——資料庫 | 掘金技術徵文面試資料庫
- 校園IP網路廣播系統方案
- 幾個專業的網際網路招聘網站推薦網站
- 知名網際網路公司校招 Java 開發崗面試知識點解析Java面試
- 「網際網路大廠」招聘Java架構師Java架構
- 2014網際網路公司招聘的奇葩故事
- 【小米集團校園招聘】射頻測試工程師 (急招)工程師
- [小米集團校園招聘] 射頻測試工程師 (急招)工程師
- 校園網應用分析
- 校園社交網站app網站APP
- 一線網際網路大廠MySQL索引面試真題MySql索引面試
- 各大IT公司2012校園招聘筆試面試整理筆試面試
- 網際網路公司最常見的面試演算法題有哪些?面試演算法
- 最新網際網路校招,看到薪資我......
- 網際網路女皇報告:全球網際網路滲透率停滯在60%
- 網際網路校招面試必備——Java多執行緒 | 掘金技術徵文面試Java執行緒
- 奧巴馬:讓99%的美國學校享受高速網際網路
- 智慧園區綜合解決方案,打造園區生態網際網路