1. 程式人生 > >親愛的面試官,這個我可沒看過!(Android部分)

親愛的面試官,這個我可沒看過!(Android部分)

如何保證Service不被殺死

Android 程序不死從3個層面入手:

  • A.提供程序優先順序,降低程序被殺死的概率
    方法一:監控手機鎖屏解鎖事件,在螢幕鎖屏時啟動1個畫素的 Activity,在使用者解鎖時將 Activity 銷燬掉。
    方法二:啟動前臺service。
    方法三:提升service優先順序:
    在AndroidManifest.xml檔案中對於intent-filter可以通過android:priority = "1000"這個屬性設定最高優先順序,1000是最高值,如果數字越小則優先順序越低,同時適用於廣播。
  • B. 在程序被殺死後,進行拉活
    方法一:註冊高頻率廣播接收器,喚起程序。如網路變化,解鎖螢幕,開機等
    方法二:雙程序相互喚起。
    方法三:依靠系統喚起。
    方法四:onDestroy方法裡重啟service:service +broadcast 方式,就是當service走ondestory的時候,傳送一個自定義的廣播,當收到廣播的時候,重新啟動service;
  • C. 依靠第三方
    根據終端不同,在小米手機(包括 MIUI)接入小米推送、華為手機接入華為推送;其他手機可以考慮接入騰訊信鴿或極光推送與小米推送做 A/B Test。

ButterKnife原理
ButterKnife對效能的影響很小,因為沒有使用使用反射,而是使用的Annotation Processing Tool(APT),註解處理器,javac中用於編譯時掃描和解析Java註解的工具。在編譯階段執行的,它的原理就是讀入Java原始碼,解析註解,然後生成新的Java程式碼。新生成的Java程式碼最後被編譯成Java位元組碼,註解解析器不能改變讀入的Java 類,比如不能加入或刪除Java方法。

基礎

Activity和Fragment生命週期有哪些?


螢幕快照 2016-09-19 下午8.10.27.png

橫豎屏切換時候Activity的生命週期

不設定Activity的android:configChanges時,切屏會重新回掉各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次
設定Activity的android:configChanges=”orientation”時,切屏還是會呼叫各個生命週期,切換橫豎屏只會執行一次
設定Activity的android:configChanges=”orientation |keyboardHidden”時,切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法

AsyncTask
原始碼解析
AsyncTask的缺陷和問題
關於執行緒池:asynctask對應的執行緒池ThreadPoolExecutor都是程序範圍內共享的,都是static的,所以是asynctask控制著程序範圍內所有的子類例項。由於這個限制的存在,當使用預設執行緒池時,如果執行緒數超過執行緒池的最大容量,執行緒池就會爆掉(3.0後預設序列執行,不會出現這個問題)。針對這種情況,可以嘗試自定義執行緒池,配合asynctask使用。

關於預設執行緒池:核心執行緒池中最多有CPU_COUNT+1個,最多有CPU_COUNT*2+1個,執行緒等待佇列的最大等待數為128,但是可以自定義執行緒池。執行緒池是由AsyncTask來管理的,執行緒池允許tasks並行執行,需要注意的是併發情況下資料的一致性問題,新資料可能會被老資料覆蓋掉,類似volatile變數。所以希望tasks能夠序列執行的話,使用SERIAL_EXECUTOR。

AsyncTask在不同的SDK版本中的區別:
呼叫AsyncTask的excute方法不能立即執行程式的原因分析及改善方案
通過查閱官方文件發現,AsyncTask首次引入時,非同步任務是在一個獨立的執行緒中順序的執行,也就是說一次只能執行一個任務,不能並行的執行,從1.6開始,AsyncTask引入了執行緒池,支援同時執行5個非同步任務,也就是說同時只能有5個執行緒執行,超過的執行緒只能等待,等待前面的執行緒某個執行完了才被排程和執行。換句話說,如果一個程序中的AsyncTask例項個數超過5個,那麼假如前5個都執行很長時間的話,那麼第6個只能等待機會了。這是AsyncTask的一個限制,而且對於2.3以前的版本無法解決。如果你的應用需要大量的後臺執行緒去執行任務,那麼你只能放棄使用AsyncTask,自己建立執行緒池來管理Thread。不得不說,雖然AsyncTask較Thread使用起來方便,但是它最多隻能同時執行5個執行緒,這也大大侷限了它的實力,你必須要小心設計你的應用,錯開使用AsyncTask的時間,盡力做到分時,或者保證數量不會大於5個,否則就會遇到上次提到的問題。可能是Google意識到了AsyncTask的侷限性了,從Android3.0開始對AsyncTask的API作出了一些調整:每次只啟動一個執行緒執行一個任務,完成之後再執行第二個任務,也就是相當於只有一個後臺執行緒在執行所提交的任務。

  • 1.生命週期
    很多開發者會認為一個在Activity中建立的AsyncTask會隨著Activity的銷燬而銷燬。然而事實並非如此。AsyncTask會一直執行,直到doInBackground()方法執行完畢。然後,如果cancel(boolean)被呼叫,那麼onCancelled(Result result)方法會被執行;否則,執行onPostExecute(Result result)方法。如果我們的Activity銷燬之前,沒有取消AsyncTask,這有可能讓我們的AsyncTask崩潰(crash)。因為它想要處理的view已經不在了。所以,我們總是必須確保在銷燬活動之前取消任務。總之,我們使用AsyncTask需要確保AsyncTask正確的取消。
  • 2.記憶體洩漏
    如果AsyncTask被宣告為Activity的非靜態的內部類,那麼AsyncTask會保留一個對Activity的引用。如果Activity已經被銷燬,AsyncTask的後臺執行緒還在執行,它將繼續在記憶體裡保留這個引用,導致Activity無法被回收,引起記憶體洩漏。
  • 3.結果丟失
    螢幕旋轉或Activity在後臺被系統殺掉等情況會導致Activity的重新建立,之前執行的AsyncTask會持有一個之前Activity的引用,這個引用已經無效,這時呼叫onPostExecute()再去更新介面將不再生效。
  • 4.並行還是序列
    在Android1.6之前的版本,AsyncTask是序列的,在1.6至2.3的版本,改成了並行的。在2.3之後的版本又做了 修改,可以支援並行和序列,當想要序列執行時,直接執行execute()方法,如果需要執行executeOnExecutor(Executor)。

Acitivty的任務棧

使用android:launchMode="standard|singleInstance|single Task|singleTop"來控制Acivity任務棧。

