溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android開(kāi)發(fā)者面試阿里等大廠遇到的問(wèn)題有哪些

發(fā)布時(shí)間:2020-08-03 09:35:36 來(lái)源:億速云 閱讀:173 作者:Leah 欄目:web開(kāi)發(fā)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)Android開(kāi)發(fā)者面試阿里等大廠遇到的問(wèn)題有哪些,文章內(nèi)容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

1.自定義Handler時(shí)如何避免內(nèi)存泄漏

答案:

一般非靜態(tài)內(nèi)部類(lèi)持有外部類(lèi)的引用的情況下,造成外部類(lèi)在使用完成后不能被系統(tǒng)回收內(nèi)存,從而造成內(nèi)存泄漏。為了避免這個(gè)問(wèn)題,我們可以自定義的Handler聲明為靜態(tài)內(nèi)部類(lèi)形式,然后通過(guò)弱引用的方式,讓Handler持有外部類(lèi)的引用,從而可避免內(nèi)存泄漏問(wèn)題。

以下是代碼實(shí)現(xiàn)

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private TextView mTextView;
private WeakReference<MainActivity> activityWeakReference;
private MyHandler myHandler;

static class MyHandler extends Handler {
    private MainActivity activity;

    MyHandler(WeakReference<MainActivity> ref) {
        this.activity = ref.get();
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {            case 1:
                //需要做判空操作                if (activity != null) {
                    activity.mTextView.setText("new Value");
                }                break;
            default:
                Log.i(TAG, "handleMessage: default ");                break;
        }

    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);
    //在onCreate中初始化
    activityWeakReference = new WeakReference<MainActivity>(this);
    myHandler = new MyHandler(activityWeakReference);

    myHandler.sendEmptyMessage(1);
    mTextView = (TextView) findViewById(R.id.tv_test);
}
}復(fù)制代碼

參考博文blog.csdn.net/ucxiii/arti…

2.onNewIntent()的調(diào)用時(shí)機(jī)

解析:

在Android應(yīng)用程序開(kāi)發(fā)的時(shí)候,從一個(gè)Activity啟動(dòng)另一個(gè)Activity并傳遞一些數(shù)據(jù)到新的Activity上非常簡(jiǎn)單,但是當(dāng)您需要讓后臺(tái)運(yùn)行的Activity回到前臺(tái)并傳遞一些數(shù)據(jù)可能就會(huì)存在一點(diǎn)點(diǎn)小問(wèn)題。

首先,在默認(rèn)情況下,當(dāng)您通過(guò)Intent啟到一個(gè)Activity的時(shí)候,就算已經(jīng)存在一個(gè)相同的正在運(yùn)行的Activity,系統(tǒng)都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例并顯示出來(lái)。為了不讓Activity實(shí)例化多次,我們需要通過(guò)在AndroidManifest.xml配置activity的加載方式(launchMode)以實(shí)現(xiàn)單任務(wù)模式,如下所示:

<activity 
android:label="@string/app_name"android:launchmode="singleTask"android:name="Activity1">
</activity>復(fù)制代碼

launchMode為singleTask的時(shí)候,通過(guò)Intent啟到一個(gè)Activity,如果系統(tǒng)已經(jīng)存在一個(gè)實(shí)例,系統(tǒng)就會(huì)將請(qǐng)求發(fā)送到這個(gè)實(shí)例上,但這個(gè)時(shí)候,系統(tǒng)就不會(huì)再調(diào)用通常情況下我們處理請(qǐng)求數(shù)據(jù)的onCreate方法,而是調(diào)用onNewIntent方法

答案:

前提:ActivityA已經(jīng)啟動(dòng)過(guò),處于當(dāng)前應(yīng)用的Activity堆棧中; 當(dāng)ActivityA的LaunchMode為SingleTop時(shí),如果ActivityA在棧頂,且現(xiàn)在要再啟動(dòng)ActivityA,這時(shí)會(huì)調(diào)用onNewIntent()方法 當(dāng)ActivityA的LaunchMode為SingleInstance,SingleTask時(shí),如果已經(jīng)ActivityA已經(jīng)在堆棧中,那么此時(shí)會(huì)調(diào)用onNewIntent()方法

