面試筆記記錄

1.AsyncTask 用法

onPreExecute()
在UI thread調(diào)用 顯示一個進(jìn)度條

doInBackground(void......params)
通過調(diào)用publishProgress()方法實時更新進(jìn)度 觸發(fā)onProgressUpdate

onProgressUpdate(Integer...values)

onPostExecute(Boolean result) 更新UI

2.JNI用法
(1).新建一個jni文件
public class JniTest{

private JniTest(){}

public static JniTest instance=null;

public static JniTest getInstance(){
    if(instance==null){
         instance=new JniTest();

     }
     return instance;

}


 static{
 
     System.loadLibrary("JniTest");
 }
  

 public static native String getJniString();

}

(2).build--->make project 在build目錄下找到生成的JniTest.class文件

(3).切換到更目錄下厕倍,執(zhí)行javah -jni com.example.firstndk.JniTest 生成
com_example_firstndk_JniTest.h文件

(4).新建一個JNI文件夾,并在此文件夾下來新建一個.c文件鳞溉,將.h文件中的內(nèi)容拷貝到
.c文件中,并且實現(xiàn)里面的空方法荤西。

(5).在JNI文件下新建android.mk和application.mk文件,然后Terminal切換到JNI目錄下拒炎,
執(zhí)行ndk-build ,生成so庫文件

3.AIDL用法
1.新建一個aidl的文件,同時建立一個aidl的接口文件校坑,比如BookManager.aidl穷遂,如果是Bean類型函匕,必須parcelable序列化,客戶端和服務(wù)端aidl文件同時存在蚪黑,且是一樣的盅惜。

2.服務(wù)端的AIDLService 要實現(xiàn)這個Booknamager.aidl接口中剩,并通過onBind()方法返回該接口的實例化對象

3.客戶端通過bindService方法建立鏈接,實現(xiàn)ServiceConnection接口抒寂,在onServiceConnected方法中把IBinder對象轉(zhuǎn)換成

aidl接口的實例化對象结啼,一旦鏈接成功,客戶端就可以和服務(wù)端進(jìn)行通信了屈芜。

private void attemptToBindService() {
Intent intent = new Intent();
intent.setAction("com.lypeer.aidl");
intent.setPackage("com.lypeer.ipcserver");
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}

4.BroadCastReceiver
(1).常駐型廣播-->靜態(tài)注冊(manifes中注冊)
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>

(2).非常駐型廣播-->動態(tài)注冊

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(String); //為BroadcastReceiver指定action郊愧,使之用于接收同action的廣播
registerReceiver(BroadcastReceiver,intentFilter);

一般動態(tài)注冊的廣播,要在onDestory中解除注冊井佑,否則會導(dǎo)致內(nèi)存泄露属铁。

5.ContentProvider
http://www.reibang.com/p/5e13d1fec9c9

(1).ContentProvider的作用是為不同的應(yīng)用之間的數(shù)據(jù)共享,提供統(tǒng)一的接口

(2).自定義
MyContentPovider extends ContentProvider{

指定authority="com.shuijian.authority"

實現(xiàn) inster躬翁,delete焦蘑,update,query

}

(3).其他應(yīng)用操作ContentProvider中的數(shù)據(jù)

獲得contentResolver=getContentResolver();

根據(jù)authority="com.shui.jian.authority"生成一個Uri,contentResolver通過這個Uri就可以操作

其他應(yīng)用中的ContentProvider中的數(shù)據(jù)了盒发,實現(xiàn)了數(shù)據(jù)的共享例嘱。

6.設(shè)計模式

A:單例模式7種(getInstance 方法一定要是public)
餓漢式
(1).
public class SingleTon{
private SingleTon(){}
private static SingleTon instance=new SingleTon();

private static getInstance(){xxxxxxxxx

 return instance;

}

}

(2).靜態(tài)代碼塊
public class SingleTon{
private SingleTon(){}
private static SingleTon instance;
static{
instance=new SingleTon()
}
private static getInstance(){ xxxxxx
return instance;
}

}
(3).靜態(tài)內(nèi)部類(holder)
public class SingleTon{
private SingleTon(){}
private static class SingleTonHolder{
private static SingleTon instance=new SingleTon();

}
private static getInstance(){ xxxxxx
return SingleTonHolder.instance;
}

}

(4)懶漢線程不安全
public class SingleTon{
private SingleTon(){}
private static SingleTon instance;

private static getInstance(){xxxxx
if(instance==null){
instance=new SingleTon();
}

 return instance;

}

}

(5)懶漢線程安全
public class SingleTon{
private SingleTon(){}
private static SingleTon instance;

private static synchrozied getInstance(){xxxxxxxx
if(instance==null){
instance=new SingleTon();
}

 return instance;

}

}
(6)懶漢線程安全
public class SingleTon{
private SingleTon(){}
private static SingleTon instance;

private static synchrozied getInstance(){xxxxxx
if(instance==null){
synchrozied(SingleTon.class){
if(instance==null){
instance=new SingleTon();
}
}
}

 return instance;

}

}
(7)
public enum SingleTon{
Instance;
}

B.工廠模式
public interface Sender{

public void send();

}