任務棧是一種後進先出的結構。位於棧頂的Activity處於焦點狀態,當按下back按鈕的時候,棧內的Activity會一個一個的出棧,並且呼叫其onDestory()方法。如果棧內沒有Activity,那麼系統就會回收這個棧,每個APP預設只有一個棧,以APP的包名來命名.

  • standard : 標準模式,每次啟動Activity都會建立一個新的Activity例項,並且將其壓入任務棧棧頂,而不管這個Activity是否已經存在。Activity的啟動三回撥(onCreate()->onStart()->onResume())都會執行。
  • singleTop : 棧頂複用模式.這種模式下,如果新Activity已經位於任務棧的棧頂,那麼此Activity不會被重新建立,所以它的啟動三回撥就不會執行,同時Activity的onNewIntent()方法會被回撥.如果Activity已經存在但是不在棧頂,那麼作用於standard模式一樣.
  • singleTask: 棧內複用模式.建立這樣的Activity的時候,系統會先確認它所需任務棧已經建立,否則先建立任務棧.然後放入Activity,如果棧中已經有一個Activity例項,那麼這個Activity就會被調到棧頂,onNewIntent(),並且singleTask會清理在當前Activity上面的所有Activity.(clear top)
  • singleInstance : 加強版的singleTask模式,這種模式的Activity只能單獨位於一個任務棧內,由於棧內複用的特性,後續請求均不會建立新的Activity,除非這個獨特的任務棧被系統銷燬了
    Activity的堆疊管理以ActivityRecord為單位,所有的ActivityRecord都放在一個List裡面.可以認為一個ActivityRecord就是一個Activity棧

onSaveInstanceState() 與onRestoreIntanceState()
使用者或者程式設計師主動去銷燬一個Activity的時候不會掉用,其他情況都會調動,來儲存介面資訊。如程式碼中finish()或使用者按下back,不會掉用。

android中程序的優先順序?

  • 前臺程序:即與使用者正在互動的Activity或者Activity用到的Service等,如果系統記憶體不足時前臺程序是最後被殺死的
  • 可見程序:可以是處於暫停狀態(onPause)的Activity或者繫結在其上的Service,即被使用者可見,但由於失去了焦點而不能與使用者互動
  • 服務程序:其中執行著使用startService方法啟動的Service,雖然不被使用者可見,但是卻是使用者關心的,例如使用者正在非音樂介面聽的音樂或者正在非下載頁面自己下載的檔案等;當系統要空間執行前兩者程序時才會被終止
  • 後臺程序:其中執行著執行onStop方法而停止的程式,但是卻不是使用者當前關心的,例如後臺掛著的QQ,這樣的程序系統一旦沒了有記憶體就首先被殺死
  • 空程序:不包含任何應用程式的程式元件的程序,這樣的程序系統是一般不會讓他存在的

Serializable和Parcelable
序列化,表示將一個物件轉換成可儲存或可傳輸的狀態。序列化後的物件可以在網路上進行傳輸,也可以儲存到本地。

  • Serializable(Java自帶):
    Serializable是序列化的意思,表示將一個物件轉換成可儲存或可傳輸的狀態。序列化後的物件可以在網路上進行傳輸,也可以儲存到本地。
  • Parcelable(android 專用):
    除了Serializable之外,使用Parcelable也可以實現相同的效果,
    不過不同於將物件進行序列化,Parcelable方式的實現原理是將一個完整的物件進行分解,
    而分解後的每一部分都是Intent所支援的資料型別,這樣也就實現傳遞物件的功能了。

動畫

  • tween 補間動畫。通過指定View的初末狀態和變化時間、方式,對View的內容完成一系列的圖形變換來實現動畫效果。 Alpha, Scale ,Translate, Rotate。
  • frame 幀動畫 AnimationDrawable 控制 animation-list xml佈局
  • PropertyAnimation 屬性動畫 3.0引入,屬性動畫核心思想是對值的變化。

屬性動畫
詳解

Property Animation 動畫有兩個步聚:
1.計算屬性值
2.為目標物件的屬性設定屬性值,即應用和重新整理動畫


valuecaculate.png


計算屬性分為3個過程:

  • 過程一:計算已完成動畫分數 elapsed fraction 為了執行一個動畫,你需要建立一個 ValueAnimator,並且指定目標物件屬性的開始、結束值和持續時間。在呼叫 start 後的整個動畫過程中, ValueAnimator 會根據已經完成的動畫時間計算得到一個 0 到 1 之間的分數,代表該動畫的已完成動畫百分比。0 表示 0%,1 表示 100%。
  • 過程二:計算插值(動畫變化率)interpolated fraction 當 ValueAnimator 計算完已完成動畫分數後,它會呼叫當前設定的 TimeInterpolator,去計算得到一個 interpolated(插值)分數,在計算過程中,已完成動畫百分比會被加入到新的插值計算中。
  • 過程三:計算屬性值 當插值分數計算完成後,ValueAnimator 會根據插值分數呼叫合適的 TypeEvaluator 去計算運動中的屬性值。
    以上分析引入了兩個概念:已完成動畫分數(elapsed fraction)、插值分數( interpolated fraction )。

Android的資料儲存形式

  • SQLite:SQLite是一個輕量級的資料庫,支援基本的SQL語法,是常被採用的一種資料儲存方式。 Android為此資料庫提供了一個名為SQLiteDatabase的類,封裝了一些操作資料庫的api
  • SharedPreference: 以鍵值對的形勢儲存。其本質就是一個xml檔案,常用於儲存較簡單的引數設定。
  • File: 即常說的檔案(I/O)儲存方法,常用語儲存大數量的資料,但是缺點是更新資料將是一件困難的事情。
  • ContentProvider: Android系統中能實現所有應用程式共享的一種資料儲存方式,由於資料通常在各應用間的是互相私密的,所以此儲存方式較少使用,但是其又是必不可少的一種儲存方式。例如音訊,視訊,圖片和通訊錄,一般都可以採用此種方式進行儲存。每個Content Provider都會對外提供一個公共的URI(包裝成Uri物件),如果應用程式有資料需要共享時,就需要使用Content Provider為這些資料定義一個URI,然後其他的應用程式就通過Content Provider傳入這個URI來對資料進行操作。

Context相關

Activity和Service以及Application的Context是不一樣的,Activity繼承自ContextThemeWraper.其他的繼承自ContextWrapper.
每一個Activity和Service以及Application的Context都是一個新的ContextImpl物件
getApplication()用來獲取Application例項的,但是這個方法只有在Activity和Service中才能呼叫的到。那麼也許在絕大多數情況下我們都是在Activity或者Service中使用Application的,但是如果在一些其它的場景,比如BroadcastReceiver中也想獲得Application的例項,這時就可以藉助getApplicationContext()方法,getApplicationContext()比getApplication()方法的作用域會更廣一些,任何一個Context的例項,只要呼叫getApplicationContext()方法都可以拿到我們的Application物件。
建立Toast和對話方塊不可以用Application 的context,只能用Activity的context。
Context的數量等於Activity的個數 + Service的個數 + 1,這個1為Application

Android各版本新特性
Android5.0新特性

  • MaterialDesign設計風格
  • 支援多種裝置
  • 支援64位ART虛擬機器

Android6.0新特性

  • 大量漂亮流暢的動畫
  • 支援快速充電的切換
  • 支援資料夾拖拽應用
  • 相機新增專業模式

Android7.0新特性

  • 分屏多工
  • 增強的Java8語言模式
  • 夜間模式