當(dāng)ActivityA的LaunchMode為Standard時(shí),由于每次啟動(dòng)ActivityA都是啟動(dòng)新的實(shí)例,和原來(lái)啟動(dòng)的沒(méi)關(guān)系,所以不會(huì)調(diào)用原來(lái)ActivityA的onNewIntent方法,仍然調(diào)用的是onCreate方法

以下是代碼實(shí)例

1.設(shè)置MainActivity的啟動(dòng)模式為SingleTask(棧內(nèi)復(fù)用)

<activity
android:name=".MainActivity"android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>復(fù)制代碼

2.MainActivity中重寫(xiě)onNewIntent方法

package code.xzy.com.handlerdemo;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Button mButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);
    mButton = (Button) findViewById(R.id.forward_btn);
    mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(MainActivity.this, Main2Activity.class));
        }
    });

}

@Override
protected void onNewIntent(Intent intent) {
    Toast.makeText(this, "onnewIntent", Toast.LENGTH_SHORT).show();
    Log.i(TAG, "onNewIntent: i done....");
}
}復(fù)制代碼

3.Main2Actvity執(zhí)行點(diǎn)擊跳轉(zhuǎn),MainActivity被復(fù)用,執(zhí)行onNewIntent方法

package code.xzy.com.handlerdemo;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class Main2Activity extends AppCompatActivity {
private Button mButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main2);

    mButton = (Button)findViewById(R.id.btn);

    mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(Main2Activity.this,MainActivity.class));
            finish();
        }
    });
}
}

打印截圖

**這里分享一份全套體系化高級(jí)架構(gòu)視頻;**七大主流技術(shù)模塊,視頻+源碼+筆記(文末有詳細(xì)面試資料專(zhuān)題整理包分享

3.RecyclerView相比ListView有哪些優(yōu)勢(shì)

解析:

首先需要解釋下RecyclerView的這個(gè)名字了,從它類(lèi)名上看,RecyclerView代表的意義是,我只管Recycler View,也就是說(shuō)RecyclerView只管回收與復(fù)用View,其他的你可以自己去設(shè)置??梢钥闯銎涓叨鹊慕怦?,給予你充分的定制自由(所以你才可以輕松的通過(guò)這個(gè)控件實(shí)現(xiàn)ListView,GirdView,瀑布流等效果)

其次RecyclerView提供了添加、刪除item的動(dòng)畫(huà) 效果,而且可以自定義

RecyclerView相比ListView優(yōu)勢(shì)在于可以輕松實(shí)現(xiàn):

  1. ListView的功能
  2. GridView的功能
  3. 橫向ListView的功能
  4. 橫向ScrollView的功能
  5. 瀑布流效果
  6. 便于添加Item增加和移除動(dòng)畫(huà)

不過(guò)一個(gè)挺郁悶的地方就是,系統(tǒng)沒(méi)有提供ClickListener和LongClickListener。 不過(guò)我們也可以自己去添加,只是會(huì)多了些代碼而已。 實(shí)現(xiàn)的方式比較多,你可以通過(guò)mRecyclerView.addOnItemTouchListener去監(jiān)聽(tīng)然后去判斷手勢(shì),

當(dāng)然你也可以通過(guò)adapter中自己去提供回調(diào)

參考

jcodecraeer.com/a/anzhuokai… blog.csdn.net/lmj62356579… www.360doc.com/content/16/…

4.談一談Proguard混淆技術(shù)

答案:

Proguard技術(shù)有如下功能:

壓縮 --檢查并移除代碼中無(wú)用的類(lèi) 優(yōu)化--對(duì)字節(jié)碼的優(yōu)化,移除無(wú)用的字節(jié)碼 混淆--混淆定義的名稱(chēng),避免反編譯

預(yù)監(jiān)測(cè)--在java平臺(tái)對(duì)處理后的代碼再次進(jìn)行檢測(cè)

代碼混淆只在上線時(shí)才會(huì)用到,debug模式下會(huì)關(guān)閉,是一種可選的技術(shù)。

那么為什么要使用代碼混淆呢?

因?yàn)镴ava是一種跨平臺(tái)的解釋性開(kāi)發(fā)語(yǔ)言,而java的源代碼會(huì)被編譯成字節(jié)碼文件,存儲(chǔ)在.class文件中,由于跨平臺(tái)的需要,java的字節(jié)碼中包含了很多源代碼信息,諸如變量名、方法名等等。并且通過(guò)這些名稱(chēng)來(lái)訪問(wèn)變量和方法,這些變量很多是無(wú)意義的,但是又很容易反編譯成java源代碼,為了防止這種現(xiàn)象,我們就需要通過(guò)proguard來(lái)對(duì)java的字節(jié)碼進(jìn)行混淆,混淆就是對(duì)發(fā)布的程序進(jìn)行重新組織和處理,使得處理后的代碼與處理前的代碼有相同的功能,和不同的代碼展示,即使被反編譯也很難讀懂代碼的含義,哪些混淆過(guò)的代碼仍能按照之前的邏輯執(zhí)行得到一樣的結(jié)果。