public Sender SMSSender implements Sender{

public void send(){
    System.out.print("sms);

}

}

public Sender QQSender implements Sender{

public void send(){
    System.out.print("QQsms);

}

}

(1).普通工廠模式

public class FactoryOne{

 poublic Sender produce(String type){
   if(type equals "sms"){
         return new SmsSender();
    }else if(type equals "QQ"){
 

      return new QQSmsSender();
    }

}

}

(2).工廠方法模式
public class FactoryTwo{
public Sender smsSender(){

        return SmsSender();
 }
  public Sender qqSender(){

        return QQSender();
 }         

}

(3).靜態(tài)工廠方法模式

public class FactoryTwo{
public static Sender smsSender(){

        return SmsSender();
 }
  public staic Sender qqSender(){

        return QQSender();
 }         

}

(4).抽象工廠模式

public interface Provider{
void produce();

}

public class FactorySms implements Provider{

public void produce(){
        return new SmsSender();

 }

}

public class FactoryQq implements Provider{

public void produce(){
        return new QQSender();

 }3

}

3.觀察者模式
public interface Observer {
void update();
}

public interface Observerable(){

void registerObserver(Observer observer);
void removerObserver(Observer observer);
void notifyObservers();

}

public class User1 implements Observer(){
public void update(){
System.print.out("收到消息1");
}
}

public class User2 implements Observer(){
public void update(){
System.print.out("收到消息2");
}
}
public class Watcher implements Observerable{
public List<Observer> list=new ArrayList<Observer>();

public registerObserver(Observer observer){
    list.add(observer);
}
  public removeObserver(Observer observer){
    list.remove(observer);
}

public void notifyObservers(){
   for(list:item){
     item.update();
   }   
}

public void opration(){

    notifyObservers();

}
}

4.適配器模式
interface PS2{ void isPS2}
interface USB { void isUsb}
public class Usber implements usb{ public void isUsb(){ }}

(1).類適配器

public AdapterOne extends Usber implements PS2{ public void isPs2{ isUsb()}}

(2).對象適配器

public AdapterOne implements PS2{ public AdapterOne(Usber usber){ this.usber=usber;} public void isPs2{

usber.isUsb()}}
(3).接口適配器

interface A { void A(),void B()宁舰,void C}

public abstract class Adapter implemntA{
void A(){} void B(){} void C(){}

}

public class MyAdapter extends Adpater{

  void A(){}......

}

5.策略模式

6.Builder模式(AlertDialog)
AlertDialog.Builder bulider= new AlertDialog.Builder(context).setTitle(R.string.app_name).setMessage("此版本已是最新版

本")
.setPositiveButton("好的", null);
AlertDialog alertDialog=bulider.show();

7.責(zé)任鏈模式

(1).構(gòu)造Request{ name ,reason,days, groupLeaderInfo ,managerInfo,departLeaderInfo}對象和Result{ isRatify ,info}結(jié)果對象

(2).interface Chain { Request request();//獲取當(dāng)前的Request Result proceed(Request request)//轉(zhuǎn)發(fā)Request}

(3).interface Ratify{ Result deal(Chain chain)}

(4). GroupLeader implements Ratify ( Result deal( return chain.proceed()or new Result))
Manager implements Ratify
CustomeLeader implements Ratify

(5)
RealChain implements Chain{
List<Ratify> list;
RealChain(List<Ratify> list,Requst requst ,int index){}

       request(){  return this.request}

       proceed(Request request){
         Result result=null;
         if(list.size>index){
           Ratify ratify=list.get(index);//得到當(dāng)前的責(zé)任人
           Realchain chain=new Realchain(list,request,index+1);//初始化責(zé)任的位置拼卵,以便轉(zhuǎn)發(fā)過來的時候使用心得責(zé)任人
           result= ratify.deal(chain);
           
         }
         return result

        }

}
(6).新建鏈條客戶端類
ChainClient {

List<Ratify> list;
addRatify(){ list.add()}//增加自定義的責(zé)任人

void executed(Request request){
List<Ratify> listNew= new List<Ratify>()
listNew.addAll(list);
listNew.add(new GroupLeader());
listNew.add(new Mannger());
listNew.add(new departLeader());
RealChain chain=new RealChain(list,request,0);

}

}

8.代理模式

public DynamicProxyHandle implements InvocationHandler{

  public DynamicProxyHandle(Object obj){
     this.obj=obj;
  }
  public Object invoke(Object proxy,Method method,Object[] args{

     Object proxy=method.invoke(obj,args);

     return proxy;

}

}

IBuy home=new Home();

DynamicProxyHandler dynamicHandler=new DynamicProxy(home);

Ibuy dynamicProxy=Proxy.newProxyInstance(home.getclass.getclassLoader,new Class[]{IBuy.class},dynamicHandler);

dynamicProxy.buy();

10.SQLite
(1).創(chuàng)建一個extendsSQLiteOpenHelper的類,并實現(xiàn)onOnCreate(建立表格的代碼)和onUpgrade(刪除原來表格明吩,重新建立表格)方法

间学。

當(dāng)表結(jié)構(gòu)發(fā)生變化的時候,會自動觸發(fā)onUpgrad()方法印荔,刪除原來的表,并重寫創(chuàng)建新的表結(jié)構(gòu)详羡。

(2).在創(chuàng)建一個OrderDao用于處理所有的數(shù)據(jù)操作仍律。
insert ,delete ,update, searchs

11.XML解析 解析速度快,占用內(nèi)存少实柠,一旦開始無法暫停
(1).Sax解析水泉,基于DefaultHandler,繼承DefaultHandler 實現(xiàn)5大方法

startDocument endDocument startElement endElement characters 函數(shù)驅(qū)動型

(2).Dom解析 占用的內(nèi)存比較大窒盐,容易OOM 雙層for循環(huán)草则, getElementByTagName()遍歷

(3).解析速度快,消耗內(nèi)存少蟹漓,很靈活,Pull解析 提供了開始標(biāo)簽START_TAG,END_TAG炕横,while循環(huán),更具標(biāo)簽進(jìn)行解析,可以根據(jù)需要跳

出解析(parse.next)

12.Git常用命令

git init
git add index.html
git commit -m " beizhu"

git commit -am "添加并提交"

git log git status 項目目前的狀態(tài)

git branch 查看當(dāng)前分支

git branch develop 創(chuàng)建分支

git branch develop origin/test

git checkout develop 切換倒develop分支

git checkout -b develop 創(chuàng)建develop并切換到develop

git merge develop

git branch -d develop 刪除本地分支

git branch -r -d origin/develop 刪除遠(yuǎn)程分支

git push -u origin master

git remote add origin http://自己的倉庫地址 注冊遠(yuǎn)程版本庫的地址

git remote remove origin 刪除遠(yuǎn)程版本庫地址

git tag 1.0

git push origin 1.0

git show 1.0

13.Java面向?qū)ο?/p>

(1)封裝
屬性封裝(private protected public )
方法封裝
內(nèi)部類(成員內(nèi)部類葡粒,靜態(tài)內(nèi)部類份殿,方法內(nèi)部類)

(2)繼承

(3)多態(tài)

引用多態(tài):Animal animal=new Animal()
Animal dog=new Dog();
方法多態(tài):

Animal animal=new Animal() 可以訪問Animal本類中的非private屬性和方法

Animal dog=new Dog(); 可以只能訪問Animal本類中的非private屬性和方法膜钓,如果有重寫父類的方法,調(diào)用的時調(diào)用的自己重寫的卿嘲,還有

自己添加的方法和屬性

14.Java泛型
(1).泛型類
public class Generics<T>{ private T key ; }
(2).泛型接口
public Interface Generics<T> { public T next();}
(3).泛型方法
public <T> T getKey(T t){}
(4).通配符和上下邊界
Generics<?>

上邊界:Generics<? extends T> 只能傳入T的子類

下邊界:Generics<? super T> 只能傳入T的父類

15.抽象類和接口的區(qū)別
(1).抽象類只能單繼承颂斜,而接口卻可以多實現(xiàn)

(2).抽象類中啥都有,但是抽象接口中一般不能有非抽象的方法拾枣。

(3).抽象類時對類的抽象沃疮,接口是對行為的抽象。(Door open close alarm

16.Java集合
(1)List
ArrayList 非同步的 基于動態(tài)數(shù)組 可以隨機(jī)訪問

LinkedList 非同步的 基于雙向鏈表 不可以隨機(jī)訪問梅肤,必須從開頭或者結(jié)尾遍歷列表 Collect.synczoiedList()變成同步列表

Vector 是同步的司蔬,其余和ArrayList一樣

Stack 繼承自Vector ,提供pop push ,peek凭语,empty葱她,search方法

17.Handler和Looper,Message之間的關(guān)系
(1).ActivityThread類 App進(jìn)程的初始化類,開啟死循環(huán)
Looper.prepareMainLooper()
Looper.loop();

(2).new 一個Hanlder對象的時候似扔,構(gòu)建方法中對Looper和MessageQueue進(jìn)行了初始化吨些,
當(dāng)我們調(diào)用handler.sendMessage()---->enqueueMessage(),將此Message注入到
Looper所在的MessageQueue隊列中

(3).一旦Looper所在的MessageQueue隊列中有message炒辉,loop()死循環(huán)方法中豪墅,通過

queue.next拿到消息,如果消息不為null黔寇,那么msg.target.dispatchMessage()處理消息偶器,

dispatchMessag內(nèi)部會調(diào)用handlerMessage()方法。

18.自定義View和ViewGroup
(1).4個構(gòu)造方法
new 缝裤,AttributeSet 屏轰,view 有style,api>=21且view有style屬性的時候調(diào)用

(2).onMeassure()
specMode=MeasureSpec.Exactly 精確值
specMode=MeasureSpec.AT_MOST 取最大值
specMode=MeasureSpec.UNSPECIFIED 父容器對當(dāng)前的View不限制

setMeasureDimension()設(shè)置View大小

onDraw View disPatchDraw ViewGruop

invalidate主線程 postInvalidate子線程

自定義屬性attrs.recycle()// 進(jìn)行對象回收

onLayout()中child.layout(), rquestLayout();

19.Android間的跨進(jìn)程通信 https://www.cnblogs.com/andy-songwei/p/10256379.html
(1).Activity可以跨進(jìn)程調(diào)用其他應(yīng)用程序的Activity憋飞;
打電話 startActivity()來啟動另外一個進(jìn)程的Activity霎苗。

Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:12345678"); 隱式Intent
startActivity(callIntent);
(2)ContentProvider可以跨進(jìn)程訪問其他應(yīng)用程序中的數(shù)據(jù)(以Cursor對象形式返回),
當(dāng)然榛做,也可以對其他應(yīng)用程序的數(shù)據(jù)進(jìn)行增唁盏、刪、改操作检眯;
Android系統(tǒng)本身提供了很多Content Provider厘擂,例如,音頻锰瘸、視頻刽严、聯(lián)系人信息等等。我們可以通過這些Content Provider獲得相關(guān)信息

的列表获茬。這些列表數(shù)據(jù)將以Cursor對象返回港庄。因此倔既,從Content Provider返回的數(shù)據(jù)是二維表的形式。

(3).Broadcast可以向android系統(tǒng)中所有應(yīng)用程序發(fā)送廣播鹏氧,
而需要跨進(jìn)程通訊的應(yīng)用程序可以監(jiān)聽這些廣播渤涌;
廣播是一種被動跨進(jìn)程通訊的方式。當(dāng)某個程序向系統(tǒng)發(fā)送廣播時把还,其他的應(yīng)用程序只能被動地接收廣播數(shù)據(jù)实蓬。這就象電臺進(jìn)行廣播一樣

,聽眾只能被動地收聽吊履,而不能主動與電臺進(jìn)行溝通安皱。

(4)Service這種可以跨進(jìn)程通訊的服務(wù)叫AIDL服務(wù)。
注意普通的Service并不能實現(xiàn)跨進(jìn)程操作艇炎,實際上普通的Service和它所在的應(yīng)用處于同一個進(jìn)程中酌伊,而且它也不會專門開一條新的線程

,因此如果在普通的Service中實現(xiàn)在耗時的任務(wù)缀踪,需要新開線程居砖。
要實現(xiàn)跨進(jìn)程通信,需要借助AIDL(Android Interface Definition Language)驴娃。Android中的跨進(jìn)程服務(wù)其實是采用C/S的架構(gòu)奏候,因而AIDL

的目的就是實現(xiàn)通信接口。

Socket 其實也可以實現(xiàn)跨進(jìn)程調(diào)用唇敞,但是一般使用在網(wǎng)絡(luò)通信中蔗草。

20.Android多線程實現(xiàn)
(1).繼承Thread類

(2).實現(xiàn)Runable接口

(3).線程池

Executors.newFixedThreadPool 定長線程池,可以控制最大并發(fā)數(shù)疆柔,超出的線程會在隊列中等待

Executors.newCachedThreadPool 可緩存的線程池咒精,如果線程池長度超多處理的需要,可以靈活回收空閑線程旷档,
如果沒有可以回收的狠轻,也可新建線程。

Executors.newScheduledThreadPool 帶有周期性質(zhì)的定長線程線程彬犯,支持定時和周期任務(wù)的執(zhí)行

Executors.newSingleThreadExecutor 單線程化的線程池,他確保了所有的任務(wù)都在一個線程中執(zhí)行查吊,不存在線程同步的問題谐区。

new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());

原理:https://www.cnblogs.com/dongguacai/p/6030187.html

21.MVC模式,MVP模式,MVVM模式

MVC模式
Modle JavaBean
View xml
Controler Activity業(yè)務(wù)邏輯,數(shù)據(jù)處理逻卖,UI處理
特點(diǎn):所有的數(shù)據(jù)處理宋列,UI處理都在Activity中,導(dǎo)致Activity上千行代碼评也,非常冗余

MVP模式 compositeSubscrition(Rxjava1) compositeDisposed(Rxjava2)
BasePresenter{ addDisposed() removeDisposed(compositeDispose.disposed())}

BaseView { loading() success()}

HomePresenter接口 HomeView接口

abstract BaseActivity<P extends BasePrestener> P createPresenter (){ new HomePresenter(this)};

MVVM模式
BaseViewModel{ addDisposed removeDisposed}

abstract BaseActivity<M extends BaseViewModel>
M createViewModel()
onDestory { viewModel.removeDisposed()}

HomeViewModel {
HomeViewModel(Activity context,ViewDataBinding databing){}

context.showDialog()
addDisposed{}   處理各種請求
context.disDialog() 

}

RecycleView多布局
onBindViewHolder onCreateViewHolder
ItemFruitBinding itemFruitBinding = DataBindingUtil.inflate(inflater, R.layout.item_fruit, parent, false);
return new FruitViewHolder(itemFruitBinding);

((FruitViewHolder) holder).getBinding().setItem(fruitBean);
((FruitViewHolder) holder).getBinding().executePendingBindings(); //解決databinding閃爍問題

22.框架原理
Glide
(1).三級緩存
內(nèi)存緩存(skipMemoryCache(true))
磁盤緩存 diskCacheStrategy(DiskCacheStrategy.None)

DiskCacheStrategy.None 不緩存

DiskCacheStrategy.All 緩存所有

DiskCacheStrategy.RESULT 緩存轉(zhuǎn)換過的

DiskCacheStrategy.SOURCE 只緩存原圖
網(wǎng)絡(luò)讀取
默認(rèn)的內(nèi)存磁盤緩存目錄:data/data/包名/cache/image_manager_disk

默認(rèn)的內(nèi)存磁盤緩存目錄:Android/data/包名/cache/

(2).源碼分析
Glide綁定生命周期炼杖,Glide.with()根據(jù)傳入的context對象和當(dāng)前的線程創(chuàng)建不同的

RequestManager實例灭返,如果是在UI線程中,context是Activity坤邪,則會創(chuàng)建一個能感知

Activity生命周期的RequestManager熙含,如果context是Fragment,則會創(chuàng)建一個能感知

Fragment生命周期的RequestManager,如果是在非UI線程中或者傳入ApplicationContext艇纺,則會一個applicationManager

對象怎静,能感知application的生命周期,在創(chuàng)建RequestManager的同時黔衡,也會創(chuàng)建一個

SupportRequestManagerFragment蚓聘,里面有onAttach,onStart,onStop,onDestory,onDetach等生命周期的方法,停止加載
圖片盟劫,釋放資源夜牡。

與Picasso的對比:
Glide可以加載Gif,Picasso不能.

Picasso.with()只能接受context作為參數(shù)侣签,但是glide的可以是
context,activity塘装,fragment glide能根據(jù)context的類型動態(tài)的
加載和釋放資源,更加靈活硝岗。

23.Retrofit2.0
(1).創(chuàng)建和用法
mRetorift=new Retrofit.Builder().baseUrl(Base_URL).client(new OkHttpClient())
.addConvertFactory(GsonConverterFactory.create())
.addCallAdapterFactory(Rxjava2CallAdapterFactory.create()).build().

Get請求
@GET("article/list/{type}?")
Call<QiushiModel> getInfoList(@Path("type") String type, @Query("page") int page);

GET請求提交數(shù)據(jù)
@GET
("MyWeb/RegServlet") Call<ResponseBody> getRegInfo(@QueryMap Map<String, String> map);

@GET
Observable<CheckVersionBean> getCheckVersion(@Url String url);

Post上傳多個文件氢哮,同時上傳表單數(shù)據(jù):
@POST("MyWeb/UPloadServlet")
Call<ResponseBody> postUploadFilesMultipartBody(@Body MultipartBody multipartBody);}

@POST("/member/login")
Observable<UserBean> getLogin(@Body RequestBody requestBody);

@FormUrlEncoded
@POST("MyWeb/RegServlet")
Call<ResponseBody> postFormFieldMap(@FieldMap Map<String , String> map);

(2).動態(tài)代理(代理類ApiService在程序運(yùn)行時動態(tài)生成,這種方式就叫做動態(tài)代理)
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();

      @Override public Object invoke(Object proxy, Method method, Object[] args)
          throws Throwable {
        // If the method is a method from Object then defer to normal invocation.
        if (method.getDeclaringClass() == Object.class) {
          return method.invoke(this, args);
        }
        if (platform.isDefaultMethod(method)) {
          return platform.invokeDefaultMethod(method, service, proxy, args);
        }
        ServiceMethod<Object, Object> serviceMethod =
            (ServiceMethod<Object, Object>) loadServiceMethod(method);
        OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
        return serviceMethod.callAdapter.adapt(okHttpCall);
      }
    });

}

