網際網路大型公司(阿里騰訊百度等)android面試題目(有答案)
又到年底了,這幾天不是很忙,就整理一下面試題目,供大家學習瞭解,哈哈年後想換工作的,你們懂得。
Android 基礎與底層機制
-
資料庫的操作型別有哪些,如何匯入外部資料庫?
資料庫的操作型別:增、刪、改、查;
把原資料庫包括在專案原始碼的 res/raw
android系統下資料庫應該存放在 /data/data/com..(package name)/ 目錄下,所以我們需要做的是把已有的資料庫傳入那個目錄下.操作方法是用FileInputStream讀取原資料庫,再用FileOutputStream把讀取到的東西寫入到那個目錄.
-
是否使用過本地廣播,和全域性廣播有什麼差別?
全域性廣播(BroadcastReceiver):發出去的廣播可以被任何應用程式接收到,也可以接受來自任何應用程式的廣播;
本地廣播(LocalBroadcastManager):傳送的廣播只會在自己App內傳播,不會洩露給其他App,確保隱私資料不會洩露;其他App也無法向你的App傳送該廣播,不用擔心其他App會來搞破壞;比系統全域性廣播更加高效;
-
是否使用過 IntentService,作用是什麼, AIDL 解決了什麼問題?
Service是在主執行緒中而沒有另開新的執行緒執行任務,不能處理耗時操作;
而IntentServicee是有替代Service處理耗時操作的作用,從IntentService的原始碼中我們也可以看到IntentService實際也是通過Handler來進行主執行緒的UI更新等操作;IntentServicee有一個抽象方法onHandleIntent,在這裡可以處理耗時操作;AIDL 可以跨程序訪問其他應用程式,和其他應用程式通訊,多程序間通訊;
-
Activity、 Window、 View 三者的差別, fragment 的特點?
Activity是Android應用程式的載體,允許使用者在其上建立一個使用者介面,並提供使用者處理事件的API,如onKeyEvent, onTouchEvent等。 並維護應用程式的生命週期。
當我們呼叫Acitivity的 setContentView方法的時候實際上是呼叫的Window物件的setContentView方法,所以我們可以看出Activity中關於介面的繪製實際上全是交給Window物件來做的。
Activity--->Window--->DecorView
Activity像一個工匠(控制單元),Window像窗戶(承載模型),View像窗花(顯示檢視) LayoutInflater像剪刀,Xml配置像窗花圖紙。
在Activity中呼叫attach,建立了一個Window
建立的window是其子類PhoneWindow,在attach中建立PhoneWindow
在Activity中呼叫setContentView(R.layout.xxx)
其中實際上是呼叫的getWindow().setContentView()
呼叫PhoneWindow中的setContentView方法
建立ParentView:作為ViewGroup的子類,實際是建立的DecorView(作為 FramLayout的子類)
將指定的R.layout.xxx進行填充通過佈局填充器進行填充【其中的parent指的>* 就是DecorView】
呼叫到ViewGroup
呼叫ViewGroup的removeAllView(),先將所有的view移除掉
新增新的view:addView()
fragment 特點
Fragment可以作為Activity介面的一部分組成出現;
可以在一個Activity中同時出現多個Fragment,並且一個Fragment也可以在多個Activity中使用;
在Activity執行過程中,可以新增、移除或者替換Fragment;
Fragment可以響應自己的輸入事件,並且有自己的生命週期,它們的生命週期會受宿主Activity的生命週期影響。
-
描述一次網路請求的流程(新浪)
域名解析
TCP的三次握手
建立TCP連線後發起HTTP請求
伺服器響應HTTP請求
瀏覽器解析html程式碼
同時請求html程式碼中的資源(如js、css、圖片等)
最後瀏覽器對頁面進行渲染並呈現給使用者
參考:
Handler、 Thread 和 HandlerThread 的差別(小米)
Thread是一個執行緒;
我們知道Handler是用來非同步更新UI的,更詳細的說是用來做執行緒間的通訊的,更新UI時是子執行緒與UI主執行緒之間的通訊。那麼現在我們要是想子執行緒與子執行緒之間的通訊要怎麼做呢?當然說到底也是用Handler+Thread來完成(不推薦,需要自己操作Looper)
HandlerThread就是(Handler+Thread結合),HandlerThread其實還是一個執行緒,它跟普通執行緒有什麼不同之處是多了一個Looper,這個是子執行緒獨有的Looper,用來做訊息的取出和處理。
-
低版本 SDK 實現高版本 api(小米)
在使用高於minSdkVersion API level的方法需要:
用@TargeApi($API_LEVEL) 使可以編譯通過, 不建議使用@SuppressLint("NewApi");
執行時判斷API level; 僅在足夠高,有此方法的API level系統中,呼叫此方法;
保證功能完整性,保證低API版本通過其他方法提供功能實現。
-
launch mode 應用場景(百度、小米、樂視)
standard:每次啟用Activity時都會建立Activity例項,並放入任務棧中。這個是預設的;
singleTop:如果已經存在在棧頂在對方的任務一個同類型的活動例項,不會有任何新的activity創造,而是被髮送到一個存在的activity例項通過onNewIntent() 方法的意圖,即會重用該例項呼叫當前activity的onNewIntent() 方法。適合接收通知啟動的內容顯示頁面。
例如,某個新聞客戶端的新聞內容頁面,如果收到10個新聞推送,每次都開啟一個新聞內容頁面是很煩人的。singleTask:如果系統中有一個存在的活動例項,整個任務將例項將被移動到頂部,Intent將通過onnewintent()方法交付。否則,新的activity將被建立並放置在適當的任務中。適合作為程式入口點。
例如瀏覽器的主介面。不管從多少個應用啟動瀏覽器,只會啟動主介面一次,其餘情況都會走onNewIntent,並且會清空主介面上面的其他頁面。singleInstance適合需要與程式分離開的頁面。
例如鬧鈴提醒,將鬧鈴提醒與鬧鈴設定分離。
singleInstance不要用於中間頁面,如果用於中間頁面,跳轉會有問題,比如:A -> B (singleInstance) -> C,完全退出後,在此啟動,首先開啟的是B。
-
touch 事件傳遞流程(小米)
image.png
-
view 繪製流程(百度)
image.png
https://www.jianshu.com/p/5a71014e7b1b
-
什麼情況導致記憶體洩漏(美團)
1.單例造成的記憶體洩漏
由於單例的靜態特性使得其生命週期和應用的生命週期一樣長,如果一個物件已經不再需要使用了,而單例物件還持有該物件的引用,就會使得該物件不能被正常回收,從而導致了記憶體洩漏。2.非靜態內部類建立靜態例項造成的記憶體洩漏
例如,有時候我們可能會在啟動頻繁的Activity中,為了避免重複建立相同的資料資源,可能會出現如下寫法:1public class MainActivity extends AppCompatActivity { 2 private static TestResource mResource = null; 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 if(mResource == null){ 8 mResource = new TestResource(); 9 } 10 //... 11 } 12 class TestResource { 13 //... 14 } 15}
這樣在Activity內部建立了一個非靜態內部類的單例,每次啟動Activity時都會使用該單例的資料。雖然這樣避免了資源的重複建立,但是這種寫法卻會造成記憶體洩漏。因為非靜態內部類預設會持有外部類的引用,而該非靜態內部類又建立了一個靜態的例項,該例項的生命週期和應用的一樣長,這就導致了該靜態例項一直會持有該Activity的引用,從而導致Activity的記憶體資源不能被正常回收。
解決方法:將該內部類設為靜態內部類或將該內部類抽取出來封裝成一個單例,如果需要使用Context,就使用Application的Context。
3.Handler造成的記憶體洩漏
示例:建立匿名內部類的靜態物件
1public class MainActivity extends AppCompatActivity { 2 private final Handler handler = new Handler() { 3 @Override 4 public void handleMessage(Message msg) { 5 // ... 6 } 7 }; 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.activity_main); 12 new Thread(new Runnable() { 13 @Override 14 public void run() { 15 // ... 16 handler.sendEmptyMessage(0x123); 17 } 18 }); 19 } 20}
1、從Android的角度
當Android應用程式啟動時,該應用程式的主執行緒會自動建立一個Looper物件和與之關聯的MessageQueue。當主執行緒中例項化一個Handler物件後,它就會自動與主執行緒Looper的MessageQueue關聯起來。所有傳送到MessageQueue的Message都會持有Handler的引用,所以Looper會據此回撥Handle的handleMessage()方法來處理訊息。只要MessageQueue中有未處理的Message,Looper就會不斷的從中取出並交給Handler處理。另外,主執行緒的Looper物件會伴隨該應用程式的整個生命週期。
2、 Java角度
在Java中,非靜態內部類和匿名類內部類都會潛在持有它們所屬的外部類的引用,但是靜態內部類卻不會。對上述的示例進行分析,當MainActivity結束時,未處理的訊息持有handler的引用,而handler又持有它所屬的外部類也就是MainActivity的引用。這條引用關係會一直保持直到訊息得到處理,這樣阻止了MainActivity被垃圾回收器回收,從而造成了記憶體洩漏。
解決方法:將Handler類獨立出來或者使用靜態內部類,這樣便可以避免記憶體洩漏。
4.執行緒造成的記憶體洩漏
示例:AsyncTask和Runnable
AsyncTask和Runnable都使用了匿名內部類,那麼它們將持有其所在Activity的隱式引用。如果任務在Activity銷燬之前還未完成,那麼將導致Activity的記憶體資源無法被回收,從而造成記憶體洩漏。
解決方法:將AsyncTask和Runnable類獨立出來或者使用靜態內部類,這樣便可以避免記憶體洩漏。
5.資源未關閉造成的記憶體洩漏
對於使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等資源,應該在Activity銷燬時及時關閉或者登出,否則這些資源將不會被回收,從而造成記憶體洩漏。
1)比如在Activity中register了一個BraodcastReceiver,但在Activity結束後沒有unregister該BraodcastReceiver。
2)資源性物件比如Cursor,Stream、File檔案等往往都用了一些緩衝,我們在不使用的時候,應該及時關閉它們,以便它們的緩衝及時回收記憶體。它們的緩衝不僅存在於 java虛擬機器內,還存在於java虛擬機器外。如果我們僅僅是把它的引用設定為null,而不關閉它們,往往會造成記憶體洩漏。
3)對於資源性物件在不使用的時候,應該呼叫它的close()函式將其關閉掉,然後再設定為null。在我們的程式退出時一定要確保我們的資源性物件已經關閉。
4)Bitmap物件不在使用時呼叫recycle()釋放記憶體。2.3以後的bitmap應該是不需要手動recycle了,記憶體已經在java層了。
6.使用ListView時造成的記憶體洩漏
初始時ListView會從BaseAdapter中根據當前的屏幕布局例項化一定數量的View物件,同時ListView會將這些View物件快取起來。當向上滾動ListView時,原先位於最上面的Item的View物件會被回收,然後被用來構造新出現在下面的Item。這個構造過程就是由getView()方法完成的,getView()的第二個形參convertView就是被快取起來的Item的View物件(初始化時快取中沒有View物件則convertView是null)。
構造Adapter時,沒有使用快取的convertView。
解決方法:在構造Adapter時,使用快取的convertView。
7.集合容器中的記憶體洩露
我們通常把一些物件的引用加入到了集合容器(比如ArrayList)中,當我們不需要該物件時,並沒有把它的引用從集合中清理掉,這樣這個集合就會越來越大。如果這個集合是static的話,那情況就更嚴重了。
解決方法:
在退出程式之前,將集合裡的東西clear,然後置為null,再退出程式。
8.WebView造成的洩露
當我們不要使用WebView物件時,應該呼叫它的destory()函式來銷燬它,並釋放其佔用的記憶體,否則其長期佔用的記憶體也不能被回收,從而造成記憶體洩露。
解決方法:
為WebView另外開啟一個程序,通過AIDL與主執行緒進行通訊,WebView所在的程序可以根據業務的需要選擇合適的時機進行銷燬,從而達到記憶體的完整釋放。
-
ANR 定位和修正
如果開發機器上出現問題,我們可以通過檢視/data/anr/traces.txt即可,最新的ANR資訊在最開始部分。
主執行緒被IO操作(從4.0之後網路IO不允許在主執行緒中)阻塞。
主執行緒中存在耗時的計算
主執行緒中錯誤的操作,比如Thread.wait或者Thread.sleep等 Android系統會>* 監控程式的響應狀況,一旦出現下面兩種情況,則彈出ANR對話方塊
應用在5秒內未響應使用者的輸入事件(如按鍵或者觸控)
BroadcastReceiver未在10秒內完成相關的處理
Service在特定的時間內無法處理完成 20秒
修正使用AsyncTask處理耗時IO操作。
使用Thread或者HandlerThread時,呼叫Process.setThreadPriority(Process.THREADPRIORITYBACKGROUND)設定優先順序,否則仍然會降低程式響應,因為預設Thread的優先順序和主執行緒相同。
使用Handler處理工作執行緒結果,而不是使用Thread.wait()或者Thread.sleep()來阻塞主執行緒。
Activity的onCreate和onResume回撥中儘量避免耗時的程式碼
BroadcastReceiver中onReceive程式碼也要儘量減少耗時,建議使用IntentService處理。
-
什麼情況導致 oom(樂視、美團)
這個跟11好像差不多
Android Service 與 Activity 之間通訊的幾種方式
通過Binder物件
通過Intent
通過Broadcast廣播
自定義介面回撥
Android 各個版本 API 的區別
http://blog.csdn.net/u012964796/article/details/50662564如何保證一個後臺服務不被殺死,比較省電的方式是什麼?(百度)
雙程序守護(就是開啟二個service,二個service是不同的程序中,用aidl監聽,有一個service殺死了,另一個service監聽到了就重新啟動剛殺死的service),這個有時間時專門寫文章介紹;
service繫結通知欄成為前臺服務,
還有一個就是鎖屏時啟動一個畫素的activity,哈哈,好像某應用就是這麼幹的;
AlarmManager不斷啟動service
通過jni呼叫,在c層啟動多程序
-
Requestlayout, onlayout, onDraw, DrawChild 區別與聯絡(獵豹)
requestLayout()方法 :會導致呼叫measure()過程 和 layout()過程 。 將會根據標誌位判斷是否需要ondraw
onLayout()方法(如果該View是ViewGroup物件,需要實現該方法,對每個子檢視進行佈局)
呼叫onDraw()方法繪製檢視本身 (每個View都需要過載該方法,ViewGroup不需要實現該方法)
drawChild()去重新回撥每個子檢視的draw()方法
-
invalidate()和 postInvalidate() 的區別及使用(百度)
postInvalidate() 方法在非 UI 執行緒中呼叫,通知 UI 執行緒重繪。
invalidate() 方法在 UI 執行緒中呼叫,重繪當前 UI。
Android 動畫框架實現原理
Animation框架定義了透明度,旋轉,縮放和位移幾種常見的動畫,而且控制的是整個View,實現原理是每次繪製檢視時View所在的ViewGroup中的drawChild函式獲取該View的Animation的Transformation值,然後呼叫canvas.concat(transformToApply.getMatrix()),通過矩陣運算完成動畫幀,如果動畫沒有完成,繼續呼叫invalidate()函式,啟動下次繪製來驅動動畫,動畫過程中的幀之間間隙時間是繪製函式所消耗的時間,可能會導致動畫消耗比較多的CPU資源,最重要的是,動畫改變的只是顯示,並不能相應事件。
-
Android 為每個應用程式分配的記憶體大小是多少?(美團)
android程式記憶體一般限制在16M,也有的是24M
-
Android View 重新整理機制(百度、美團)
由ViewRoot物件的performTraversals()方法呼叫draw()方法發起繪製該View樹,值得注意的是每次發起繪圖時,並不會重新繪製每個View樹的檢視,而只會重新繪製那些“需要重繪”的檢視,View類內部變數包含了一個標誌位DRAWN,當該檢視需要重繪時,就會為該View新增該標誌位。
呼叫流程 :
mView.draw()開始繪製,draw()方法實現的功能如下:
繪製該View的背景為顯示漸變框做一些準備操作(見5,大多數情況下,不需要改漸變框)呼叫onDraw()方法繪製檢視本身 (每個View都需要過載該方法,ViewGroup不需要實現該方法)呼叫dispatchDraw ()方法繪製子檢視(如果該View型別不為ViewGroup,即不包含子檢視,不需要過載該方法)值得說明的是,ViewGroup類已經為我們重寫了dispatchDraw ()的功能實現,應用程式一般不需要重寫該方法,但可以過載父類函式實現具體的功能。
-
LinearLayout 對比 RelativeLayout(百度)(Ricky)
RelativeLayout會讓子View呼叫2次onMeasure,LinearLayout 在有weight時,也會呼叫子View2次onMeasure,RelativeLayout的子View如果高度和RelativeLayout不同,則會引發效率問題,當子View很複雜時,這個問題會更加嚴重。如果可以,儘量使用padding代替margin。在不影響層級深度的情況下,使用LinearLayout和FrameLayout而不是RelativeLayout。
最後再思考一下文章開頭那個矛盾的問題,為什麼Google給開發者預設新建了個RelativeLayout,而自己卻在DecorView中用了個LinearLayout。因為DecorView的層級深度是已知而且固定的,上面一個標題欄,下面一個內容欄。採用RelativeLayout並不會降低層級深度,所以此時在根節點上用LinearLayout是效率最高的。而之所以給開發者預設新建了個RelativeLayout是希望開發者能採用儘量少的View層級來表達佈局以實現效能最優,因為複雜的View巢狀對效能的影響會更大一些。
-
優化自定義 view(百度、樂視、小米)
為了加速你的view,對於頻繁呼叫的方法,需要儘量減少不必要的程式碼。先從onDraw開始,需要特別注意不應該在這裡做記憶體分配的事情,因為它會導致GC,從而導致卡頓。在初始化或者動畫間隙期間做分配記憶體的動作。不要在動畫正在執行的時候做記憶體分配的事情。
你還需要儘可能的減少onDraw被呼叫的次數,大多數時候導致onDraw都是因為呼叫了invalidate().因此請儘量減少呼叫invaildate()的次數。如果可能的話,儘量呼叫含有4個引數的invalidate()方法而不是沒有引數的invalidate()。沒有引數的invalidate會強制重繪整個view。
另外一個非常耗時的操作是請求layout。任何時候執行requestLayout(),會使得Android UI系統去遍歷整個View的層級來計算出每一個view的大小。如果找到有衝突的值,它會需要重新計算好幾次。另外需要儘量保持View的層級是扁平化的,這樣對提高效率很有幫助。
如果你有一個複雜的UI,你應該考慮寫一個自定義的ViewGroup來執行他的layout操作。與內建的view不同,自定義的view可以使得程式僅僅測量這一部分,這避免了遍歷整個view的層級結構來計算大小。這個PieChart 例子展示瞭如何繼承ViewGroup作為自定義view的一部分。PieChart 有子views,但是它從來不測量它們。而是根據他自身的layout法則,直接設定它們的大小。
-
ContentProvider(樂視)
http://blog.csdn.net/coder_pig/article/details/47858489
https://www.jianshu.com/p/f5ec75a9cfea
-
fragment 生命週期
image.png
-
volley 解析(美團、樂視)
https://www.jianshu.com/p/15e6209d2e6f
-
Android Glide 原始碼解析
http://blog.csdn.net/guolin_blog/article/details/53759439
-
Android 屬性動畫特性(樂視、小米)
https://www.jianshu.com/p/8076fe970a0c
-
Handler 機制及底層實現
http://blog.csdn.net/lmj623565791/article/details/38377229
-
Binder 機制及底層實現
http://blog.csdn.net/weijinqian0/article/details/52233529
Java 基礎
-
介面的意義(百度)
1、重要性:在Java語言中, abstract class 和interface 是支援抽象類定義的兩種機制。正是由於這兩種機制的存在,才賦予了Java強大的 面向物件能力。
2、簡單、規範性:如果一個專案比較龐大,那麼就需要一個能理清所有業務的架構師來定義一些主要的介面,這些介面不僅告訴開發人員你需要實現那些業務,而且也將命名規範限制住了(防止一些開發人員隨便命名導致別的程式設計師無法看明白)。
3、維護、拓展性:比如你要做一個畫板程式,其中裡面有一個面板類,主要負責繪畫功能,然後你就這樣定義了這個類。可是在不久將來,你突然發現這個類滿足不了你了,然後你又要重新設計這個類,更糟糕是你可能要放棄這個類,那麼其他地方可能有引用他,這樣修改起來很麻煩。
如果你一開始定義一個介面,把繪製功能放在接口裡,然後定義類時實現這個介面,然後你只要用這個介面去引用實現它的類就行了,以後要換的話只不過是引用另一個類而已,這樣就達到維護、拓展的方便性。
4、安全、嚴密性:介面是實現軟體鬆耦合的重要手段,它描敘了系統對外的所有服務,而不涉及任何具體的實現細節。這樣就比較安全、嚴密一些(一般軟體服務商考慮的比較多)。
-
抽象類的意義(樂視)
抽象類往往用來表徵對問題領域進行分析、設計中得出的抽象概念,是對一系列看上去不同,但是本質上相同的具體概念的抽象。具體分析如下:
1.因為抽象類不能例項化物件,所以必須要有子類來實現它之後才能使用。這樣就可以把一些具有相同屬性和方法的元件進行抽象,這樣更有利於程式碼和程式的維護。
2.當又有一個具有相似的元件產生時,只需要實現該抽象類就可以獲得該抽象類的那些屬性和方法。
-
內部類的作用(百度,樂視)
定義:放在一個類的內部的類我們就叫內部類。
作用:
1.內部類可以很好的實現隱藏,一般的非內部類,是不允許有 private 與protected許可權的,但內部類可以
2.內部類擁有外圍類的所有元素的訪問許可權
3.可是實現多重繼承
4.可以避免修改介面而實現同一個類中兩種同名方法的呼叫。
-
父類的靜態方法能否被子類重寫,為什麼?(獵豹)
父類的靜態方法是不能被子類重寫的,其實重寫只能適用於例項方法,不能用於靜態方法,對於上面這種靜態方法而言,我們應該稱之為隱藏。
Java靜態方法形式上可以重寫,但從本質上來說不是Java的重寫。因為靜態方法只與類相關,不與具體實現相關。宣告的是什麼類,則引用相應類的靜態方法(本來靜態無需宣告,可以直接引用)。並且static方法不是後期繫結的,它在編譯期就綁定了。換句話說,這個方法不會進行多型的判斷,只與宣告的類有關。
-
舉 1-2 個排序演算法,並使用 java 程式碼實現(美團)
-
列舉 java 的集合和繼承關係(百度、美團)
-
java 虛擬機器的特性(百度、樂視)
Java語言的一個非常重要的特點就是與平臺的無關性。而使用Java虛擬機器是實現這一特點的關鍵。一般的高階語言如果要在不同的平臺上執行,至少需要編譯成不同的目的碼。而引入Java語言虛擬機器後,Java語言在不同平臺上執行時不需要重新編譯。Java語言使用模式Java虛擬機器遮蔽了與具體平臺相關的資訊,使得Java語言編譯程式只需生成在Java虛擬機器上執行的目的碼(位元組碼),就可以在多種平臺上不加修改地執行。Java虛擬機器在執行位元組碼時,把位元組碼解釋成具體平臺上的機器指令執行。
-
哪些情況下的物件會被垃圾回收機制處理掉(樂視、美團、小米)
Java 垃圾回收機制最基本的做法是分代回收。記憶體中的區域被劃分成不同的世代,物件根據其存活的時間被儲存在對應世代的區域中。一般的實現是劃分成3個世代:年輕、年老和永久。記憶體的分配是發生在年輕世代中的。當一個物件存活時間足夠長的時候,它就會被複制到年老世代中。對於不同的世代可以使用不同的垃圾回收演算法。進行世代劃分的出發點是對應用中物件存活時間進行研究之後得出的統計規律。一般來說,一個應用中的大部分物件的存活時間都很短。比如區域性變數的存活時間就只在方法的執行過程中。基於這一點,對於年輕世代的垃圾回收演算法就可以很有針對性。
(1)超出物件的引用控制代碼的作用域時,這個引用控制代碼引用的物件就變成垃圾。(2)沒有超出物件的引用控制代碼的作用域時,給這個引用控制代碼賦值為空時,這個引用控制代碼引用的物件就變成垃圾。
(3)建立匿名物件時,匿名物件用完以後即成垃圾。
-
程序和執行緒的區別(獵豹)
程序和執行緒都是一個時間段的描述,是CPU工作時間段的描述,不過是顆粒大小不同。
簡而言之,一個程式至少有一個程序,一個程序至少有一個執行緒.
執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高。
另外,程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率。
執行緒在執行過程中與程序還是有區別的。每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。
從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個執行緒看做多個獨立的應用,來實現程序的排程和管理以及資源分配。這就是程序和執行緒的重要區別。
-
Java 中==和 equals 的區別, equals 和 hashCode 的區別(樂視)
http://blog.csdn.net/tiantiandjava/article/details/46988461
-
ArrayList 和 HashMap 的實現原理(美團,百度)
https://www.jianshu.com/p/f174d49b391c
-
java 中 int char long 各佔多少位元組數
short 2個位元組
int 4個位元組
long 8個位元組
-
java int 與 integer 的區別
http://blog.csdn.net/chenliguan/article/details/53888018
-
string stringbuffer stringbuilder 區別(小米、樂視、百度)
String:適用於少量的字串操作的情況
StringBuilder:適用於單執行緒下在字元緩衝區進行大量操作的情況(非執行緒安全)
StringBuffer:適用多執行緒下在字元緩衝區進行大量操作的情況(執行緒安全)
在大部分情況下 StringBuilder > StringBuffer
https://www.cnblogs.com/su-feng/p/6659064.html
Java 多型(樂視)
http://blog.csdn.net/Jian_Yun_Rui/article/details/52937791什麼導致執行緒阻塞(58、美團)
http://blog.csdn.net/sinat_22013331/article/details/45740641抽象類介面區別(360)
https://www.cnblogs.com/yongjiapei/p/5494894.html容器類之間的區別(樂視、美團)
https://www.cnblogs.com/sunliming/archive/2011/04/05/2005957.htmlJava 中 HashMap 和 HashTable 的區別(樂視、小米)
https://www.cnblogs.com/lchzls/p/6714335.html
http://blog.csdn.net/u012050154/article/details/50905364ArrayMap VS HashMap
http://blog.csdn.net/vansbelove/article/details/52422087
資料結構與演算法
-
堆和棧在記憶體中的區別是什麼(資料結構方面以及實際實現方面)
-
最快的排序演算法是哪個?給阿里 2 萬多名員工按年齡排序應該選擇哪個演算法?堆和樹的區別;寫出快排程式碼;連結串列逆序程式碼(阿里)
-
求 1000 以內的水仙花數以及 40 億以內的水仙花數(百度)
-
子串包含問題(KMP 演算法)寫程式碼實現
-
萬億級別的兩個 URL 檔案 A 和 B,如何求出 A 和 B 的差集 C,(Bit 對映->hash 分組->多檔案讀寫效率->磁碟定址以及應用層面對定址的優化)
-
蟻群演算法與蒙特卡洛演算法
-
寫出你所知道的排序演算法及時空複雜度,穩定性(小米)
其他
-
死鎖的四個必要條件
1)互斥條件,即某個資源在一段時間內只能由一個執行緒佔有,不能同時被兩個或兩個以上的執行緒佔有
2)不可搶佔條件,執行緒所獲得的資源在未使用完畢之前,資源申請者不能強行地從資源佔有者手中奪取資源,而只能由該資源的佔有者執行緒自行釋放
3)佔有且申請條件,執行緒至少已經佔有一個資源,但又申請新的資源;由於該資源已被另外執行緒佔有,此時該執行緒阻塞;但是,它在等待新資源之時,仍繼續佔用已佔有的資源。
4)迴圈等待條件,存在一個執行緒等待序列{P1,P2,…,Pn},其中P1等待P2所佔有的某一資源,P2等待P3所佔有的某一源,……,而Pn等待P1所佔有的的某一資源,形成一個執行緒迴圈等待環
解決死鎖的辦法:加鎖順序,死鎖檢測
-
常見編碼方式; utf-8 編碼中的中文佔幾個位元組;數字幾個位元組
一個utf8數字佔1個位元組,一個utf8英文字母佔1個位元組,少數是漢字每個佔用3個位元組,多數佔用4個位元組。
-
實現一個 Json 解析器(可以通過正則提高速度)
1String json = "{name:\"jason\",father:\"jason\",age:18}";
2//name:"jason"
3//age:18
4//\"\\w+\" 字串屬性
5Pattern p = Pattern.compile("\\w+:(\"\\w+\"|\\d*)");
6Matcher m = p.matcher(json);
7while(m.find()){
8 String text = m.group();
9 int dotPos= text.indexOf(":");
10 String key = text.substring(0, dotPos);
11 String value = text.substring(dotPos+1, text.length());
12 //替換字串的開始結束的雙引號
13 value = value.replaceAll("^\\\"|\\\"$", "");
14 System.out.println(key);
15 System.out.println(value);
16}
-
Android App 的設計架構: MVC,MVP,MVVM 與架構經驗談(搜狐)
-
寫出觀察者模式的程式碼
-
TCP 的 3 次握手和四次揮手; TCP 與 UDP 的區別
http://blog.csdn.net/whuslei/article/details/6667471
1、TCP面向連線(如打電話要先撥號建立連線);UDP是無連線的,即傳送資料之前不需要建立連線
2、TCP提供可靠的服務。也就是說,通過TCP連線傳送的資料,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付
3、TCP面向位元組流,實際上是TCP把資料看成一連串無結構的位元組流;UDP是面向報文的
UDP沒有擁塞控制,因此網路出現擁塞不會使源主機的傳送速率降低(對實時應用很有用,如IP電話,實時視訊會議等)
4、每一條TCP連線只能是點到點的;UDP支援一對一,一對多,多對一和多對多的互動通訊
5、TCP首部開銷20位元組;UDP的首部開銷小,只有8個位元組
6、TCP的邏輯通訊通道是全雙工的可靠通道,UDP則是不可靠通道
-
HTTP 協議; HTTP1.0 與 2.0 的區別;HTTP 報文結構
-
HTTP 與 HTTPS 的區別以及如何實現安全性
https://www.jianshu.com/p/be7a20cc8468
獲取更多資料加qq群:853967238