但是,某些java類(lèi)是不能被混淆的,比如實(shí)現(xiàn)了序列化的java類(lèi)是不能被混淆的,否則反序列化時(shí)會(huì)出問(wèn)題。

下面這類(lèi)代碼混淆的時(shí)候要注意保留,不能混淆。

  • Android系統(tǒng)組件,系統(tǒng)組件有固定的方法被系統(tǒng)調(diào)用。
  • 被Android Resource 文件引用到的。名字已經(jīng)固定,也不能混淆,比如自定義的View 。
  • Android Parcelable ,需要使用android 序列化的。

其他Anroid 官方建議 不混淆的,如

  • android.app.backup.BackupAgentHelper?
  • android.preference.Preference?
  • com.android.vending.licensing.ILicensingService?
  • Java序列化方法,系統(tǒng)序列化需要固定的方法。?
  • 枚舉 ,系統(tǒng)需要處理枚舉的固定方法。?
  • 本地方法,不能修改本地方法名?
  • annotations 注釋?
  • 數(shù)據(jù)庫(kù)驅(qū)動(dòng)?
  • 有些resource 文件用到反射的地方

5.ANR出現(xiàn)的場(chǎng)景及解決方案

在Android中,應(yīng)用的響應(yīng)性被活動(dòng)管理器(Activity Manager)和窗口管理器(Window Manager)這兩個(gè)系統(tǒng)服務(wù)所監(jiān)視。當(dāng)用戶觸發(fā)了輸入事件(如鍵盤(pán)輸入,點(diǎn)擊按鈕等),如果應(yīng)用5秒內(nèi)沒(méi)有響應(yīng)用戶的輸入事件,那么,Android會(huì)認(rèn)為該應(yīng)用無(wú)響應(yīng),便彈出ANR對(duì)話框。而彈出ANR異常,也主要是為了提升用戶體驗(yàn)。

解決方案是對(duì)于耗時(shí)的操作,比如訪問(wèn)網(wǎng)絡(luò)、訪問(wèn)數(shù)據(jù)庫(kù)等操作,需要開(kāi)辟子線程,在子線程處理耗時(shí)的操作,主線程主要實(shí)現(xiàn)UI的操作

6.HTTPS中SSL證書(shū)認(rèn)證的過(guò)程

7.簡(jiǎn)述Android的Activity的內(nèi)部機(jī)制

8.對(duì)Android Framework層的某一個(gè)模塊(或者System App)做簡(jiǎn)要介紹

9.Android Handler的機(jī)制和原理

主線程使用Handler的過(guò)程