Proxy.newProxyInstance(classLoader,class[],new InvocationHanlder({
public object invoke(){
return ;
}

}))

24.Rxjava 類似于觀察者模式型檀,是一個可以完成異步任務(wù)冗尤,基于事件的程序庫。
(1).

Observable(被觀察者)

Observer 觀察者 Consumer 消費(fèi)者胀溺,顧客 ,Subscriber 訂閱者

subscribe 訂閱

(2).取消訂閱
取消訂閱:
!dispose.isDisposed dispose.disposed();

compositeDispose.disposed();

compositeSubcrition.unScribe();

(3)操作符:
just ,from ,create map floatMap

map:將一種類型的數(shù)據(jù)轉(zhuǎn)換成另外一種類型的數(shù)據(jù)裂七。Integer, String
Observable.just(666).map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {//Integer---->String
return integer+"";
}
}).map(new Func1<String, Long>() {
@Override
public Long call(String s) {
return Long.parseLong(s);
}
}).subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
Log.i(TAG,"call:"+aLong);
}
});

floatMap:將原數(shù)轉(zhuǎn)換成新的Observable Student, Observable<String>

List<Student> students= DataUtils.getStudentList();
Observable.from(students).flatMap(new Func1<Student, Observable<String>>() {
@Override
public Observable<String> call(Student student) {
return Observable.from(student.getCourses());
}
}).subscribe(new Observer<String>() {
@Override
public void onCompleted() {

                }

                @Override
                public void onError(Throwable throwable) {

                }

                @Override
                public void onNext(String s) {
                    Log.i("TAG","couseName:"+s.toString());
                }
            });

