德豐集團面試:
1.熱更新的實現(xiàn)原理
andfix直接在native層替換原有的方法止状。由于底層替換原理只支持方法替換集峦,不支持方法的增加
和減少速妖,成員字段的增加和減少
在android5.0之前,每個android應(yīng)用只含有一個dex文件,dex的方法數(shù)量被限制在了65535之內(nèi)
,導(dǎo)致apk引入大量第三方sdk后方法數(shù)量超過限制無法編譯通過。為了解決這個問題,Google推
出多dex文件的解決方案multidex弯囊,一個apk可以包含多個dex文件。通過Multidex.install
(this)完成dex文件的加載。
在編譯時通過新舊兩個Dex生成差異patch.dex,將差異patch.dex重新和原始安裝包的舊Dex合并
還原為新的Dex,這個過程是在后臺進程中進行,由于采用ClassLoader機制看彼,所以需要app重啟茁计。
2.推送的實現(xiàn)原理
常駐型的廣播毒返,onReceiver
(JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction()))
Logger.d(TAG, "[MyReceiver] 接收到推送下來的自定義消息: " + bundle.getString
(JPushInterface.EXTRA_MESSAGE));
在app登錄的時候盆赤,一般把用戶的id作為唯一的推送標識,進行綁定,然后推送的時候,可以根
據(jù)這個id進行推送。
3.JNI使用
4.Inflate解析文件的原理
(1).LayoutInflater其實就是使用Android提供的pull解析方式來解析布局文件的
(2).會調(diào)用inflate(XmlPullParse parse ,ViewGruop root ,boolean AttachToRoot)
創(chuàng)建根View ,createViewFromTag(節(jié)點名稱,參數(shù)),根據(jù)節(jié)點名稱創(chuàng)建View對象,在
createViewFromTag()方法內(nèi)部有會去調(diào)用CreateView方法盏档,然后使用
反射的方式創(chuàng)建View的實例并返回稚配。
(3).會遞歸性的調(diào)用rInflate(XmlPullParse ,ViewGroup,AttributeSet)這個根布局下面
的子元素,createViewFromTag()方法來創(chuàng)建View的實例尊流,然后還會在rInflate()方法來查找這
個View下的子元素响疚,每次遞歸完成后則將這個View添加到父布局當中
Root為null,attachToRoot將失去作用
Root不為null,attachToRoot為true肄程,這時為給該布局指定一個布局root
Root不為null,attachToRoot為false,布局文件最外層的所有l(wèi)ayout屬性進行屬性將會失效拓提。
5.java虛擬機和Delvik虛擬機的區(qū)別
A:JVM運行的java字節(jié)碼(節(jié)碼碼按照class文件格式的規(guī)范組成了class文件)蹦疑,但是Dalvik運
行的dex文件(dx工具轉(zhuǎn)換而來)
B:JVM是基于棧判莉,必須使用指令來載入和操作數(shù)據(jù)锰镀,所以需要的指令會更多,而Dalvik是基于寄
存器 的泳炉,(有效的減少指令的分發(fā)和減少內(nèi)存的讀寫訪問)
C:Dalvik可執(zhí)行文件的體積更泻斗ぁ(Class文件包含多個不同的方法簽名,如果A類文件引用B類文
件中的方法花鹅,方法簽名也會被復(fù)制到A類文件中,同樣的大量的字符串常量也會在多個多個文件
中被重復(fù)使用,這些冗余信息會增加文件體積)顷歌,SDK中有個Dx工具負責將Java字節(jié)碼轉(zhuǎn)換
dalvik字節(jié)碼(class文件轉(zhuǎn)換為dex文件),所有的類文件共享一個常量池私杜,使得相同的字符串
泊柬,常量在dex文件中只出現(xiàn)一次蜡娶,較小文件的體積速梗。
6.Context 有哪幾種春宣,都有什么區(qū)別
Applicaton则酝,Activity,Service 一共三種
區(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有多個。
7.線程中sleep和wait有啥區(qū)別收厨。
(1).一個來自Thread類晋柱,一個來自O(shè)bject類
(2).sleep沒有釋放鎖而wait方法釋放了鎖,使得其他的線程可以使用同步代碼塊诵叁,或者方法
雁竞。
sleep不出讓系統(tǒng)資源,wait進入線程池等待,出讓系統(tǒng)資源碑诉,一直等到notify/notifyAll
喚醒等待池中的所有線程彪腔,才會進入就緒隊列等待OS分配系統(tǒng)資源。
(3).使用范圍不同进栽,wait德挣,notify和notifyAll只能在同步代碼塊,或者同步方法中使用快毛,但是
sleep可以在任何地方使用格嗅。
(4).sleep必須要捕獲異常,但是wait,notify和notifyAll不需要捕獲異常唠帝。
8.queue和Stack有啥不同
(1).隊列先進先出屯掖,棧先進后出
(2).隊列只能在表尾進行插入,在表頭的進行刪除襟衰,棧只能在表尾(棧頂)進行插入和刪
除操作
(3).遍歷數(shù)據(jù)的速度不同
隊列遍歷的速度更快贴铜,從隊頭或者隊尾開始遍歷,它是基于地址指針進行遍歷瀑晒,不需要另外的開
辟臨時空間绍坝,不影響數(shù)據(jù)的結(jié)構(gòu)。
棧遍歷的速度比較慢瑰妄,只能從棧頂開始遍歷陷嘴,為了保證遍歷前的一致性,需要另外開辟臨時空間间坐。
(4).隊列:應(yīng)用的范圍也不一樣,線程池您觉,消息傳遞機制获诈,以及系統(tǒng)中的各種資源的管理等用到的一般都是隊列管嬉。
棧的:問題的求解,函數(shù)調(diào)用和遞歸實現(xiàn),計算機中斷蜈七,數(shù)據(jù)保存和恢復(fù)。
9.ArrayList和LinkedList有啥區(qū)別
(1).arrayList是基于動態(tài)數(shù)組莫矗,linkedList是基于雙向鏈表飒硅。
(2).對于隨機訪問get和set,ArrayList優(yōu)于LinkedList作谚,因為ArrayList可以隨機定位三娩,而LinkedList要移動指針一步一步的移動到節(jié)點處。
(3).對于新增和刪除操作add和remove妹懒,LinedList比較占優(yōu)勢雀监,只需要對指針進行修改即可,而ArrayList要移動數(shù)據(jù)來填補被刪除的對象的空間.
性能上的區(qū)別:
1.對ArrayList和LinkedList而言,在列表末尾增加一個元素所花的開銷都是固定的会前。對 ArrayList而言好乐,主要是在內(nèi)部數(shù)組中增加一項,指向所添加的元素瓦宜,偶爾可能會導(dǎo)致對數(shù)組重新進行分配蔚万;而對LinkedList而言,這個開銷是 統(tǒng)一的临庇,分配一個內(nèi)部Entry對象反璃。
2.在ArrayList集合中添加或者刪除一個元素時,當前的列表所所有的元素都會被移動苔巨。而LinkedList集合中添加或者刪除一個元素的開銷是固定的版扩。
3.LinkedList集合不支持 高效的隨機隨機訪問(RandomAccess),因為可能產(chǎn)生二次項的行為侄泽。
4.ArrayList的空間浪費主要體現(xiàn)在在list列表的結(jié)尾預(yù)留一定的容量空間礁芦,而LinkedList的空間花費則體現(xiàn)在它的每一個元素都需要消耗相當?shù)目臻g。
對于需要快速插入悼尾,刪除元素柿扣,應(yīng)該使用LinkedList,如果需要快速隨機訪問元素闺魏,應(yīng)該使用ArrayList未状。
六號網(wǎng)絡(luò)面試:
1.低耦合高內(nèi)聚(面向?qū)ο笤瓌t:低耦合高內(nèi)聚,多聚合析桥,少繼承)
內(nèi)聚:每個模塊盡可能獨立完成自己的功能司草,不依賴于模塊外部的代碼。
耦合:模塊與模塊之間接口的復(fù)雜程度泡仗,模塊之間聯(lián)系越復(fù)雜耦合度越高埋虹,牽一發(fā)而動全身。
2.Android項目安全性(混淆,加固)
minifyEanble true
proguard-android.txt
-keep 保留某個類不被混淆
-dontwarn去除警告
android四大組件不應(yīng)該被混淆
使用了自定義控件那么要保證它們不參與混淆
對第三方庫中的類不進行混淆
使用了 Gson 之類的工具要使 JavaBean 類即實體類不被混淆
定義的Application* 實體類
JNI中調(diào)用的類
3.Android模塊化開發(fā)
4.Android動畫(https://github.com/OCNYang/Android-Animation-Set)
視圖動畫
幀動畫
屬性動畫 ObjectAnimator ValueAnimator,Animator
觸摸反饋動畫娩怎,ripple ,selectableItemBackground,selectableItemBackgroundBorderless
轉(zhuǎn)場動畫搔课,ActivityOptions.makeSceneTransitionAnimation(),transitionName
Slide,Fade 在activity的onCreate方法中。
揭露動畫
createCircularReveal
SVG矢量動畫 Vector
添加動畫的矢量圖片可為 <group> 以及 <path> 元素的屬性添加動畫截亦。<group> 元素定義路徑集或子組爬泥, 而 <path> 元素則定義將繪制的路徑。
完成一個AnimatedVectorDrawable需要創(chuàng)建3個文件
1). android.graphics.drawable.VectorDrawable 對應(yīng)的 XML 文件崩瓤,它以 <vector> 為根袍啡。我們可能讓 path 或 group 的屬性進行動畫,因此需要對進行動畫的 path 或 group 命名谷遂。
(2). android.graphics.drawable.AnimatedVectorDrawable 對應(yīng)的 XML 文件葬馋,它以 <animated-vector> 為根。 這里定義需動畫的 path 或 group 的 <target>,<target>的 animation 屬性指定為一般的 ObjectAnimator 或 AnimatorSet 對應(yīng)的 XML畴嘶。
(3). android.graphics.drawable.Animator 對應(yīng)的 XML 文件蛋逾,它以 <set>,<objectAnimator> 等為根窗悯, 對應(yīng) AnimatorSet 和 ObjectAnimator区匣。
ConstraintSet 動畫
PathData語法:https://blog.csdn.net/n4167/article/details/79184286
5.Google的一些最新的框架
6.策略模式(人上樓,通過樓梯蒋院,電梯上樓亏钩,可以構(gòu)建出那些對象)
http://baijiahao.baidu.com/s?id=1601547440739500969&wfr=spider&for=pc
7.適配器模式
https://www.cnblogs.com/V1haoge/p/6479118.html
8.Git tag 指向的是我們的最后一次提交,就像被我封存起來一樣,它其實是一個獨立的分支,
或者說是一個不可變的分支.指向特定提交對象的引用使用git 創(chuàng)建一個tag ,這樣一個不可修改的歷史代碼版本就像被我們封存起來一樣,不論是運維發(fā)布拉取,或者以后的代碼版本管理,都是十分方便的
9.像素點換算成byte字節(jié)
1個byte字節(jié)占用8位欺旧,1個像素點如果加載的是24位圖片姑丑,就是占用3個字節(jié),如果加載16位圖片就是占用2個字節(jié)辞友。
10.builder模式
https://blog.csdn.net/ljcITworld/article/details/80387378
11.責任鏈模式
https://blog.csdn.net/u012810020/article/details/71194853
12.代理模式
https://www.cnblogs.com/gonjan-blog/p/6685611.html
13.在自定義View中用到哪些設(shè)計模式
點擊事件栅哀,觀察者模式
事件傳遞,dispatchOnTouchEvent称龙,onIntereceptTouchEvent留拾,onTouchEvent
類似責任鏈模式,
模板方法模式
方圓集團面試:
內(nèi)存優(yōu)化管理鲫尊,有哪些工具可以分析內(nèi)存痴柔,怎么優(yōu)化。
https://blog.csdn.net/tuke_tuke/article/details/52316285
FindBugs_IDEA --->Analyze Project files
Android自帶的Lint代碼檢查工具
SonarLint 實時分析每個文件
廈門與夢公司面試:
IT線上公司面試:
TCP(傳輸控制協(xié)議)
TCP傳輸控制協(xié)議,為應(yīng)用層提供可靠的疫向,面向連接的基于流的服務(wù)
TCP有確認機制和三次握手機制咳蔚,容易被人攔擊利用攻擊。
UP協(xié)議()
與TCP協(xié)議相反搔驼,為應(yīng)用層提供不可靠的屹篓,無連接和基于數(shù)據(jù)報的服務(wù)。(網(wǎng)絡(luò)質(zhì)量差容易丟包)
TCP三次握手:
ONE:客戶端發(fā)送Syn包到服務(wù)器端匙奴,并進入SYN_SEND狀態(tài).
TWO:服務(wù)器端收到SYN包,會發(fā)送一個SYN+ACK包給到客戶端妄荔,并進入SYN_RECEIVED狀態(tài)泼菌。
THREE:客戶端收到服務(wù)器發(fā)送的SYN+ACK包,并發(fā)送ACK包到服務(wù)器端啦租,自身進入established狀態(tài)哗伯。
三次握手協(xié)議是為了防止失效的的連接請求被發(fā)送到服務(wù)器。
TCP四次揮手:
ONE:客戶端發(fā)送一個FIN篷角,用來關(guān)閉客戶端到服務(wù)器的數(shù)據(jù)傳送焊刹。
TWO:服務(wù)器端收到這個FIN,并發(fā)回一個ACK
THREE:與此同時,服務(wù)端還會關(guān)閉自身連接虐块,發(fā)送一個FIN給客戶端
FORU:客戶端在向服務(wù)端發(fā)回ACK報文確認俩滥。
第一層:應(yīng)用層 http(HypertextTransfer Protocol),ftp(File TransferProtocol) 協(xié)議贺奠,TELNET遠程終端霜旧,POP3郵件協(xié)議版本。(為應(yīng)用程序提供網(wǎng)絡(luò)接口)
第二層:傳輸層 TCP和UDP協(xié)議儡率。(建立端到端的連接)
第三層:網(wǎng)絡(luò)層 IP協(xié)議挂据。(尋址和路由)
第四層:數(shù)據(jù)鏈路層 (物理介質(zhì)訪問)
第四層:接口和電纜 (二進制數(shù)據(jù)流傳輸)
Socket:http://www.reibang.com/p/fb4dfab4eec1
TCP編程的服務(wù)端流程:
1.創(chuàng)建ServerSocket類對象-serverSocket
2.使用serverSocket開始一直阻塞監(jiān)聽accept,等待客戶端發(fā)送來數(shù)據(jù)并且得到socket
3.根據(jù)socket的輸入流讀取客戶端的數(shù)據(jù)儿普,根據(jù)socket的輸出流返回給客戶端數(shù)據(jù)
4.關(guān)閉socket以及IO流
public class Server {
public static void main(String[] args) {
try {
// 為了看流程崎逃,我就把所有的代碼都放在main函數(shù)里了,也沒有捕捉異常,直接拋出去了眉孩。實際開發(fā)中不可取个绍。
// 1.新建ServerSocket對象,創(chuàng)建指定端口的連接
ServerSocket serverSocket = new ServerSocket(12306);
System.out.println("服務(wù)端監(jiān)聽開始了~~~~");
// 2.進行監(jiān)聽
Socket socket = serverSocket.accept();// 開始監(jiān)聽9999端口勺像,并接收到此套接字的連接障贸。
// 3.拿到輸入流(客戶端發(fā)送的信息就在這里)
InputStream is = socket.getInputStream();
// 4.解析數(shù)據(jù)
InputStreamReader reader = new InputStreamReader(is);
BufferedReader bufReader = new BufferedReader(reader);
String s = null;
StringBuffer sb = new StringBuffer();
while ((s = bufReader.readLine()) != null) {
sb.append(s);
}
System.out.println("服務(wù)器:" + sb.toString());
// 關(guān)閉輸入流
socket.shutdownInput();
OutputStream os = socket.getOutputStream();
os.write(("我是服務(wù)端,客戶端發(fā)給我的數(shù)據(jù)就是:"+sb.toString()).getBytes());
os.flush();
// 關(guān)閉輸出流
socket.shutdownOutput();
os.close();
// 關(guān)閉IO資源
bufReader.close();
reader.close();
is.close();
socket.close();// 關(guān)閉socket
serverSocket.close();// 關(guān)閉ServerSocket
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:我們手機端發(fā)送完一個請求后,服務(wù)端(Server)拿到數(shù)據(jù)吟宦,解析數(shù)據(jù)篮洁,返回給客戶端數(shù)據(jù),關(guān)閉所有資源殃姓,也就是服務(wù)器關(guān)閉了袁波。這時,如果另一個客戶端再想跟服務(wù)器進行通信時蜗侈,發(fā)現(xiàn)服務(wù)器已經(jīng)關(guān)閉了篷牌,無法與服務(wù)器再次進行通信。換句話說踏幻,只能跟服務(wù)器通信一次枷颊,服務(wù)端 只能支持單線程數(shù)據(jù)處理。也就是說该面,上面的服務(wù)器的代碼無法實現(xiàn)多線程編程夭苗,只能進行一次通信。
作者:徐愛卿
鏈接:http://www.reibang.com/p/fb4dfab4eec1
來源:簡書
簡書著作權(quán)歸作者所有隔缀,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處题造。
TCP編程的客戶端對象
1.創(chuàng)建客戶端的socket對象
2.使用客戶端的socket對象的輸出流發(fā)送給服務(wù)器數(shù)據(jù),使用客戶端的socket對象的輸入流得到服務(wù)端的數(shù)據(jù)
public void onClick(View view){
new Thread(){
@Override
public void run() {
super.run();
try {
//1.創(chuàng)建監(jiān)聽指定服務(wù)器地址以及指定服務(wù)器監(jiān)聽的端口號
Socket socket = new Socket("111.111.11.11", 12306);//111.111.11.11為我這個本機的IP地址猾瘸,端口號為12306.
//2.拿到客戶端的socket對象的輸出流發(fā)送給服務(wù)器數(shù)據(jù)
OutputStream os = socket.getOutputStream();
//寫入要發(fā)送給服務(wù)器的數(shù)據(jù)
os.write(et.getText().toString().getBytes());
os.flush();
socket.shutdownOutput();
//拿到socket的輸入流界赔,這里存儲的是服務(wù)器返回的數(shù)據(jù)
InputStream is = socket.getInputStream();
//解析服務(wù)器返回的數(shù)據(jù)
InputStreamReader reader = new InputStreamReader(is);
BufferedReader bufReader = new BufferedReader(reader);
String s = null;
final StringBuffer sb = new StringBuffer();
while((s = bufReader.readLine()) != null){
sb.append(s);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText(sb.toString());
}
});
//3丢习、關(guān)閉IO資源(注:實際開發(fā)中需要放到finally中)
bufReader.close();
reader.close();
is.close();
os.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
TCP的多線程編程
public class MultiThreadServer {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(12306);
//死循環(huán)
while(true){
System.out.println("MultiThreadServer~~~監(jiān)聽~~~");
//accept方法會阻塞,直到有客戶端與之建立連接
Socket socket = serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
serverThread.start();
}
} catch (IOException e) {
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
}
}
}
public class ServerThread extends Thread{
private Socket socket;
//在構(gòu)造中得到要單獨會話的socket
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
super.run();
InputStreamReader reader = null;
BufferedReader bufReader = null;
OutputStream os = null;
try {
reader = new InputStreamReader(socket.getInputStream());
bufReader = new BufferedReader(reader);
String s = null;
StringBuffer sb = new StringBuffer();
while((s = bufReader.readLine()) != null){
sb.append(s);
}
System.out.println("服務(wù)器:"+sb.toString());
//關(guān)閉輸入流
socket.shutdownInput();
//返回給客戶端數(shù)據(jù)
os = socket.getOutputStream();
os.write(("我是服務(wù)端,客戶端發(fā)給我的數(shù)據(jù)就是:"+sb.toString()).getBytes());
os.flush();
socket.shutdownOutput();
} catch (IOException e2) {
e2.printStackTrace();
} finally{//關(guān)閉IO資源
if(reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bufReader != null){
try {
bufReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
UDP協(xié)議
//客戶端
private void udp() {
byte[] bytes = et.getText().toString().getBytes();
try {
/*******************發(fā)送數(shù)據(jù)***********************/
InetAddress address = InetAddress.getByName("192.168.232.2");
//1.構(gòu)造數(shù)據(jù)包
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, 12306);
//2.創(chuàng)建數(shù)據(jù)報套接字并將其綁定到本地主機上的指定端口淮悼。
DatagramSocket socket = new DatagramSocket();
//3.從此套接字發(fā)送數(shù)據(jù)報包咐低。
socket.send(packet);
/*******************接收數(shù)據(jù)***********************/
//1.構(gòu)造 DatagramPacket,用來接收長度為 length 的數(shù)據(jù)包敛惊。
final byte[] bytes1 = new byte[1024];
DatagramPacket receiverPacket = new DatagramPacket(bytes1, bytes1.length);
socket.receive(receiverPacket);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText(new String(bytes1, 0, bytes1.length));
}
});
// socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//服務(wù)端
public class UDPServer {
public static void main(String[] args) throws IOException {
byte[] buf = new byte[1024];
// 一:接受數(shù)據(jù)
// 1.創(chuàng)建接受數(shù)據(jù)的數(shù)據(jù)包
DatagramPacket packet = new DatagramPacket(buf, buf.length);
// 2.創(chuàng)建UPD 的 socket
DatagramSocket socket = new DatagramSocket(12306);
// 3.接收數(shù)據(jù)
System.out.println("服務(wù)端開始監(jiān)聽渊鞋!~~~~");
socket.receive(packet);
// 4.處理數(shù)據(jù)
System.out.println("服務(wù)端:" + new String(buf, 0, buf.length));
// 二:返回數(shù)據(jù)
DatagramPacket p = new DatagramPacket(buf, buf.length, packet.getAddress(), packet.getPort());
socket.send(p);
socket.close();
}
}
線程池的類型:
(1).newFixedThreadPool
這是一種數(shù)量固定的線程池,當線程處于空閑的時候,并不會被回收,除非線程池被關(guān)閉.
當所有的線程都處于活動狀態(tài)時,新任務(wù)都會處于等待狀態(tài),直到有線程空閑出來.
由于FixedThreadPool中只有核心線程并且這些核心線程不會被回收,這意味著它能夠更加快速地響應(yīng)外界的請求
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
(2).newScheduledThreadPool
//核心線程數(shù)是固定的,非核心線程無限大,并且非核心線程數(shù)有10s的空閑存活時間,這類線程池主要用于執(zhí)行定時任務(wù)和具有固定周期的重復(fù)任務(wù).
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSzie) {
return new ScheduledThreadPoolExecutor(corePoolSzie);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
(3).newCachedThreadPool
無核心線程,最大線程數(shù)為Integer.MAX_VALUE(2147483647),當線程池中所有線程都處于活動的狀態(tài)時,線程池會創(chuàng)建新的線程來處理新任務(wù),否則就會復(fù)用空閑線程來處理
(3-1)比較適合執(zhí)行大量的耗時較少的任務(wù).
(3-2)當整個線程都處于閑置狀態(tài)時,線程池中的線程都會超時而被停止,這時候的CacheThreadPool幾乎不占任何系統(tǒng)資源的.
public static ExecutorService newCacheThreadPool(){
return new ThreadPoolExecutor(
0,Integer.MAX_VALUE,
60L,TimeUnit.SECONDS,
new SynchronousQueue<Runnable>()
);
}
(4).newSingleThreadExecutor
這類線程池內(nèi)部只有一個核心線程,它確保所有的任務(wù)都在同一個線程中按順序執(zhí)行.
SingleThreadExecutor的意義在于統(tǒng)一外界所有任務(wù)到一個線程,這使得這些任務(wù)之間不需要處理線程同步的問題.
public static ExecutorService newSingleThreadExecutor() {
return Executors.newSingleThreadExecutor();
}
//特點:
//線程中只有一個核心線程
//并且無超時時間
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public class MainTest {
public static void main(String[] args){
//線程池中只允許同時存在2個線程
System.out.println("****************************newFixedThreadPool*******************************");
ExecutorService newFixedThreadPool=Executors.newFixedThreadPool(2);
for(int j=0;j<4;j++){
final int index=j;
newFixedThreadPool.execute(new MyRunnable(index));
}
//創(chuàng)建一個定長線程池,延時執(zhí)行某個代碼
System.out.println("****************************newScheduleThreadPool*******************************");
ScheduledExecutorService newScheduleThreadPool= Executors.newScheduledThreadPool(2);
for(int k=0;k<4;k++){
final int index=k;
//執(zhí)行結(jié)果:延遲三秒之后執(zhí)行瞧挤,除了延遲執(zhí)行之外和newFixedThreadPool基本相同锡宋,可以用來執(zhí)行定時任務(wù)
newScheduleThreadPool.schedule(new MyRunnable(index),3, TimeUnit.SECONDS);
}
System.out.println("****************************newFixedThreadPool*******************************");
ExecutorService newSingleThreadPool=Executors.newSingleThreadExecutor();
for(int l=0;l<4;l++){
final int index=l;
//執(zhí)行結(jié)果:只存在一個線程,順序執(zhí)行
newSingleThreadPool.execute(new MyRunnable(index));
}
System.out.println("****************************newCachedThreadPool*******************************");
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
for(int i=0;i<4;i++) {
final int index=i;
newCachedThreadPool.execute(new MyRunnable(index));
}
}
}
public class MyRunnable implements Runnable {
private Integer index;
public MyRunnable(Integer index) {
this.index = index;
}
@Override
public void run() {
/***
* 業(yè)務(wù)......省略
*/
try {
System.out.println("開始處理線程L靥瘛V戳!");
Thread.sleep(index*1000);
System.out.println("我的線程標識是:"+this.toString());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
天下科技集團面試:
自定義ViewGrop繪制自身癌刽,requestlayout的會導(dǎo)致子控件的重新繪制
TY:
HTTPS原理役首,進程間的通信,有序和無序集合
Seek Top:MVVM模式中显拜,RecycleView如何進行綁定一下
天貓集團:4中啟動模式:https://www.cnblogs.com/claireyuancy/p/7387696.html