首先在主線程創(chuàng)建一個(gè)Handler對(duì)象 ,并重寫(xiě)handleMessage()方法。然后當(dāng)在子線程中需要進(jìn)行更新UI的操作,我們就創(chuàng)建一個(gè)Message對(duì)象,并通過(guò)handler發(fā)送這條消息出去。之后這條消息被加入到MessageQueue隊(duì)列中等待被處理,通過(guò)Looper對(duì)象會(huì)一直嘗試從Message Queue中取出待處理的消息,最后分發(fā)會(huì)Handler的handler Message()方法中。

參考 blog.csdn.net/u012827296/…

10.線程間通信和進(jìn)程間通信有什么不同,Android開(kāi)發(fā)過(guò)程中是怎么實(shí)現(xiàn)的

www.cnblogs.com/yangtao1995…

11.簡(jiǎn)述項(xiàng)目中對(duì)于內(nèi)存優(yōu)化的幾個(gè)細(xì)節(jié)點(diǎn)

答案:

  1. 當(dāng)查詢完數(shù)據(jù)庫(kù)之后,及時(shí)關(guān)閉Cursor對(duì)象。
  2. 記得在Activity的onPause方法中調(diào)用unregisterReceiver()方法,反注冊(cè)廣播
  3. 避免Content內(nèi)存泄漏,比如在4.0.1之前的版本上不要講Drawer對(duì)象置為static。當(dāng)一個(gè)Drawable綁定到了View上,實(shí)際上這個(gè)View對(duì)象就會(huì)成為這個(gè)Drawable的一個(gè)callback成員變量,上面的例子中靜態(tài)的sBackground持有TextView對(duì)象lable的引用,而lable只有Activity的引用,而Activity會(huì)持有其他更多對(duì)象的引用。sBackground生命周期要長(zhǎng)于Activity。當(dāng)屏幕旋轉(zhuǎn)時(shí),Activity無(wú)法被銷(xiāo)毀,這樣就產(chǎn)生了內(nèi)存泄露問(wèn)題。
  4. 盡量不要在Activity中使用非靜態(tài)內(nèi)部類(lèi),因?yàn)榉庆o態(tài)內(nèi)部類(lèi)會(huì)隱式持有外部類(lèi)實(shí)例的引用,當(dāng)非靜態(tài)內(nèi)部類(lèi)的引用的聲明周期長(zhǎng)于Activity的聲明周期時(shí),會(huì)導(dǎo)致Activity無(wú)法被GC正?;厥盏?。
  5. 謹(jǐn)慎使用線程Thread??!這條是很多人會(huì)犯的錯(cuò)誤: Java中的Thread有一個(gè)特點(diǎn)就是她們都是直接被GC Root所引用,也就是說(shuō)Dalvik虛擬機(jī)對(duì)所有被激活狀態(tài)的線程都是持有強(qiáng)引用,導(dǎo)致GC永遠(yuǎn)都無(wú)法回收掉這些線程對(duì)象,除非線程被手動(dòng)停止并置為null或者用戶直接kill進(jìn)程操作。所以當(dāng)使用線程時(shí),一定要考慮在Activity退出時(shí),及時(shí)將線程也停止并釋放掉
  6. 使用Handler時(shí),要么是放在單獨(dú)的類(lèi)文件中,要么就是使用靜態(tài)內(nèi)部類(lèi)。因?yàn)殪o態(tài)的內(nèi)部類(lèi)不會(huì)持有外部類(lèi)的引用,所以不會(huì)導(dǎo)致外部類(lèi)實(shí)例的內(nèi)存泄露

12.簡(jiǎn)述Android的視圖層級(jí)優(yōu)化,簡(jiǎn)述自定義View或者自定義ViewGroup的步驟

個(gè)人的理解是,Android視圖渲染必須經(jīng)過(guò)measure、layout、draw三個(gè)步驟,measure過(guò)程是在一個(gè)樹(shù)形結(jié)構(gòu)中不斷遍歷的,如果UI層級(jí)嵌套很深,必將花費(fèi)大量的時(shí)間,所以應(yīng)該盡量減少層級(jí)嵌套,保證樹(shù)的結(jié)構(gòu)扁平,并移除不需要渲染的views

自定義view步驟:

Android自定義View的一般步驟