(4).線程調(diào)度
Scheduler.io()
AndroidSchedulers.mainThread()
Observable.just(1, 2, 3, 4)
.subscribeOn(Schedulers.io()) // 指定 subscribe() 發(fā)生在 IO 線程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回調(diào)發(fā)生在主線程
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer number) {
Log.d(tag, "number:" + number);
}
});

25.Okhttp (RequestBody,MultipartBody)
(1).構(gòu)建請求的方式
new Okhttp().newCall(new Reuqest.Builder().url.post(requestBody).build()).enqueue(new Callback(){

 onFailture()
 
 onResponse()

}))

(2).原理

new Okhttp().newCall(request)--->RealCall()---->

同步--->execute()

異步---enqueue()----->dispatcher---->execute()

execute---> getResponseWithInterceptorChain()

getResponseWithInterceptorChain()----> new List<interceptors>().addAll(自定義的責(zé)任人)

Okhttp5大攔截器(https://blog.csdn.net/lxk_1993/article/details/101288561
RetryAndFollowUpInterceptor 負(fù)責(zé)請求的重試和重定向

BrideInterceptor 給請求添加對應(yīng)的 header 信息,處理響應(yīng)結(jié)果的 header 信息

CacheInterceptor 根據(jù)當(dāng)前獲取的狀態(tài)選擇 網(wǎng)絡(luò)請求 仓坞、讀取緩存背零、更新緩存。

ConnectInterceptor 建立 http 連接无埃。

CallServerInterceptor ----->Response {code ,message ,header,body} 讀寫網(wǎng)絡(luò)數(shù)據(jù)徙瓶。

RealInterceptorChain ----->遞歸調(diào)用,index+1
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);

Okhttp緩存 https://juejin.cn/post/6844903552339410958

緩存主要是通過header的Cache-Control來控制嫉称,
通過對Cache-Control進(jìn)行設(shè)置侦镇,即可實現(xiàn)不同的緩存策略。

max-age 訪問緩存的有效時間(一般很短)

max-state 可接受的緩存過期的時間

有網(wǎng)絡(luò)的時候:

可定義網(wǎng)絡(luò)攔截器來為Response設(shè)置緩存策略

無網(wǎng)絡(luò)的時候织阅,可以通過自定義攔截器設(shè)置Request使用緩存的策略

25.熱更新的實現(xiàn)原理
(1).AndroidFix (https://github.com/alibaba/AndFix
A:加載方式(init loadPatch addPatch)

mPatchManager = new PatchManager(this);
mPatchManager.init("1.0");
mPatchManager.loadPatch();
String patchFileString = Environment.getExternalStorageDirectory()
.getAbsolutePath() + APATCH_PATH;
mPatchManager.addPatch(patchFileString);

B:生成補(bǔ)丁的命令

apkpatch.bat -f 新apk -t 舊apk -o 輸出目錄 -k app簽名文件 -p 簽名文件密碼 -a 簽名文件別名 -e 別名密碼

將生成的補(bǔ)丁手動放到SD目錄下或者自己從云端下載下來壳繁。

C:原理

通過Native層,使用指針替換的方式替換bug,達(dá)到修復(fù)闹炉。
不能修改xml布局文件蒿赢,資源文件無法替換

(2).Bugly熱更新
A:集成方式
重寫SmapleApplicationLike extends DefaultApplicationLike

配置基準(zhǔn)thinkId,assembleRelease編譯生成基準(zhǔn)包渣触,修改代碼后羡棵,

根據(jù)基線版本生成補(bǔ)丁包,然后將補(bǔ)丁包patch_signed.apk上傳昵观。

B:原理
通過base.apk(base.dex) 和Fix.apk(fix.dex) 生成 patch.apk(patch.dex)

patch.dex和本地的base.dex 合并生成新的patch_base.dex文件晾腔,然后重新啟動

就可以了。(patch.dex插入到dexElements數(shù)組的前面啊犬,同時刪除舊的base.dex)

C:優(yōu)勢
Tinker熱補(bǔ)丁方案不僅支持類灼擂、So以及資源的替換,
Tinker不支持修改AndroidManifest.xml觉至,Tinker不支持新增四大組件

25.Jpush推送的實現(xiàn)原理
(1).從寫MyJPushMessageReceiver
處理自定義消息:

if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);