Json

  • JSON的全程是JavaScript Object Notation,也就是JavaScript 物件表示法
  • JSON是儲存和交換文字資訊的語法,類似XML,但是比XML更小、更快,更易解析
  • JSON是輕量級的文字資料交換格式,獨立於語言,具有自我描述性,更易理解

物件可以包含多個名稱/值對,比如:

{"name":"zhangsan" , "age":25}

使用谷歌的GSON包進行解析
在 Android Studio 裡引入依賴:

compile 'com.google.code.gson:gson:2.7'

值得注意的是實體類中變數名稱必須和json中的值名相同。
json1的解析
我們這裡的實體類是Student.class

Gson gson = new Gson();
Student student = gson.fromJson(json1, Student.class);

json2的解析
我們可以解析成int陣列,也可以解析成Integer的List。
解析成陣列:

Gson gson = new Gson();
int[] ages = gson.fromJson(json2, int[].class);
解析成List:

Gson gson = new Gson();
List<Integer> ages = gson.fromJson(json2, new TypeToken<List<Integer>>(){}.getType);

json3的解析
同樣可以解析成List或者陣列,我們就直接解析成List.

Gson gson = new Gson();
List<Student> students = gson.fromJson(json3, new TypeToke<List<Student>>(){}.getType);

android中有哪幾種解析xml的類,官方推薦哪種?以及它們的原理和區別

  • DOM解析

    優點:
    1.XML樹在記憶體中完整儲存,因此可以直接修改其資料和結構.
    2.可以通過該解析器隨時訪問XML樹中的任何一個節點.
    3.DOM解析器的API在使用上也相對比較簡單.
    缺點:如果XML文件體積比較大時,將文件讀入記憶體是非常消耗系統資源的.
    使用場景:DOM 是用與平臺和語言無關的方式表示 XML 文件的官方 W3C 標準.DOM 是以層次結構組織的節點的集合.這個層次結構允許開發人員在樹中尋找特定資訊.分析該結構通常需要載入整個文件和構造層次結構,然後才能進行任何工作.DOM是基於物件層次結構的.

  • SAX解析

    優點:
    SAX 對記憶體的要求比較低,因為它讓開發人員自己來決定所要處理的標籤.特別是當開發人員只需要處理文件中所包含的部分資料時,SAX 這種擴充套件能力得到了更好的體現.
    缺點:
    用SAX方式進行XML解析時,需要順序執行,所以很難訪問到同一文件中的不同資料.此外,在基於該方式的解析編碼過程也相對複雜.
    使用場景:
    對於含有資料量十分巨大,而又不用對文件的所有資料進行遍歷或者分析的時候,使用該方法十分有效.該方法不用將整個文件讀入記憶體,而只需讀取到程式所需的文件標籤處即可.

  • Xmlpull解析

    android SDK提供了xmlpull api,xmlpull和sax類似,是基於流(stream)操作檔案,然後根據節點事件回撥開發者編寫的處理程式.因為是基於流的處理,因此xmlpull和sax都比較節約記憶體資源,不會象dom那樣要把所有節點以對橡樹的形式展現在記憶體中.xmlpull比sax更簡明,而且不需要掃描完整個流.

Jar和Aar的區別

Jar包裡面只有程式碼,aar裡面不光有程式碼還包括程式碼還包括資原始檔,比如 drawable 檔案,xml 資原始檔。對於一些不常變動的 Android Library,我們可以直接引用 aar,加快編譯速度

什麼是三級快取

  • 網路載入,不優先載入,速度慢,浪費流量
  • 本地快取,次優先載入,速度快
  • 記憶體快取,優先載入,速度最快

三級快取原理

首次載入 Android App 時,肯定要通過網路互動來獲取圖片,之後我們可以將圖片儲存至本地SD卡和記憶體中
之後執行 App 時,優先訪問記憶體中的圖片快取,若記憶體中沒有,則載入本地SD卡中的圖片
總之,只在初次訪問新內容時,才通過網路獲取圖片資源

Android為每個應用程式分配的記憶體大小是多少
android程式記憶體一般限制在16M,也有的是24M

更新UI方式
Activity.runOnUiThread(Runnable)
View.post(Runnable),View.postDelay(Runnable,long)
Handler
AsyncTask

進階

引起記憶體洩漏的情況

  • 對於使用了BraodcastReceiver,ContentObserver,File,遊標 Cursor,Stream,Bitmap等資源的使用,應該在Activity銷燬時及時關閉或者登出。
  • 靜態內部類持有外部成員變數(或context):可以使用弱引用或使用ApplicationContext。
  • 內部類持有外部類引用,非同步任務中,持有外部成員變數。
  • 集合中沒用的物件沒有及時remove。
  • 不用的物件及時釋放,如使用完Bitmap後掉用recycle(),再賦null。
  • handler引起的記憶體洩漏,MessageQueue裡的訊息如果在activity銷燬時沒有處理完,就會引起記憶體的洩漏,可以使用弱引用解決。
  • 構造Adapter時,沒有使用快取的convertView。
  • 設定過的監聽不用時,及時移除。如在Destroy時及時remove。尤其以addListener開頭的,在Destroy中都需要remove。
  • activity洩漏可以使用LeakCanary。
  • 在記憶體引用上做些處理,常用的有軟引用、弱引用
  • 在記憶體中載入圖片時直接在記憶體中作處理,如:邊界壓縮
  • 動態回收記憶體
  • 優化Dalvik虛擬機器的堆記憶體分配
  • 自定義堆記憶體大小

Activity/Window/View三者的差別,fragment的特點

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的生命週期影響。

JVM 和Dalvik虛擬機器的區別

  • JVM:
    .java -> javac -> .class -> jar -> .jar
    架構: 堆和棧的架構.
  • DVM:
    .java -> javac -> .class -> dx.bat -> .dex
    架構: 暫存器(cpu上的一塊快取記憶體)

怎麼考慮資料傳輸的安全性
如果應用對傳輸的資料沒有任何安全措施,攻擊者設定的釣魚網路中更改DNS伺服器。這臺伺服器可以獲取使用者資訊,或充當中間人與原伺服器交換資料。在SSL/TLS通訊中,客戶端通過數字證書判斷伺服器是否可信,並採用證書的公鑰與伺服器進行加密通訊。

自定義View的相關方法
1.自定義屬性
2.onLayout(Viewgroup)
3.onMesure
4.onDraw
5.互動:
onIntercepterTouchEvent()
onTouchEvent()

事件傳遞機制 詳解
當手指觸控到螢幕時,系統就會呼叫相應View的onTouchEvent,並傳入一系列的action。

dispatchTouchEvent的執行順序為:

首先觸發ACTIVITY的dispatchTouchEvent,然後觸發ACTIVITY的onInterceptTouchEvent.
然後觸發LAYOUT的dispatchTouchEvent,然後觸發LAYOUT的onInterceptTouchEvent
這就解釋了重寫ViewGroup時必須呼叫super.dispatchTouchEvent();