13.選取一個(gè)常用的第三方開(kāi)源庫(kù),簡(jiǎn)述其接入步驟

Volley教程 blog.csdn.net/jdfkldjlkjd…

14.TCP和UPD的區(qū)別以及使用場(chǎng)景

TCP與UDP基本區(qū)別

  1. 基于連接與無(wú)連接
  2. TCP要求系統(tǒng)資源較多,UDP較少;
  3. UDP程序結(jié)構(gòu)較簡(jiǎn)單
  4. 流模式(TCP)與數(shù)據(jù)報(bào)模式(UDP);
  5. TCP保證數(shù)據(jù)正確性,UDP可能丟包
  6. TCP保證數(shù)據(jù)順序,UDP不保證

UDP應(yīng)用場(chǎng)景:

  1. 面向數(shù)據(jù)報(bào)方式
  2. 網(wǎng)絡(luò)數(shù)據(jù)大多為短消息
  3. 擁有大量Client
  4. 對(duì)數(shù)據(jù)安全性無(wú)特殊要求
  5. 網(wǎng)絡(luò)負(fù)擔(dān)非常重,但對(duì)響應(yīng)速度要求高

15.簡(jiǎn)述一個(gè)設(shè)計(jì)模式的概念,并簡(jiǎn)要談?wù)刦ramework層哪些地方用到了什么設(shè)計(jì)模式

單例模式:單例模式是一種對(duì)象創(chuàng)建模式,它用于產(chǎn)生一個(gè)對(duì)象的具體實(shí)例,它可以確保系統(tǒng)中一個(gè)類(lèi)只產(chǎn)生一個(gè)實(shí)例。

適配器模式:將一個(gè)接口轉(zhuǎn)換成客戶希望的另一個(gè)接口,適配器模式使接口不兼容的那些類(lèi)可以一起工作,其別名為包裝器(Wrapper)

裝飾模式:動(dòng)態(tài)地給一個(gè)對(duì)象增加一些額外的職責(zé),就增加對(duì)象功能來(lái)說(shuō),裝飾模式比生成子類(lèi)實(shí)現(xiàn)更為靈活。裝飾模式是一種對(duì)象結(jié)構(gòu)型模式。

使用場(chǎng)景:

  1. 在不影響其他對(duì)象的情況下,以動(dòng)態(tài)、透明的方式給單個(gè)對(duì)象添加職責(zé)。
  2. 當(dāng)不能采用繼承的方式對(duì)系統(tǒng)進(jìn)行擴(kuò)展或者采用繼承不利于系統(tǒng)擴(kuò)展和維護(hù)時(shí)可以使用裝飾模式。

優(yōu)點(diǎn):

對(duì)于擴(kuò)展一個(gè)對(duì)象的功能,裝飾模式比繼承更加靈活,不會(huì)導(dǎo)致類(lèi)的個(gè)數(shù)急劇增加。

可以通過(guò)一種動(dòng)態(tài)地方式來(lái)擴(kuò)展一個(gè)對(duì)象的功能。

可以對(duì)一個(gè)對(duì)象進(jìn)行多次裝飾,通過(guò)使用不同的具體裝飾類(lèi)以及這些裝飾類(lèi)的排列組合。

實(shí)際運(yùn)用:

Android中Context類(lèi)的實(shí)現(xiàn)

外觀模式:主要目的在于讓外部減少與子系統(tǒng)內(nèi)部多個(gè)模塊的交互,從而讓外部能夠更簡(jiǎn)單得使用子系統(tǒng)。它負(fù)責(zé)把客戶端的請(qǐng)求轉(zhuǎn)發(fā)給子系統(tǒng)內(nèi)部的各個(gè)模塊進(jìn)行處理。

使用場(chǎng)景:

  1. 當(dāng)你要為一個(gè)復(fù)雜的子系統(tǒng)提供一個(gè)簡(jiǎn)單的接口時(shí)
  2. 客戶程序與抽象類(lèi)的實(shí)現(xiàn)部分之前存在著很大的依賴(lài)性
  3. 當(dāng)你需要構(gòu)建一個(gè)層次結(jié)構(gòu)的子系統(tǒng)時(shí)