if (!TextUtils.isEmpty(message)) {

PushBean mBean = mGson.fromJson(message, PushBean.class);

mNotificationUtils.simpleNotify(context, mBean);

}

用戶打開通知:

JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())

(2).登錄后使用Id作為綁定的別名剔应。

JPushInterface.setAlias(getApplicationContext(), Integer.parseInt(bean.getResultObject().getUserId

()),bean.getResultObject().getUserId());

集成Jpush時,我們已經(jīng)把應(yīng)用的報名语御,appkey值峻贮,發(fā)到Jpush服務(wù)端進(jìn)行注冊,然后本地集成了JpushReceiver的BroadCastReceiver应闯,在

onReceiver

中纤控,通過官方提供的各種Action,分類處理各種服務(wù)端推送過來的消息碉纺。

26.Inflate解析文件的原理

inflate() ---->獲取根節(jié)點(diǎn)的名稱--->調(diào)用createViewFragTag通過class.forName反射的方式創(chuàng)建根View船万,

通過調(diào)用rInflate,遍歷該View下面的子View骨田,如果子View中還有子View耿导,那么會遞歸性的調(diào)用rInflate(),

直到遍歷完所有的View态贤,不在進(jìn)入while循環(huán)舱呻,最后調(diào)用parent.onFinishInflate()遍歷完結(jié)

27.Java虛擬機(jī)和Delivk虛擬機(jī)的區(qū)別

(1)Java虛擬機(jī)運(yùn)行的時java字節(jié)碼,但是Dalvik運(yùn)行的是dex文件

(2).Java虛擬機(jī)是基于棧悠汽,需要用指令來載入和操作數(shù)據(jù)箱吕,Dalvik是基于寄存器的,能有效減少指令的

分發(fā)和減少內(nèi)存的讀寫訪問柿冲。

28.Context 有哪幾種殖氏,都有什么區(qū)別

(1)Application繼承自ContextTheamWrap(帶主題的相關(guān)類,內(nèi)部包含了主題相關(guān)的接口姻采,可

以加在主題),Activity和Service繼承自ContextWrap,并不需要加載主題慨亲。

(2)生命周期不一樣婚瓜,applicaton和應(yīng)用的生命周期綁定,但是activity和service的自身的生

命周期綁定刑棵。

(3)使用的場景也會有不一樣巴刻,比如啟動一個activity,show一個dialog蛉签,或者

layotuInflate解析一個文件都只能使用activigty用了胡陪,application和service不可以。

(4)applicaton一個碍舍,activity和service有多個柠座。

28.線程中sleep和wait有啥區(qū)別。

(1).一個來自Thread類片橡,一個來自O(shè)bject類

(2).sleep沒有釋放鎖而wait方法釋放了鎖妈经,使得其他的線程可以使用同步代碼塊,或者方法.

sleep不出讓系統(tǒng)資源捧书,wait進(jìn)入線程池等待吹泡,出讓系統(tǒng)資源,一直等到notify/notifyAll,

才會從新進(jìn)入就緒隊列等待OS分配系統(tǒng)資源

(3).使用范圍不同经瓷,wait爆哑,notify和notifyAll只能在同步代碼塊,或者同步方法中使用舆吮,但是

sleep可以在任何地方使用揭朝。

(4).sleep必須要捕獲異常,但是wait,notify和notifyAll不需要捕獲異常歪泳。

29.queue和Stack有啥不同
(1).隊列先進(jìn)先出萝勤,棧先進(jìn)后出
(2).隊列只能在表尾進(jìn)行插入,在表頭的進(jìn)行刪除呐伞,棧只能在表尾(棧頂)進(jìn)行插入和刪
除操作

(3).遍歷數(shù)據(jù)的速度不同
隊列遍歷的速度更快敌卓,從隊頭或者隊尾開始遍歷,它是基于地址指針進(jìn)行遍歷伶氢,不需要另外的開
辟臨時空間趟径,不影響數(shù)據(jù)的結(jié)構(gòu)。
棧遍歷的速度比較慢癣防,只能從棧頂開始遍歷蜗巧,為了保證遍歷前的一致性,需要另外開辟臨時空間蕾盯。

(4).隊列:應(yīng)用的范圍也不一樣幕屹,線程池,消息傳遞機(jī)制,以及系統(tǒng)中的各種資源的管理等用到的一般都是隊列望拖。

棧的:問題的求解渺尘,函數(shù)調(diào)用和遞歸實現(xiàn),計算機(jī)中斷,數(shù)據(jù)保存和恢復(fù)说敏。

30.ArrayList和LinkedList有啥區(qū)別
(1).arrayList是基于動態(tài)數(shù)組鸥跟,linkedList是基于雙向鏈表。

(2).對于隨機(jī)訪問get和set盔沫,ArrayList優(yōu)于LinkedList医咨,因為ArrayList可以隨機(jī)定位,
而LinkedList要移動指針一步一步的移動到節(jié)點(diǎn)處架诞。

(3).對于新增和刪除操作add和remove拟淮,LinedList比較占優(yōu)勢,只需要對指針進(jìn)行修改即可侈贷,

而ArrayList要移動數(shù)據(jù)來填補(bǔ)被刪除的對象的空間.

31.Android項目安全性(混淆,加固)

minifyEanble true

proguard-android.txt

-keep 保留某個類不被混淆

-dontwarn去除警告

android四大組件不應(yīng)該被混淆

使用了自定義控件那么要保證它們不參與混淆

對第三方庫中的類不進(jìn)行混淆

使用了 Gson 之類的工具要使 JavaBean 類即實體類不被混淆

32.Android動畫
(1).View動畫
TranslateAnimation
ScaleAnimation
RotateAnimation
AlphaAnimation

AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
view.startAnimation(animation);

(2).屬性動畫 3.0之后

ObjectAnimator
ObjectAnimator.ofFloat(view, "rotationY", 0.0f, 360.0f).setDuration(1000).start();

ValueAnimator
ValueAnimator animator = ValueAnimator.ofFloat(0, mContentHeight); //定義動畫
animator.setTarget(view); //設(shè)置作用目標(biāo)
animator.setDuration(5000).start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation){
float value = (float) animation.getAnimatedValue();
view.setXXX(value); //必須通過這里設(shè)置屬性值才有效
view.mXXX = value; //不需要setXXX屬性方法
}
});

AnimatorSet 動畫組合惩歉,時播放、順序播放或延遲播放

ObjectAnimator a1 = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0f);
ObjectAnimator a2 = ObjectAnimator.ofFloat(view, "translationY", 0f, viewWidth);
......
AnimatorSet animSet = new AnimatorSet();
animSet.setDuration(5000);
animSet.setInterpolator(new LinearInterpolator());
//animSet.playTogether(a1, a2, ...); //兩個動畫同時執(zhí)行
animSet.play(a1).after(a2); //先后執(zhí)行
......//其他組合方式
animSet.start();

(3).幀動畫
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"

android:oneshot=["true" | "false"] >

<item
android:drawable="@[package:]drawable/drawable_resource_name"

android:duration="integer" />

</animation-list>

rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();

(4).6.0之后觸摸反饋動畫

Ripple

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#4285f4">
</ripple>

Reveal 揭露動畫