(1)dispatchTouchEvent:

此方法一般用於初步處理事件,因為動作是由此分發,所以通常會呼叫super.dispatchTouchEvent。這樣就會繼續呼叫onInterceptTouchEvent,再由onInterceptTouchEvent決定事件流向。

(2)onInterceptTouchEvent:

若返回值為true事件會傳遞到自己的onTouchEvent();若返回值為false傳遞到下一個View的dispatchTouchEvent();

(3)onTouchEvent():

若返回值為true,事件由自己消耗,後續動作讓其處理;若返回值為false,自己不消耗事件了,向上返回讓其他的父View的onTouchEvent接受處理

三大方法關係的虛擬碼:如果當前View攔截事件,就交給自己的onTouchEvent去處理,否則就丟給子View繼續走相同的流程。

public boolean dispatchTouchEvent(MotionEvent ev)
{
    boolean consume = false;
    if(onInterceptTouchEvent(ev))
    {
        consume = onTouchEvent(ev);
    }
    else
    {
        consume = child.dispatchTouchEvent(ev);
    }
    return consume;
}

onTouchEvent的傳遞:

當有多個層級的View時,在父層級允許的情況下,這個action會一直傳遞直到遇到最深層的View。所以touch事件最先呼叫的是最底層View的onTouchEvent,如果View的onTouchEvent接收到某個touch action並做了相應處理,最後有兩種返回方式return true和return false;return true會告訴系統當前的View需要處理這次的touch事件,以後的系統發出的ACTION_MOVE,ACTION_UP還是需要繼續監聽並接收的,並且這次的action已經被處理掉了,父層的View是不可能觸發onTouchEvent的了。所以每一個action最多隻能有一個onTouchEvent介面返回true。如果返回false,便會通知系統,當前View不關心這一次的touch事件,此時這個action會傳向父級,呼叫父級View的onTouchEvent。但是這一次的touch事件之後發出任何action,該View都不在接受,onTouchEvent在這一次的touch事件中再也不會觸發,也就是說一旦View返回false,那麼之後的ACTION_MOVE,ACTION_UP等ACTION就不會在傳入這個View,但是下一次touch事件的action還是會傳進來的。

父層的onInterceptTouchEvent

前面說了底層的View能夠接收到這次的事件有一個前提條件:在父層允許的情況下。假設不改變父層級的dispatch方法,在系統呼叫底層onTouchEvent之前會呼叫父View的onInterceptTouchEvent方法判斷,父層View是否要截獲本次touch事件之後的action。如果onInterceptTouchEvent返回了true,那麼本次touch事件之後的所有action都不會向深層的View傳遞,統統都會傳給父層View的onTouchEvent,就是說父層已經截獲了這次touch事件,之後的action也不必詢問onInterceptTouchEvent,在這次的touch事件之後發出的action時onInterceptTouchEvent不會再被呼叫,直到下一次touch事件的來臨。如果onInterceptTouchEvent返回false,那麼本次action將傳送給更深層的View,並且之後的每一次action都會詢問父層的onInterceptTouchEvent需不需要截獲本次touch事件。只有ViewGroup才有onInterceptTouchEvent方法,因為一個普通的View肯定是位於最深層的View,touch能夠傳到這裡已經是最後一站了,肯定會呼叫View的onTouchEvent()。

底層View的getParent().requestDisallowInterceptTouchEvent(true)

對於底層的View來說,有一種方法可以阻止父層的View獲取touch事件,就是呼叫getParent().requestDisallowInterceptTouchEvent(true)方法。一旦底層View收到touch的action後呼叫這個方法那麼父層View就不會再呼叫onInterceptTouchEvent了,也無法截獲以後的action(如果父層ViewGroup和最底層View需要截獲不同焦點,或不同手勢的touch,不能使用這個寫死)。

ART和Dalvik區別

art上應用啟動快,執行快,但是耗費更多儲存空間,安裝時間長,總的來說ART的功效就是”空間換時間”。

ART: Ahead of Time
Dalvik: Just in Time

什麼是Dalvik:Dalvik是Google公司自己設計用於Android平臺的Java虛擬機器。Dalvik虛擬機器是Google等廠商合作開發的Android移動裝置平臺的核心組成部分之一,它可以支援已轉換為.dex(即Dalvik Executable)格式的Java應用程式的執行,.dex格式是專為Dalvik應用設計的一種壓縮格式,適合記憶體和處理器速度有限的系統。Dalvik經過優化,允許在有限的記憶體中同時執行多個虛擬機器的例項,並且每一個Dalvik應用作為獨立的Linux程序執行。獨立的程序可以防止在虛擬機器崩潰的時候所有程式都被關閉。

什麼是ART:Android作業系統已經成熟,Google的Android團隊開始將注意力轉向一些底層元件,其中之一是負責應用程式執行的Dalvik執行時。Google開發者已經花了兩年時間開發更快執行效率更高更省電的替代ART執行時。ART代表Android Runtime,其處理應用程式執行的方式完全不同於Dalvik,Dalvik是依靠一個Just-In-Time(JIT)編譯器去解釋位元組碼。開發者編譯後的應用程式碼需要通過一個直譯器在使用者的裝置上執行,這一機制並不高效,但讓應用能更容易在不同硬體和架構上執行。ART則完全改變了這套做法,在應用安裝的時候就預編譯位元組碼到機器語言,這一機制叫Ahead-Of-Time(AOT)編譯。在移除解釋程式碼這一過程後,應用程式執行將更有效率,啟動更快。

ART優點:

系統性能的顯著提升
應用啟動更快、執行更快、體驗更流暢、觸感反饋更及時。
更長的電池續航能力
支援更低的硬體

ART缺點:
更大的儲存空間佔用,可能會增加10%-20%
更長的應用安裝時間

Scroller原理

Scroller執行流程裡面的三個核心方法

mScroller.startScroll()
mScroller.computeScrollOffset()
view.computeScroll()
1、在mScroller.startScroll()中為滑動做了一些初始化準備,比如:起始座標,滑動的距離和方向以及持續時間(有預設值),動畫開始時間等。

2、mScroller.computeScrollOffset()方法主要是根據當前已經消逝的時間來計算當前的座標點。因為在mScroller.startScroll()中設定了動畫時間,那麼在computeScrollOffset()方法中依據已經消逝的時間就很容易得到當前時刻應該所處的位置並將其儲存在變數mCurrX和mCurrY中。除此之外該方法還可判斷動畫是否已經結束。

webView.addJavaScriptInterface(new Object(){xxx}, "xxx");
1
答案:可以使用WebView控制元件執行JavaScript指令碼,並且可以在JavaScript中執行Java程式碼。要想讓WebView控制元件執行JavaScript,需要呼叫WebSettings.setJavaScriptEnabled方法,程式碼如下:

WebView webView = (WebView)findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
//設定WebView支援JavaScript
webSettings.setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());

JavaScript呼叫Java方法需要使用WebView.addJavascriptInterface方法設定JavaScript呼叫的Java方法,程式碼如下:

webView.addJavascriptInterface(new Object()
{
    //JavaScript呼叫的方法
    public String process(String value)
    {
        //處理程式碼
        return result;
    }
}, "demo");       //demo是Java物件對映到JavaScript中的物件名

可以使用下面的JavaScript程式碼呼叫process方法,程式碼如下:

<script language="javascript">
    function search()
    {
        //呼叫searchWord方法
        result.innerHTML = "<font color='red'>" + window.demo.process('data') + "</font>";
    }

SurfaceView和View的最本質的區別

SurfaceView是在一個新起的單獨執行緒中可以重新繪製畫面,而view必須在UI的主執行緒中更新畫面。

在UI的主執行緒中更新畫面可能會引發問題,比如你更新的時間過長,那麼你的主UI執行緒就會被你正在畫的函式阻塞。那麼將無法響應按鍵、觸屏等訊息。當使用SurfaceView由於是在新的執行緒中更新畫面所以不會阻塞你的UI主執行緒。但這也帶來了另外一個問題,就是事件同步。比如你觸屏了一下,你需要SurfaceView中thread處理,一般就需要有一個event queue的設計來儲存touchevent,這會稍稍複雜一點,因為涉及到執行緒安全。
常用的設計模式
單例,介面卡,策略模式等常用的設計模式需要掌握

單例
public class Singleton{  
private volatile static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
  if(mSingleton == null){\\A
    synchronized(Singleton.class){\\C
     if(mSingleton == null)
      mSingleton = new Singleton();\\B
      }
    }
    return mSingleton;
  }
}

ANR排錯

1、ANR排錯一般有三種情況

  • KeyDispatchTimeout(5 seconds) –主要型別按鍵或觸控事件在特定時間內無響應
  • BroadcastTimeout(10 secends) –BroadcastReceiver在特定時間內無法處理完成
  • ServiceTimeout(20 secends) –小概率事件 Service在特定的時間內無法處理完成
    發生原因
    主執行緒被IO操作(從4.0之後網路IO不允許在主執行緒中)阻塞。
    主執行緒中存在耗時的計算
    主執行緒中錯誤的操作,比如Thread.wait或者Thread.sleep等 Android系統會監控程式的響應狀況
    使用AsyncTask處理耗時IO操作。

2、如何避免

UI執行緒儘量只做跟UI相關的工作
耗時的操作(比如資料庫操作,I/O,連線網路或者別的有可能阻塞UI執行緒的操作)把它放在單獨的執行緒處理
儘量用Handler來處理UIthread和別的thread之間的互動.
使用Thread或者HandlerThread時,呼叫Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)設定優先順序,否則仍然會降低程式響應,因為預設Thread的優先順序和主執行緒相同。
使用Handler處理工作執行緒結果,而不是使用Thread.wait()或者Thread.sleep()來阻塞主執行緒。
Activity的onCreate和onResume回撥中儘量避免耗時的程式碼
BroadcastReceiver中onReceive程式碼也要儘量減少耗時,建議使用IntentService處理。

3、ANR定位和修正
如果開發機器上出現問題,我們可以通過檢視/data/anr/traces.txt即可,最新的ANR資訊在最開始部分。

Android程式執行時許可權與檔案系統許可權
1,Linux 檔案系統許可權。不同的使用者對檔案有不同的讀寫執行許可權。在android系統中,system和應用程式是分開的,system裡的資料是不可更改的。
2,Android中有3種許可權,程序許可權UserID,簽名,應用申明許可權。每次安裝時,系統根據包名為應用分配唯一的userID,不同的userID執行在不同的程序裡,程序間的記憶體是獨立的,不可以相互訪問,除非通過特定的Binder機制。
Android提供瞭如下的一種機制,可以使兩個apk打破前面講的這種壁壘。
在AndroidManifest.xml中利用sharedUserId屬性給不同的package分配相同的userID,通過這樣做,兩個package可以被當做同一個程式,系統會分配給兩個程式相同的UserID。當然,基於安全考慮,兩個package需要有相同的簽名,否則沒有驗證也就沒有意義了。

如何讓程式自動啟動
定義一個Braodcastreceiver,action為BOOT——COMPLETE,接受到廣播後啟動程式。

Handler機制
andriod提供了Handler 和 Looper 來滿足執行緒間的通訊。Handler先進先出原則。Looper類用來管理特定執行緒內物件之間的訊息交換(MessageExchange)。
Looper: 一個執行緒可以產生一個Looper物件,由它來管理此執行緒裡的MessageQueue(訊息佇列)。
Handler: 你可以構造Handler物件來與Looper溝通,以便push新訊息到MessageQueue裡;或者接收Looper從Message Queue取出)所送來的訊息。
Message Queue(訊息佇列):用來存放執行緒放入的訊息。
執行緒:UIthread 通常就是main thread,而Android啟動程式時會替它建立一個MessageQueue。

ListView卡頓原因
Adapter的getView方法裡面convertView沒有使用setTag和getTag方式;
在getView方法裡面ViewHolder初始化後的賦值或者是多個控制元件的顯示狀態和背景的顯示沒有優化好,抑或是裡面含有複雜的計算和耗時操作;
在getView方法裡面 inflate的row 巢狀太深(佈局過於複雜)或者是佈局裡面有大圖片或者背景所致;
Adapter多餘或者不合理的notifySetDataChanged;
listview 被多層巢狀,多次的onMessure導致卡頓,如果多層巢狀無法避免,建議把listview的高和寬設定為fill_parent. 如果是程式碼繼承的listview,那麼也請你別忘記為你的繼承類新增上LayoutPrams,注意高和寬都是fill_parent的;

啟動一個程式,可以主介面點選圖示進入,也可以從一個程式中跳轉過去,二者有什麼區別?
是因為啟動程式(主介面也是一個app),發現了在這個程式中存在一個設定為

<category android:name="android.intent.category.LAUNCHER" />

的activity,
所以這個launcher會把icon提出來,放在主介面上。當用戶點選icon的時候,發出一個Intent:

Intent intent = mActivity.getPackageManager().getLaunchIntentForPackage(packageName);
mActivity.startActivity(intent);

跳過去可以跳到任意允許的頁面,如一個程式可以下載,那麼真正下載的頁面可能不是首頁(也有可能是首頁),這時還是構造一個Intent,startActivity.
這個intent中的action可能有多種view,download都有可能。系統會根據第三方程式向系統註冊的功能,為你的Intent選擇可以開啟的程式或者頁面。所以唯一的一點
不同的是從icon的點選啟動的intent的action是相對單一的,從程式中跳轉或者啟動可能樣式更多一些。本質是相同的。