**組合模式:**將對(duì)象以樹(shù)形結(jié)構(gòu)組織起來(lái),以達(dá)成”部分--整體”的層次結(jié)構(gòu),使得客戶端對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

使用場(chǎng)景:

  1. 需要表示一個(gè)對(duì)象整體或部分 層次
  2. 讓客戶端能夠忽略不同對(duì)象層次的變化

優(yōu)點(diǎn):

1.高層模塊調(diào)用簡(jiǎn)單 2.節(jié)點(diǎn)自由增加

**模板方法:**是通過(guò)一個(gè)算法骨架,而將算法中的步驟延遲到子類(lèi),這樣子類(lèi)就可以復(fù)寫(xiě)這些步驟的實(shí)現(xiàn)來(lái)實(shí)現(xiàn)特定的算法。

它的使用場(chǎng)景:

  1. 多個(gè)子類(lèi)有公有的方法,并且邏輯基本相同
  2. 重要、復(fù)雜的算法,可以把核心算法設(shè)計(jì)為模板方法、
  3. 重構(gòu)時(shí),模板方法模式是一個(gè)經(jīng)常使用的模式

觀察者模式:定義對(duì)象之間一種一對(duì)多依賴(lài)關(guān)系,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí),其相關(guān)依賴(lài)對(duì)象皆得到通知并被自動(dòng)更新。

其使用場(chǎng)景:

  1. 一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴(lài)于另一個(gè)方面
  2. 一個(gè)對(duì)象的改變將導(dǎo)致一個(gè)或多個(gè)其他對(duì)象也 發(fā)生改變
  3. 需要在 系統(tǒng)中創(chuàng)建一個(gè) 觸發(fā)鏈

具體應(yīng)用:

比如回調(diào)模式中,實(shí)現(xiàn)了抽象類(lèi)/接口的實(shí)例實(shí)現(xiàn)了父類(lèi)提供的抽象方法后,將該方法交還給父類(lèi)來(lái)處理

Listview中的notifyDataSetChanged

RxJava中的觀察者模式

**責(zé)任鏈模式:**是一個(gè)請(qǐng)求有多個(gè)對(duì)象來(lái)處理,這些對(duì)象是一條鏈,但具體由哪個(gè)對(duì)象來(lái)處理,根據(jù)條件判斷來(lái)確定,如果不能處理會(huì)傳遞給該鏈條中的下一個(gè)對(duì)象,直到有對(duì)象處理它為止。

使用場(chǎng)景:1.有多個(gè)對(duì)象可以處理同一個(gè)請(qǐng)求,具體哪個(gè)對(duì)象處理該請(qǐng)求待運(yùn)行時(shí)再確定 2.在不明確指定接收者的情況下,向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求。

實(shí)際運(yùn)用:Try...catch語(yǔ)句 OrderedBroadcast MotionEvent:actionDwon actionMove actionUp 事件分發(fā)機(jī)制三個(gè)重要方法:dispatchTouchEvent. onInterceptTouchEvent. onTouchEvent

**策略模式:**定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái),并且使他們可互相替換。本模式使得算法可獨(dú)立于使用它的客戶而變化。策略模式的使用場(chǎng)景:一個(gè)類(lèi)定義了多種行為,并且這些行為在這個(gè)類(lèi)的方法中以多個(gè)條件語(yǔ)句的形式出現(xiàn),那么可以使用策略模式避免在類(lèi)中使用大量的條件語(yǔ)句。

使用場(chǎng)景:一個(gè)類(lèi)定義了多種行為,并且這些行為在這個(gè)類(lèi)的方法中以多個(gè)條件語(yǔ)句的形式出現(xiàn),那么可以使用策略模式避免在類(lèi)中使用大量的條件語(yǔ)句。

優(yōu)點(diǎn):1.上下文Context和具體策略ConcreateStrategy是松耦合關(guān)系 2.策略模式滿足 開(kāi)-閉原則