ViewAnimationUtils.createCircularReveal()

Transition Animation 轉(zhuǎn)場動畫

你需要給共享元素的兩個View設(shè)置相同的android:transitionName屬性值

layout/activity_a.xml

<ImageView
android:id="@+id/small_blue_icon"
style="@style/MaterialAnimations.Icon.Small"
android:src="@drawable/circle"
android:transitionName="@string/blue_name" />

layout/activity_b.xml

<ImageView
android:id="@+id/big_blue_icon"
style="@style/MaterialAnimations.Icon.Big"
android:src="@drawable/circle"
android:transitionName="@string/blue_name" />

String transitionName = getString(R.string.blue_name);

    ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, 

sharedView, transitionName);
startActivity(i, transitionActivityOptions.toBundle());

SVG矢量動畫,通過Path路徑構(gòu)建動畫

33.安卓內(nèi)存優(yōu)化
https://blog.csdn.net/tuke_tuke/article/details/52316285

Bitmap不被使用的時候recycle掉

Cursor和I/O流及時關(guān)閉

BroadCastReceiver、Service

線程不再需要繼續(xù)執(zhí)行的時候要記得及時關(guān)閉,開啟線程的時候吵冒,使用線程池

使用Rxjava做網(wǎng)絡(luò)請求的時候,在Activity銷毀的時候争涌,取消訂閱

使用FindBus和Lint代碼檢查工具,提高代碼質(zhì)量

34.UDP&TCP的區(qū)別 https://www.cnblogs.com/williamjie/p/9390164.html

相同點(diǎn):UDP協(xié)議和TCP協(xié)議都是傳輸層協(xié)議

TCP:面向連接的,可靠性高辣恋,中間會有三次握手來建立連接亮垫,但是占用的系統(tǒng)資源高,容易被攻擊伟骨,基于字節(jié)流的饮潦。

Socket socket = new Socket("111.111.11.11", 12306);//111.111.11.11為我這個本機(jī)的IP地址,端口號為12306.
socket.getInputStream

socket.getOutputStream

UDP是面向非連接的携狭,可靠性低继蜡,在網(wǎng)絡(luò)不好的時候,容易丟包逛腿,但是傳輸速度很快稀并,效率比較高,基于用戶數(shù)據(jù)報的单默。

DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, 12306);
socket.send(packet);

socket.receive(receiverPacket);

35.http和https

http://www.reibang.com/p/7a40e874f6c2?utm_source=oschina-app

https客戶端和服務(wù)端建立SSL連接的過程:

(1).客戶端發(fā)起請求碘举,服務(wù)端會把公鑰發(fā)給客戶端。

(2).android客戶端利用本地證書對公鑰進(jìn)行校驗搁廓,合法的話引颈,生成一個隨機(jī)值并用服務(wù)端給的公鑰進(jìn)行加密耕皮,

然后傳給服務(wù)端,服務(wù)端利用私鑰進(jìn)行解密线欲,此時客戶端和服務(wù)端都有這個隨機(jī)值明场,然后利用這個隨機(jī)值作為

二邊的私鑰,建立SSL連接李丰,開始通信。

36.Kotlin

(1).?. null safety,object直接創(chuàng)建單例,compain Object (相當(dāng)于static,可以通過類.方法名調(diào)用)
屬性委托(protected var isLogin:Boolean by Preference(Constant.LOGIN_KEY,false))

(2).主要構(gòu)造函數(shù)和次級構(gòu)造函數(shù)(Secondary Constructor是定義在類體中逼泣。第二趴泌,Secondary Constructor
可以有多個,而Primary Constructor只會有一個拉庶。)
主要構(gòu)造函數(shù):
class Person constructor(username: String, age: Int){

private val username: String

private var age: Int

init{
this.username = username

this.age = age

   }

}

class Person (username: String, age: Int){

private val username: String

private var age: Int

init{
this.username = username

this.age = age

   }

}
次級構(gòu)造函數(shù):
class User{

private val username: String

private var age: Int

constructor(username: String, age: Int){

this.username = username

this.age = age

}

}

(3).為什么要轉(zhuǎn)戰(zhàn)kotlin
kotlin比Java要簡單嗜憔。它去除了很多Java里面的冗余代碼,而且有很多新的特性
比如說不用findViewById,在xml定義Id之后,直接可以在代碼中引用氏仗,
類擴(kuò)展吉捶,直接給類添加方法,而不需要繼承皆尔。
fun Activity.showSnackMsg(msg:String){
val snackbar=Snackbar.make(this.window.decorView,msg,Snackbar.LENGTH_SHORT)
val view=snackbar.view
view.findViewById<TextView>(R.id.snackbar_text).setTextColor(ContextCompat.getColor(this,R.color.white))
snackbar.show()
}

(4).聲明變量呐舔,支持面向?qū)ο蠛兔嫦蜻^程編程, range操作符 for(1 in 1...15)
var a:Int  kotlin類缺省是final的慷蠕。因為kotlin支持多重類繼承珊拼。開放類代價要比final類高很多,
如果一個類可以被繼承或者方法被重寫,必須open

PlayAndroid

設(shè)置白天黑夜模式:
value-night DayNight主題
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)

37.啟動模式

https://www.cnblogs.com/claireyuancy/p/7387696.html

Standard 標(biāo)準(zhǔn)模式 每次啟動一個Activity都會又一次創(chuàng)建一個新的實例入棧流炕,無論這個實例是否存在

SingleTop 棧頂復(fù)用模式 須要創(chuàng)建的Activity已經(jīng)處于棧頂時澎现,此時會直接復(fù)用棧頂?shù)腁ctivity。
不會再創(chuàng)建新的Activity每辟, onNewIntent會被回調(diào)

SingleTask 棧內(nèi)復(fù)用模式 將存在棧中的Activity上面的其他Activity所有銷毀剑辫,使它成為棧頂,onNewIntent

SingleInstance 單實例模式 系統(tǒng)會為它創(chuàng)建一個單獨(dú)的任務(wù)棧渠欺,由于棧內(nèi)復(fù)用的特性妹蔽,不會創(chuàng)建新的Activity,除非這個獨(dú)特的任務(wù)棧

被系統(tǒng)銷毀