AIDL的全稱是什麼?如何工作?能處理哪些型別的資料?
AIDL全稱Android Interface Definition Language(Android介面描述語言)是一種介面描述語言; 編譯器可以通過aidl檔案生成一段程式碼,通過預先定義的介面達到兩個程序內部通訊程序跨界訪問物件的目的.AIDL的IPC的機制和COM或CORBA類似, 是基於介面的,但它是輕量級的。它使用代理類在客戶端和實現層間傳遞值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相關類.; 2. 呼叫aidl產生的class.
理論上, 引數可以傳遞基本資料型別和String, 還有就是Bundle的派生類, 不過在Eclipse中,目前的ADT不支援Bundle做為引數,
具體實現步驟如下:
1、建立AIDL檔案, 在這個檔案裡面定義介面, 該介面定義了可供客戶端訪問的方法和屬性。
2、編譯AIDL檔案, 用Ant的話, 可能需要手動, 使用Eclipse plugin的話,可以根據adil檔案自動生產java檔案並編譯, 不需要人為介入.
3、在Java檔案中, 實現AIDL中定義的介面. 編譯器會根據AIDL介面, 產生一個JAVA介面。這個介面有一個名為Stub的內部抽象類,它繼承擴充套件了介面並實現了遠端呼叫需要的幾個方法。接下來就需要自己去實現自定義的幾個介面了.
4、向客戶端提供介面ITaskBinder, 如果寫的是service,擴充套件該Service並重載onBind ()方法來返回一個實現上述介面的類的例項。
5、在伺服器端回撥客戶端的函式. 前提是當客戶端獲取的IBinder介面的時候,要去註冊回撥函式, 只有這樣, 伺服器端才知道該呼叫那些函式
AIDL語法很簡單,可以用來宣告一個帶一個或多個方法的介面,也可以傳遞引數和返回值。 由於遠端呼叫的需要, 這些引數和返回值並不是任何型別.下面是些AIDL支援的資料型別:

  1. 不需要import宣告的簡單Java程式語言型別(int,boolean等)
  2. String, CharSequence不需要特殊宣告
  3. List, Map和Parcelables型別, 這些型別內所包含的資料成員也只能是簡單資料型別, String等其他比支援的型別.
    (另外: 我沒嘗試Parcelables, 在Eclipse+ADT下編譯不過, 或許以後會有所支援).
    實現介面時有幾個原則:
    1.丟擲的異常不要返回給呼叫者. 跨程序拋異常處理是不可取的.
    2.IPC呼叫是同步的。如果你知道一個IPC服務需要超過幾毫秒的時間才能完成地話,你應該避免在Activity的主執行緒中呼叫。也就是IPC呼叫會掛起應用程式導致介面失去響應. 這種情況應該考慮單起一個執行緒來處理.
    3.不能在AIDL介面中宣告靜態屬性。
    IPC的呼叫步驟:
  4. 宣告一個介面型別的變數,該介面型別在.aidl檔案中定義。
  5. 實現ServiceConnection。
  6. 呼叫ApplicationContext.bindService(),並在ServiceConnection實現中進行傳遞.
  7. 在ServiceConnection.onServiceConnected()實現中,你會接收一個IBinder例項(被呼叫的Service). 呼叫
    YourInterfaceName.Stub.asInterface((IBinder)service)將引數轉換為YourInterface型別。
  8. 呼叫介面中定義的方法。你總要檢測到DeadObjectException異常,該異常在連線斷開時被丟擲。它只會被遠端方法丟擲。

aidl主要就是幫助我們完成了包裝資料和解包的過程,並呼叫了transact過程,而用來傳遞的資料包我們就稱為parcel

AIDL: xxx.aidl->xxx.java,註冊service

用aidl定義需要被呼叫方法介面
實現這些方法
呼叫這些方法

FC(Force Close)

什麼時候會出現

  • Error
  • OOM,記憶體溢位
  • StackOverFlowError
  • Runtime,比如說空指標異常

解決的辦法

  • 注意記憶體的使用和管理
  • 使用Thread.UncaughtExceptionHandler介面

效能優化

介面優化
太多重疊的背景(overdraw)

這個問題其實最容易解決,建議就是檢查你在佈局和程式碼中設定的背景,有些背景是隱藏在底下的,它永遠不可能顯示出來,這種沒必要的背景一定要移除,因為它很可能會嚴重影響到app的效能。如果採用的是selector的背景,將normal狀態的color設定為”@android:color/transparent”,也同樣可以解決問題。

太多重疊的View

第一個建議是 :使用ViewStub來載入一些不常用的佈局,它是一個輕量級且預設是不可見的檢視,可以動態的載入一個佈局,只要你用到這個重疊著的View的時候才載入,推遲載入的時間。

第二個建議是:如果使用了類似Viewpager+Fragment這樣的組合或者有多個Fragment在一個介面上,需要控制Fragment的顯示和隱藏,儘量使用動態的Inflation view,它的效能要比SetVisibility好。

複雜的Layout層級

這裡的建議比較多一些,首先推薦使用Android提供的佈局工具Hierarchy Viewer來檢查和優化佈局。第一個建議是:如果巢狀的線性佈局加深了佈局層次,可以使用相對佈局來取代。第二個建議是:用標籤來合併佈局。第三個建議是:用標籤來重用佈局,抽取通用的佈局可以讓佈局的邏輯更清晰明瞭。記住,這些建議的最終目的都是使得你的Layout在Hierarchy Viewer裡變得寬而淺,而不是窄而深。

總結:可以考慮多使用merge和include,ViewStub。儘量使佈局淺平,根佈局儘量少使用RelactivityLayout,因為RelactivityLayout每次需要測量2次。

記憶體優化
核心思想:減少記憶體使用,能不new的不new,能少分配的少分配。因為分配更多的記憶體就意味著發生更多的GC,每次觸發GC都會佔用CPU時間,影響效能。

  • 集合優化:Android提供了一系列優化過後的資料集合工具類,如SparseArray、SparseBooleanArray、LongSparseArray,使用這些API可以讓我們的程式更加高效。HashMap工具類會相對比較低效,因為它需要為每一個鍵值對都提供一個物件入口,而SparseArray就避免掉了基本資料型別轉換成物件資料型別的時間。
  • Bitmap優化:讀取一個Bitmap圖片的時候,千萬不要去載入不需要的解析度。可以壓縮圖片等操作。
  • 儘量避免使用依賴注入框架。
  • 避免創作不必要的物件:字串拼接使用StringBuffer,StringBuilder。
  • onDraw方法裡面不要執行物件的建立.
  • 重寫onTrimMemory,根據傳入的引數,進行記憶體釋放。
  • 使用static final 優化成員變數。

移動端獲取網路資料優化的幾個點

連線複用:節省連線建立時間,如開啟 keep-alive。
對於Android來說預設情況下HttpURLConnection和HttpClient都開啟了keep-alive。只是2.2之前HttpURLConnection存在影響連線池的Bug,具體可見:Android HttpURLConnection及HttpClient選擇

請求合併:即將多個請求合併為一個進行請求,比較常見的就是網頁中的CSS Image Sprites。如果某個頁面內請求過多,也可以考慮做一定的請求合併。

減少請求資料的大小:對於post請求,body可以做gzip壓縮的,header也可以做資料壓縮(不過只支援http 2.0)。
返回資料的body也可以做gzip壓縮,body資料體積可以縮小到原來的30%左右。(也可以考慮壓縮返回的json資料的key資料的體積,尤其是針對返回資料格式變化不大的情況,支付寶聊天返回的資料用到了)
根據使用者的當前的網路質量來判斷下載什麼質量的圖片(電商用的比較多)

高階

Android系統啟動過程,App啟動過程
]從桌面點選到activity啟動的過程

1.Launcher執行緒捕獲onclick的點選事件,呼叫Launcher.startActivitySafely,進一步呼叫Launcher.startActivity,最後呼叫父類Activity的startActivity。

2.Activity和ActivityManagerService互動,引入Instrumentation,將啟動請求交給Instrumentation,呼叫Instrumentation.execStartActivity。

3.呼叫ActivityManagerService的startActivity方法,這裡做了程序切換(具體過程請檢視原始碼)。

4.開啟Activity,呼叫onCreate方法

熱布丁
原因:因為一個dvm中儲存方法id用的是short型別,導致dex中方法不能超過65536個
原理:將編譯好的class檔案拆分打包成兩個dex,繞過dex方法數量的限制以及安裝時的檢查,在執行時再動態載入第二個dex檔案中。使用Dexclassloader。

動態載入(也叫外掛化技術)
動態載入主要解決3個技術問題:
1,使用ClassLoader載入類。
2,資源訪問。
3,生命週期管理。

Binder機制

跨程序間通訊(IPC):四大元件之間通過Intent互相跳轉,Android實現IPC的方式是binder機制。

Android系統的架構


螢幕快照 2016-09-07 上午9.26.57.png


android的系統架構和其作業系統一樣,採用了分層的架構。從架構圖看,android分為四個層,從高層到低層分別是應用程式層、應用程式框架層、系統執行庫層和linux核心層。
  1.應用程式
  Android會同一系列核心應用程式包一起釋出,該應用程式包包括email客戶端,SMS短訊息程式,日曆,地圖,瀏覽器,聯絡人管理程式等。所有的應用程式都是使用JAVA語言編寫的。
  2.應用程式框架
  開發人員也可以完全訪問核心應用程式所使用的API框架。該應用程式的架構設計簡化了元件的重用;任何一個應用程式都可以釋出它的功能塊並且任何其它的應用程式都可以使用其所釋出的功能塊(不過得遵循框架的安全性限制)。同樣,該應用程式重用機制也使使用者可以方便的替換程式元件。
  隱藏在每個應用後面的是一系列的服務和系統, 其中包括;
   豐富而又可擴充套件的檢視(Views),可以用來構建應用程式, 它包括列表(lists),網格(grids),文字框(text boxes),按鈕(buttons), 甚至可嵌入的web瀏覽器。   內容提供器(Content Providers)使得應用程式可以訪問另一個應用程式的資料(如聯絡人資料庫), 或者共享它們自己的資料
   資源管理器(Resource Manager)提供 非程式碼資源的訪問,如本地字串,圖形,和佈局檔案( layout files )。   通知管理器 (Notification Manager) 使得應用程式可以在狀態列中顯示自定義的提示資訊。
  * 活動管理器( Activity Manager) 用來管理應用程式生命週期並提供常用的導航回退功能。
  有關更多的細節和怎樣從頭寫一個應用程式,請參考 如何編寫一個 Android 應用程式.

 3.系統執行庫
  1)程式庫
  Android 包含一些C/C++庫,這些庫能被Android系統中不同的元件使用。它們通過 Android 應用程式框架為開發者提供服務。以下是一些核心庫:
  系統 C 庫 - 一個從 BSD 繼承來的標準 C 系統函式庫( libc ), 它是專門為基於 embedded linux 的裝置定製的。
   媒體庫 - 基於 PacketVideo OpenCORE;該庫支援多種常用的音訊、視訊格式回放和錄製,同時支援靜態影象檔案。編碼格式包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG 。
   Surface Manager - 對顯示子系統的管理,並且為多個應用程式提 供了2D和3D圖層的無縫融合。
   LibWebCore - 一個最新的web瀏覽器引擎用,支援Android瀏覽器和一個可嵌入的web檢視。
  SGL- 底層的2D圖形引擎
   3D libraries - 基於OpenGL ES 1.0 APIs實現;該庫可以使用硬體 3D加速(如果可用)或者使用高度優化的3D軟加速。
   FreeType -點陣圖(bitmap)和向量(vector)字型顯示。
   SQLite - 一個對於所有應用程式可用,功能強勁的輕型關係型資料庫引擎。
  2)Android 執行庫
  Android 包括了一個核心庫,該核心庫提供了JAVA程式語言核心庫的大多數功能。
  每一個Android應用程式都在它自己的程序中執行,都擁有一個獨立的Dalvik虛擬機器例項。Dalvik被設計成一個裝置可以同時高效地執行多個虛擬系統。 Dalvik虛擬機器執行(.dex)的Dalvik可執行檔案,該格式檔案針對小記憶體使用做了優化。同時虛擬機器是基於暫存器的,所有的類都經由JAVA編譯器編譯,然後通過SDK中 的 “dx” 工具轉化成.dex格式由虛擬機器執行。
  Dalvik虛擬機器依賴於linux核心的一些功能,比如執行緒機制和底層記憶體管理機制。
  *
4.Linux 核心**
Android 的核心繫統服務依賴於 Linux 2.6 核心,如安全性,記憶體管理,程序管理, 網路協議棧和驅動模型。 Linux 核心也同時作為硬體和軟體棧之間的抽象層。



文/maat紅飛(簡書作者)
原文連結:http://www.jianshu.com/p/89f19d67b348#
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。

相關推薦

親愛的面試這個Android部分

如何保證Service不被殺死 Android 程序不死從3個層面入手: A.提供程序優先順序,降低程序被殺死的概率 方法一:監控手機鎖屏解鎖事件,在螢幕鎖屏時啟動1個畫素的 Activity,在使用者解鎖時將 Activity 銷燬掉。 方法二:啟動前臺service。

JS的原型鏈這個圖你

想到Objective-C有個isa指標,物件的isa指向類,類的isa指向元類,元類的isa指向自己。正是有了isa指標,才有了強大的runtime功能。 那麼,前端技術js也有自己的指向關係,這裡借用《JavaScript高階程式設計》中的描述: 每個建構函式都有一個

非常全的各類知識大排行完你就是文化人了反正

158、最能代表中國文化的20種書 (1) 《詩經》 (2) 《墨子》 (3) 《李太白詩集》 (4) 《孫子》 (5) 《杜工部詩集》 (6) 《莊子》 (7) 《宋元戲曲史》 (8) 《韓非子》 (9) 《紅樓夢》 (10) 《明夷待訪錄》 (11) 《魯迅雜感選集》 (12) 《

在印度這樣的國家這位父親太令人敬佩文/萱草

成績 顏色 自己的 兩個 掌握 最可 老婆 代表作 精彩 阿米爾汗不愧是印度電影的良心。他的幾部代表作無一不在針砭時弊,為民發聲。就像《三傻大鬧寶萊塢》對錯誤教育制度的反擊,《我的個神》和《偶滴神啊》對印度宗教的大膽批判和質疑,《芭薩堤的顏色》對印度政治體制的強烈抨擊等,每

推薦6個國內技術大牛部落格全棧工程師修行的祕籍建議收藏

學習PHP語言、JavaScript語言、Python語言及前端的知識點,光是自己學習還是不夠的,我們還要借鑑大牛們的程式設計思路,瞭解程式設計的技巧和方法,這樣才能事半功倍。 今天就為大家推薦我認為比較不錯的6個技術大牛部落格,大家有興趣可以關注一下,看看大牛們的程式設計思路,學習他們思考問題

單機遊戲—亂世君臨純python實現大型遊戲開發初級篇

             學習Python中有不明白推薦加入交流群                 號:516107834 &nbs

作為面試是怎麼快速判斷程式設計師能力的?

技術面試是一個工程師成長到一定階段後必然要承擔的一項工作,優秀的技術面試官能幫助公司篩選出優秀的工程師,並且潛移默化的吸引候選人選擇加入公司。相反,糟糕的面試不僅會錯失優秀候選人,甚至還會給公司招來大麻煩。儘管技術面試如此重要,我還是瞭解到,很多公司的技術面試官都是“無證上崗

作為一個面試是怎麼來面試測試人員的?

其實之前關於面試也說了好多,知乎上我也開過一個面試的Live,也有幸被選進了知乎2016精選。不過今天我想說的是在實際過程中如果我去面試了,我會怎麼進行面試,會問什麼問題,會遵照哪些原則。我本身的行事風格就是比較特殊的,希望對廣大應聘者和麵試官有所幫助。   只關心對方

第一次作為面試很緊張

我作為應聘者,從來不緊張,哪怕是第一次應聘的時候,但在前幾天作為面試官的時候,我很緊張。 為什麼緊張呢。因為作為應聘者我只要為我自己負責。但是作為一個面試官,我不是在為自己負責,而是在為應聘者與公司負責。當肩負這樣的使命後,就感覺有一定的擔子。 可以說面試是一個人的基本技能

包裝嚴重的IT行業作為面試是如何甄別應聘者的包裝程度

在網際網路極速膨脹的社會背景下,各行各業湧入網際網路的IT民工日益增大。 早在2

某程序員趣聞:面試了曾經的面試把他曾經問的又問了他一遍

相聲 docker 招生信息 流轉 零基礎入門 inf ali image 開會 想必最近有不少互聯網同行都在面試,大家進行的怎麽樣呢? 近日,騰訊某程序員在互聯網社區分享了自己作為面試官的趣聞:今天面試了個百度來的,他不記得我了,我前年在百度二面的面試官就是他&hell

面試求求你不要問這麼簡單但又刁難的演算法題了

有時候面試官往往會問我們一些簡單,但又刁難的問題,主要是看看你對問題的處理思路。如果你沒接觸過這些問題,可能一時之間還真不知道怎麼處理才比較好,這種題更重要的是一種思維的散發吧,今天就來分享幾道題面試中遇到的演算法題(當然,不是我自己遇到過,是別人遇到過,我挑選出來的) 案例1 題目描述:求1+2+3+..

作為IT面試如何考核計算機專業畢業生?作為培訓班老師又如何提升他們?

    我最近幾年一直在做技術面試官,除了面試有一定工作經驗的社會人員外,有時還會面試在校實習生和剛畢業的大學生。同時,我也在學校裡做過兼職講師,上些政府補貼課程(這些課程有補貼,學生不用出錢),所以我會在不同的場合承擔兩種截然相反的職責。     幸好我的公司不會從

作為阿里面試究竟想問什麼

原文連結地址:Nealyang/personalBlog 市面上有很多關於面試的文章,但是基本都是從應聘者的角度去分析問題的,從招聘官的角度去分享的著實不多。本文將從我的個人招聘經歷分享下關於前端一面的一些思考和自己的感悟。以下所有感悟皆為筆者個人感悟,不代表任何。有不妥之處,歡迎指出 其實不得不說,找工

面試不要再問三次握手和四次揮手

三次握手和四次揮手是各個公司常見的考點,也具有一定的水平區分度,也被一些面試官作為熱身題。很多小夥伴說這個問題剛開始回答的挺好,但是後面越回答越冒冷汗,最後就歇菜了。 見過比較典型的面試場景是這樣的: 面試官:請介紹下三次握手 求職者:第一次握手就是客戶端給伺服器端傳送一個報文,第二次就是伺服器收到報文之後

面試不要再問“Java GC垃圾回收機制”了

Java GC垃圾回收幾乎是面試必問的JVM問題之一,本篇文章帶領大家瞭解Java GC的底層原理,圖文並茂,突破學習及面試瓶頸。 楔子-JVM記憶體結構補充 在上篇《JVM之記憶體結構詳解》中有些內容我們沒有講,本篇結合垃圾回收機制來一起學習。還記得JVM中堆的結構圖嗎? 圖中展示了堆中三個區域:Ede

面試不要再問“Java 垃圾收集器”了

如果Java虛擬機器中標記清除演算法、標記整理演算法、複製演算法、分代演算法這些屬於GC收集演算法中的方法論,那麼“GC收集器”則是這些方法論的具體實現。 在面試過程中這個深度的問題涉及的比較少,但對於理解上面的這些演算法有很好的幫助。如果能夠如數家珍,也是面試中的加分項,還是那句話,畢竟面試官的時間也不多了

什麼鬼面試竟然讓用Redis實現一個訊息佇列

GitHub 9.4k Star 的Java工程師成神之路 ,不來了解一下嗎? GitHub 9.4k Star 的Java工程師成神之路 ,真的不來了解一下嗎? GitHub 9.4k Star 的Java工程師成神之路 ,真的確定不來了解一下嗎? 眾所周知,redis是一個高效能的key-value資料庫

作為阿里的面試有話想說。

面試,面試官比候選人還難 近期面試了許多,真的是許多同學,講道理其實我是比較有耐心的面試官,但是還是忍不住想要吐槽,因此寫下這篇文章,一方面希望可以幫助到正在面試,或者在來面試路上的同學,另一方面,純粹吐槽。 作為面試官,我是真心希望為團隊招到優秀的候選人,招到優秀的合作伙伴,其實面試官比候選人還著急。

瞭解集合類面試竟然問為啥HashMap的負載因子不設定成1

在Java基礎中,集合類是很關鍵的一塊知識點,也是日常開發的時候經常會用到的。比如List、Map這些在程式碼中也是很常見的。 個人認為,關於HashMap的實現,JDK的工程師其實是做了很多優化的,要說所有的JDK原始碼中,哪個類埋的彩蛋最多,那我想HashMap至少可以排前五。 也正是因為如此,很多細節都