具體應(yīng)用:

  1. HttpStack
  2. Volley框架

16.字節(jié)流和字符流的區(qū)別

字節(jié)流操作的基本單元為字節(jié);字符流操作的基本單元為Unicode碼元(2個(gè)字節(jié))。 字節(jié)流默認(rèn)不使用緩沖區(qū);字符流使用緩沖區(qū)。

字節(jié)流通常用于處理二進(jìn)制數(shù)據(jù),實(shí)際上它可以處理任意類(lèi)型的數(shù)據(jù),但它不支持直接寫(xiě)入或讀取Unicode碼元;字符流通常處理文本數(shù)據(jù),它支持寫(xiě)入及讀取Unicode碼元。

參考 理解Java中字符流與字節(jié)流的區(qū)別

17.View的繪制流程,是先測(cè)量父View還是先測(cè)量子View

View和ViewGroup的基本繪制流程

18.OOM異常是否可以被try...catch捕獲(或者可否用try-catch捕獲Out Of Memory Error以避免其發(fā)生?)

只有在一種情況下,這樣做是可行的:在try語(yǔ)句中聲明了很大的對(duì)象,導(dǎo)致OOM,并且可以確認(rèn)OOM是由try語(yǔ)句中的對(duì)象聲明導(dǎo)致的,那么在catch語(yǔ)句中,可以釋放掉這些對(duì)象,解決OOM的問(wèn)題,繼續(xù)執(zhí)行剩余語(yǔ)句。

但是這通常不是合適的做法。Java中管理內(nèi)存除了顯式地catch OOM之外還有更多有效的方法:比如SoftReference, WeakReference, 硬盤(pán)緩存等。在JVM用光內(nèi)存之前,會(huì)多次觸發(fā)GC,這些GC會(huì)降低程序運(yùn)行的效率。如果OOM的原因不是try語(yǔ)句中的對(duì)象(比如內(nèi)存泄漏),那么在catch語(yǔ)句中會(huì)繼續(xù)拋出OOM

19.WeakReference和SoftReference的區(qū)別

Java的StrongReference, SoftReference, WeakReference, PhantomReference的區(qū)別

20.請(qǐng)計(jì)算一張100像素*100像素的圖片所占用內(nèi)存

blog.csdn.net/u010652002/…

21.okHttp實(shí)現(xiàn)的原理

22.okHttp有哪些攔截器

23.計(jì)算1+2!+3!+4!+5!+...+20!的結(jié)果,用代碼實(shí)現(xiàn)

24.寫(xiě)出單例模式,哪些是線程安全的,為什么是線程安全的

25.Retrofit實(shí)現(xiàn)原理

26.android圖片有哪些格式

答案:blog.csdn.net/xmc28114194…

27.sqlite可以執(zhí)行多線程操作嗎?如何保證多線程操作數(shù)據(jù)庫(kù)的安全性

答:

每當(dāng)你需要使用數(shù)據(jù)庫(kù)時(shí),你需要使用DatabaseManager的openDatabase()方法來(lái)取得數(shù)據(jù)庫(kù),這個(gè)方法里面使用了單例模式,保證了數(shù)據(jù)庫(kù)對(duì)象的唯一性,也就是每次操作數(shù)據(jù)庫(kù)時(shí)所使用的sqlite對(duì)象都是一致得到。其次,我們會(huì)使用一個(gè)引用計(jì)數(shù)來(lái)判斷是否要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)對(duì)象。如果引用計(jì)數(shù)為1,則需要?jiǎng)?chuàng)建一個(gè)數(shù)據(jù)庫(kù),如果不為1,說(shuō)明我們已經(jīng)創(chuàng)建過(guò)了。 在closeDatabase()方法中我們同樣通過(guò)判斷引用計(jì)數(shù)的值,如果引用計(jì)數(shù)降為0,則說(shuō)明我們需要close數(shù)據(jù)庫(kù)。