38.Android系統(tǒng)架構(gòu) (https://blog.csdn.net/cpq37/article/details/5708649)

(1).Application 應(yīng)用層

(2).Application Fragmework

ActivityManager PackageManager WindowManager NotificationManager

(3).Library 系統(tǒng)運(yùn)行庫

SQLite Webkit

(4).Linx內(nèi)核層
Wifi Driver USB Driver CameraDriver

  1. Android性能分析
    LeakCanary 它能實時的告訴我具體哪個類發(fā)現(xiàn)了內(nèi)存泄漏

TraceView 測量函數(shù)耗時

SysTrace

MAT

Hierarchy(hai:ra:k) Viewer 測量View的布局層次峻堰,已經(jīng)每個View的刷新時間讹开。
使用Merge,ViewStub標(biāo)簽優(yōu)化重復(fù)的布局捐名,盡量多使用Constraintlayout

使用自定義View

40.哪些情況可能會導(dǎo)致內(nèi)存泄露

(1).資源使用完沒有關(guān)閉
BroadCastReceiver File Crusor database Bitmap

(2).Timer或者TimeTask不使用的時候旦万,必須取消,new thread镶蹋。

(3).Static Context Static Drawable 會導(dǎo)致內(nèi)存leak.

Static 集合類成艘,比如ArrayList ,Vector 如果不及時的設(shè)置為null的話赏半,

也可能導(dǎo)致內(nèi)存泄露。

41.如果避免OOM

(1).減少內(nèi)存對象的暫用淆两。
盡量少用Bitmap ,減少資源圖片的大小断箫,過大的圖片可以壓縮,盡量不用Enum

或者設(shè)置暫用內(nèi)存較低的解碼格式decode formate
ARGB_888【8bit】
RGB_564 【4bit】

(2).自定義View的時候秋冰,盡量不要在onDraw里面new 對象仲义, 自定屬性的時候,記得recycle().

(3).避免內(nèi)存泄露(內(nèi)存對象的泄漏剑勾,會導(dǎo)致一些不再使用的對象無法及時釋放埃撵,
這樣一方面占用了寶貴的內(nèi)存空間,很容易導(dǎo)致后續(xù)需要分配內(nèi)存的時候虽另,空閑空間不足而出現(xiàn)OOM)

42.ANR怎么樣避免和解決暂刘?

(1).應(yīng)該避免在UI線程中處理復(fù)雜的邏輯和計算,還有耗時操作捂刺。

(2).在Activity的onCreate谣拣,onResume里面也不要做耗時的操作。盡量把耗時的操作交給異步線程族展。

按鍵或觸摸事件在5s內(nèi)主線程沒喲響應(yīng)

BroadcastReceiver 前臺廣播在10s內(nèi)森缠,沒有返回值,也會導(dǎo)致ANR

啟動的Service在20s內(nèi)沒有完成苛谷,也會導(dǎo)致ANR

43.android線程間的通信

handler runOnUiThread view.post Rxjava .io .mainThread(線程調(diào)度)

44.Android屏幕適配
(1).盡量用dp適配屏幕辅鲸,sp作為字體單位

(2).xml布局的時候,盡量使用weight

(3).代碼中獲取屏幕的寬高腹殿,按比例動態(tài)設(shè)置独悴,

(4).特殊機(jī)型,可以使用value-sw1080,mipmap-w600dp

(5).約束布局

46.android進(jìn)程甭辔荆活機(jī)制
內(nèi)存不足
省電機(jī)制
用戶清理

如何笨坛矗活進(jìn)程:
(1).鎖屏的時候,掛1像素的Activity到前臺自沧,提高進(jìn)程的優(yōu)先級坟奥,鎖屏的時候關(guān)閉。

(2).啟動一個前臺Service拇厢,Service爱谁。SERVICE_ID=1

(3).雙進(jìn)程拉活。

(4).監(jiān)聽開機(jī)孝偎,鎖屏等系統(tǒng)廣播拉活访敌。

(5).監(jiān)聽其他大廠的廣播,拉活衣盾。

47.打包優(yōu)化

代碼混淆
去除無用的資源 shrinkResouce true
圖片壓縮
so 庫配置 abiFilter armeabi armeabi-v7a

把圖片放在云端寺旺,通過鏈接聯(lián)網(wǎng)加載爷抓。

48.ButterKnife源碼分析 https://www.cnblogs.com/tony-yang-flutter/p/12483127.html

ButterKnife.bind(this)----> 會構(gòu)造一個包名+類名+_ViewBinding的構(gòu)造函數(shù)類,通過constructor.newInstance()返回這個綁定的對

象阻塑。

MainActivity_ViewBind.java ,這個類在編譯的時候蓝撇,通過ButterProcessor生成的,繼承了抽象類

AbstractProcessor,AbstractProcessor實現(xiàn)了

Processor接口陈莽,init getSupportAnnotationTypes getSupportedAnnotations ,process

最重要的就是Process方法渤昌,,首先通過findAndParseTarget()得到一個bindingMap對象走搁,這個對象 類名稱(key)耘沼, 注解屬性

(BindingSet),

BindingSet存儲的是生成類的基本信息以及注解元素的基本信息朱盐,通過遍歷這個bindingMap生產(chǎn)對應(yīng)的java文件。

當(dāng)我們調(diào)用ButterKnife的bind()方法的時候菠隆,它會根據(jù)類的全限定類型兵琳,找到相應(yīng)的模板代碼。

45.GreenDao ,Realm數(shù)據(jù)庫 對象關(guān)系數(shù)據(jù)映射
Realm和GreenDAO有很大的不同骇径,Realm本身就是一種數(shù)據(jù)庫躯肌,而且是可以支持跨平臺的數(shù)據(jù)庫,比SQLite更輕量級破衔,速度也更快清女,支持

JSON格式、數(shù)據(jù)變更通知晰筛、數(shù)據(jù)同步等等特性.

http://www.reibang.com/p/12c46d38f6a9

@Entity
public class Student {
@Id(autoincrement = true) Long id;
String name;
int age;
String grades;
@ToMany(referencedJoinProperty = "studentId")
List<Course> courseList;
}
生成 DaoMaster DaoSesion 各種Dao類

Realm.init(this);支持新增字段
Realm.setDefaultConfiguration(configuration);

public class Student extends RealmObject{}
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Student student = new Student();
student.setName("小明");
student.setAge(18);
student.setGrades("一年級");
realm.copyToRealm(student);
}
});

49.Flutter

widget在flutter里基本是一些UI組件

有兩種類型的widget嫡丙,分別是statefulWidget 和 statelessWidget兩種

statelessWidget不會自己重新構(gòu)建自己,但是statefulWidget

Hot Reload

50.Glide 三級緩存源碼分析
http://www.reibang.com/p/ba7f38ede854

51.App啟動優(yōu)化读第。
1s 左右的白屏閃現(xiàn)曙博, 低版本黑屏
windowBackground windowIsTranslucent
沒有白屏但是中間還是有一小段不可見,增加了Splash 的廣告頁怜瞒,增加了倒計時
TraceView檢測函數(shù)的耗時情況父泳,一個是懶加載,在一個就是使用線程池初始化 newSingleExcutor
精簡xml布局

52.HashMap原理
HashMap(https://juejin.cn/post/6844904084219101197
JDK1.7---數(shù)組+鏈表 JDK1.8---數(shù)組+鏈表+紅黑二叉樹
map.put(k,v)實現(xiàn)原理
前提條件吴汪,如果table等于null惠窄,那就resize擴(kuò)容,初始化table
(1)首先將k,v封裝到Node對象當(dāng)中(節(jié)點(diǎn))漾橙。
(2)然后它的底層會調(diào)用K的hashCode()方法得出hash值杆融。
(3)通過哈希表函數(shù)/哈希算法,將hash值轉(zhuǎn)換成數(shù)組的下標(biāo)Index近刘,
下標(biāo)位置上如果沒有任何元素擒贸,就把Node添加到這個位置上臀晃。
如果當(dāng)前位置有元素,那就比較當(dāng)前位置Node節(jié)點(diǎn)的key值和hash值介劫,
如果相等徽惋,說明key存在,直接替換值即可座韵,如果不存在险绘,那說明,當(dāng)前的
節(jié)點(diǎn)可能是TreeNode,或者鏈表誉碴,如果說下標(biāo)對應(yīng)的位置是TreeNode
(instanceof TreeNode)宦棺,直接插入,
否者就一定是鏈表黔帕,此時代咸,就會拿著k和鏈表上每個節(jié)點(diǎn)的k進(jìn)行equal比較。
如果所有的equals方法返回都是false成黄,那么這個新的節(jié)點(diǎn)將被添加到鏈表的
末尾(JDK1.8尾插法)呐芥。如果其中有一個equals返回了true,那么這個節(jié)點(diǎn)的
value將會被覆蓋奋岁∷嘉粒【如果鏈表的長度大于8且數(shù)組長度大于64的時候,
就會把鏈表轉(zhuǎn)換成紅黑二叉樹】
map.get(k)實現(xiàn)原理
(1).先調(diào)用k的hashCode()方法得出哈希值闻伶,并通過哈希算法轉(zhuǎn)換成數(shù)組的下標(biāo)滨攻。
(2).通過上一步哈希算法轉(zhuǎn)換成數(shù)組的下標(biāo)之后,在通過數(shù)組下標(biāo)快速定位到某個位置上蓝翰。
如果這個位置上什么都沒有光绕,則返回null,如果當(dāng)前位置有元素霎箍,那就比較當(dāng)前位置Node節(jié)點(diǎn)
的key值和hash值奇钞,如果相等,說明改節(jié)點(diǎn)就在table數(shù)組中漂坏,直接返回景埃,否則,如果這個位置
上是紅黑二叉樹(instanceof TreeNode)顶别,就會調(diào)用getTreeNode(hash,key)返回當(dāng)前節(jié)點(diǎn)谷徙,
否則就是鏈表,那么它就會拿著參數(shù)K和單向鏈表上的每一個節(jié)點(diǎn)的K進(jìn)行equals驯绎,
如果所有equals方法都返回false完慧,則get方法返回null。如果其中一個節(jié)點(diǎn)的K和參數(shù)K進(jìn)行equals返回true剩失,
那么此時該節(jié)點(diǎn)的value就是我們要找的value了屈尼,get方法最終返回這個要找的value册着。

hash(key)的源碼
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
key.hashCode() 獲取到的hashcode無符號右移16位并和原h(huán)ashCode進(jìn)行^運(yùn)算 ,
這樣做的目的是為了讓高位與低進(jìn)行混合脾歧,讓兩者都參與運(yùn)算甲捏,以便讓hash值分布更加均勻。

數(shù)組索引index的計算采用的都是hash&(table.length-1)

千里馬駿

1.ConstraintLayout 布局 百分比布局

UI適配鞭执,多屏幕適配

2.Binder原理

3.new OkHttp().newCall(new Request).execute()

new OkHttp().newCall(new Request).enqueue() 按照調(diào)用方式說原理

4.點(diǎn)擊桌面的圖標(biāo)司顿,Application啟動原理。

5.recycleview四級緩存機(jī)制 https://blog.csdn.net/u014644594/article/details/105771763
mAttachedScrap 緩存當(dāng)前頁面的數(shù)據(jù)

mCachedViews 緩存剛剛劃出屏幕外的數(shù)據(jù)(2個)

RecycleViewPool 緩存Cache中出來的數(shù)據(jù)(5)

先充Scrap和Cache中取ViewHoder,如果沒有取到兄纺,就從RecycleViewPool 中取大溜,如果還是沒有取到,就CreateViewHolder

6.垃圾回收算法

compare比較算法

7.虛擬機(jī)內(nèi)部區(qū)域劃分

酷派外包:
負(fù)責(zé)哪些模塊估脆,問ListView和RecycleView緩存機(jī)制的區(qū)別钦奋。
UI刷新的原理
Fragment和Activity的區(qū)別
A:生命周期不同
B:可以在XML在靈活的添加Fragment,Activity不能疙赠,F(xiàn)ragment是3.0之后引入的锨苏,通過FragmentManager管理,Activity是四大組件之一棺聊,通過ActivityManager管理。
C:從靈活性上來說贞谓,F(xiàn)ragment
Context為null的原因

OPOP外包:
項目中的難點(diǎn)限佩,如何解決的。
自己創(chuàng)建線程池裸弦,需要傳遞哪些參數(shù)祟同。

OkHttp的緩存機(jī)制
https://juejin.cn/post/6844904095233376269
Http和Https的有什么區(qū)別。證書主要是放在服務(wù)端還是客戶端?

SoftReference
WeakReference

Handler導(dǎo)致內(nèi)存泄露的例子理疙,內(nèi)部類導(dǎo)致內(nèi)存泄露的例子晕城。
http://www.reibang.com/p/b56731447179

反射(學(xué)習(xí)一下)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市窖贤,隨后出現(xiàn)的幾起案子砖顷,更是在濱河造成了極大的恐慌,老刑警劉巖赃梧,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滤蝠,死亡現(xiàn)場離奇詭異,居然都是意外死亡授嘀,警方通過查閱死者的電腦和手機(jī)物咳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹄皱,“玉大人览闰,你說我怎么就攤上這事芯肤。” “怎么了压鉴?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵崖咨,是天一觀的道長。 經(jīng)常有香客問我晴弃,道長掩幢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任上鞠,我火速辦了婚禮际邻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘芍阎。我一直安慰自己世曾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布谴咸。 她就那樣靜靜地躺著轮听,像睡著了一般。 火紅的嫁衣襯著肌膚如雪岭佳。 梳的紋絲不亂的頭發(fā)上血巍,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機(jī)與錄音珊随,去河邊找鬼述寡。 笑死,一個胖子當(dāng)著我的面吹牛叶洞,可吹牛的內(nèi)容都是我干的鲫凶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼衩辟,長吁一口氣:“原來是場噩夢啊……” “哼螟炫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起艺晴,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤昼钻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后封寞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體换吧,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年钥星,在試婚紗的時候發(fā)現(xiàn)自己被綠了沾瓦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖贯莺,靈堂內(nèi)的尸體忽然破棺而出风喇,到底是詐尸還是另有隱情,我是刑警寧澤缕探,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布魂莫,位于F島的核電站,受9級特大地震影響爹耗,放射性物質(zhì)發(fā)生泄漏耙考。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一潭兽、第九天 我趴在偏房一處隱蔽的房頂上張望倦始。 院中可真熱鬧,春花似錦山卦、人聲如沸鞋邑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枚碗。三九已至,卻和暖如春铸本,著一層夾襖步出監(jiān)牢的瞬間肮雨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工箱玷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酷含,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓汪茧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親限番。 傳聞我的和親對象是個殘疾皇子舱污,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 51、類ExampleA繼承Exception弥虐,類ExampleB繼承ExampleA扩灯。 有如下代碼片斷: try...
    Nathan_Yang閱讀 623評論 0 0
  • 中華新聞 側(cè)邊欄setContentView(R.layout.activity_main);// 添加側(cè)邊欄se...
    SmNiuhe閱讀 512評論 0 0
  • 答: 方法的重載屬于編譯時多態(tài),方法名相同參數(shù)列表不同,返回值必須相同或都沒有返回值類型。方法的重寫屬于運(yùn)行時多態(tài)...
    JA尐白閱讀 882評論 1 19
  • 面試必背 會舍棄霜瘪、總結(jié)概括——根據(jù)我這些年面試和看面試題搜集過來的知識點(diǎn)匯總而來 建議根據(jù)我的寫的面試應(yīng)對思路中的...
    luoyangzk閱讀 6,755評論 6 173
  • 黑馬程序員的視頻: 只要精通一門技能就能防身珠插,切不可范范而學(xué)不可只懂皮毛。 Log.v() 最低級颖对,打印意義最小的...
    lwwlsky閱讀 1,139評論 0 2