大致的做法就是在多線程訪問(wèn)的情況下需要自己來(lái)封裝一個(gè)DatabaseManager來(lái)管理Sqlite數(shù)據(jù)庫(kù)的讀寫(xiě),需要同步的同步,需要異步的異步,不要直接操作數(shù)據(jù)庫(kù),這樣很容易出現(xiàn)因?yàn)殒i的問(wèn)題導(dǎo)致加鎖后的操作失敗。

該答案參考了這篇文章blog.csdn.net/rockcode_li…

28.有兩個(gè)長(zhǎng)度已知的鏈表,怎樣確定兩個(gè)鏈表的交集

解析:leetcode 兩個(gè)鏈表的交集點(diǎn) www.360doc.com/content/16/…

有以下幾種思路:

(1) 暴力破解 ,遍歷鏈表A的所有節(jié)點(diǎn),并且對(duì)于每個(gè)節(jié)點(diǎn),都與鏈表B中的所有節(jié)點(diǎn)比較,退出條件是在B中找到第一個(gè)相等的節(jié)點(diǎn)。時(shí)間復(fù)雜度O(lengthA*lengthB),空間復(fù)雜度O(1)。

(2) 哈希表 。遍歷鏈表A,并且將節(jié)點(diǎn)存儲(chǔ)到哈希表中。接著遍歷鏈表B,對(duì)于B中的每個(gè)節(jié)點(diǎn),查找哈希表,如果在哈希表中找到了,說(shuō)明是交集開(kāi)始的那個(gè)節(jié)點(diǎn)。時(shí)間復(fù)雜度O(lengthA+lengthB),空間復(fù)雜度O(lengthA)或O(lengthB)。

(3) 雙指針?lè)?,指針pa、pb分別指向鏈表A和B的首節(jié)點(diǎn)。

遍歷鏈表A,記錄其長(zhǎng)度lengthA,遍歷鏈表B,記錄其長(zhǎng)度lengthB。

因?yàn)閮蓚€(gè)鏈表的長(zhǎng)度可能不相同,比如題目所給的case,lengthA=5,lengthB=6,則作差得到 lengthB- lengthA=1,將指針pb從鏈表B的首節(jié)點(diǎn)開(kāi)始走1步,即指向了第二個(gè)節(jié)點(diǎn),pa指向鏈表A首節(jié)點(diǎn),然后它們同時(shí)走,每次都走一步,當(dāng)它們相等時(shí),就是交集的節(jié)點(diǎn)。

結(jié)尾

如今安卓開(kāi)發(fā)不像前幾年那么熱門(mén),但是高級(jí)人才依然緊缺,大家看著這句話是不是很熟悉,因?yàn)?web 高級(jí)人才也緊缺,c++ 高級(jí)人才一樣緊缺,那么到了人工智能時(shí)代,人工智能時(shí)代的高級(jí)人才也同樣會(huì)緊缺!似乎是高級(jí)人才的人在其他領(lǐng)域也是高級(jí)人才,而不是因?yàn)檫x擇了熱門(mén)才會(huì)一帆風(fēng)順。

網(wǎng)上高級(jí)工程師面試相關(guān)文章魚(yú)龍混雜,要么一堆內(nèi)容,要么內(nèi)容質(zhì)量太淺, 鑒于此我整理了如下安卓開(kāi)發(fā)高級(jí)工程師面試題以及答案幫助大家順利進(jìn)階為高級(jí)工程師,目前我就職于某大廠安卓高級(jí)工程師職位,在當(dāng)下大環(huán)境下也想為安卓工程師出一份力,這些問(wèn)題都是我認(rèn)真看過(guò)并且覺(jué)得不錯(cuò)才整理出來(lái),大家知道高級(jí)工程師不會(huì)像剛?cè)腴T(mén)那樣被問(wèn)的問(wèn)題一句話兩句話就能表述清楚,所以我通過(guò)過(guò)濾好文章來(lái)幫助大家理解,希望對(duì)大家有所幫助。

上述就是小編為大家分享的Android開(kāi)發(fā)者面試阿里等大廠遇到的問(wèn)題有哪些了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI