Java 開發者最困惑的四件事,值得一看!,BAT面試文檔

HarmonyOS學習 2021-11-25 18:58:26
java 困惑 件事 值得一看 一看

}

}

//?end?of?class?scope.

  1. 創建匿名類時可以使用任何構造方法。注意這裏也使用了構造方法的參數。

  2. 匿名類可以擴展頂層類,並實現抽象類或接口。所以,訪問控制的規則依然適用。我們可以訪問protected變量,而改成private就不能訪問了。

  3. 由於上述代碼中擴展了Football類,我們不需要重載所有方法。但是,如果它是個接口或抽象類,那麼必須為所有未實現的方法提供實現。

  4. 匿名類中不能定義靜態初始化方法或成員接口。

  5. 匿名類可以有靜態成員變量,但它們必須是常量。

匿名類的用途:

  1. **更清晰的項目結構:**通常我們在需要隨時改變某個類的某些方法的實現時使用匿名類。這樣做就不需要在項目中添加新的*.java文件來定義頂層類了。特別是在頂層類只被使用一次時,這種方法非常好用。

  2. **UI事件監聽器:**在圖形界面的應用程

《一線大廠Java面試題解析+後端開發學習筆記+最新架構講解視頻+實戰項目源碼講義》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整內容開源分享

序中,匿名類最常見的用途就是創建各種事件處理器。例如,下述代碼:

button.setOnClickListener(new?View.OnClickListener()?{

public?void?onClick(View?v)?{

//?your?handler?code?here

}

});

我們創建了一個匿名類,實現了setOnClickListener接口。當用戶點擊按鈕時會觸發它的onClick方法。

多線程

Java中的多線程能够同時執行多個線程。線程是輕量級的子進程,也是處理的最小單比特。使用多線程的主要目的是最大化CPU的使用率。我們使用多線程而不是多進程,因為線程更輕量化,也可以共享同一個進程內的內存空間。多線程用來實現多任務。

線程的生命周期

Java 開發者最困惑的四件事,值得一看!,BAT面試文檔_面試

如上圖所示,線程的生命周期主要有5個狀態。我們來依次解釋每個狀態。

  1. New:創建線程的實例後,它會進入new狀態,這是第一個狀態,但線程還沒有准備好運行。

  2. Runanble:調用線程類的start()方法,狀態就會從new變成Runnable,意味著線程可以運行了,但實際上什麼時候開始運行,取决於Java線程調度器,因為調度器可能在忙著執行其他線程。線程調度器會以FIFO(先進先出)的方式從線程池中挑選一個線程。

  3. Blocked:有很多情况會導致線程變成blocked狀態,如等待I/O操作、等待網絡連接等。此外,優先級較高的線程可以將當前運行的線程變成blocked狀態。

  4. Waiting:線程可以調用wait()進入waiting狀態。當其他線程調用notify()時,它將回到runnable狀態。

  5. Terminated:start()方法退出時,線程進入terminated狀態。

為什麼使用多線程?

使用線程可以讓Java應用程序同時做多件事情,從而加快運行速度。用技術術語來說,線程可以幫你在Java程序中實現並行操作。由於現代CPU非常快,還可能包含多個核心,因此僅有一個線程就沒辦法使用所有的核心。

需要記住的要點

  • 多線程可以更好地利用CPU。

  • 提高響應性,提高用戶體驗

  • 减少響應時間

  • 同時為多個客戶端提供服務

創建線程的方法主要有兩種:

  1. 擴展Thread類

  2. 實現Runnable接口

通過擴展Thread類來創建線程

創建一個類擴展Thread類。該類應當重載Thread類中的run()方法。線程在run()方法中開始生命周期。我們創建新類的對象,然後調用start()方法開始執行線程。在Thread對象中,start()會調用run()。

public?class?MultithreadingTest?extends?Thread{

public?void?run()

{

try{

System.out.println(“Thread?”+Thread.currentThread().getName()+“?is?now?running”);

}catch?(Exception?ex)?{

ex.printStackTrace();

}

}

public?static?void?main(String[]?args)

{

for(int?i=0;i<10;i++)

{

MultithreadingTest?multithreadingTest?=?new?MultithreadingTest();

multithreadingTest.start();

}

}

}

也可以通過接口創建類。

下面的代碼創建了一個類,實現java.lang.Runnable接口並重載了run()方法。然後我們實例化一個Thread對象,調用該對象的start()方法。

public?class?MultithreadingTest?implements?Runnable{

@Override

public?void?run()?{

System.out.println(“Thread?”+Thread.currentThread().getName()+“?is?now?running”);?//To?change?body?of?generated?methods,?choose?Tools?|?Templates.

}

public?static?void?main(String[]?args)

{

for(int?i=0;i<10;i++)

{

Thread?thread?=?new?Thread(new?MultithreadingTest());

thread.start();

}

}

}

Thread類與Runnable接口

  • 擴展Thread類,就無法擴展更多的類,因為Java不允許多重繼承。多重繼承可以通過接口實現。所以最好是使用接口而不是Thread類。

  • 如果擴展Thread類,那麼它還包含了一些方法,如yield()、interrupt()等,我們的程序可能用不到。而在Runnable接口中就沒有這些派不上用場的方法。

同步

同步指的是多線程的同步。synchronized的代碼塊在同一時刻只能被一個線程執行。Java中的同步是個很重要的概念,因為Java是多線程語言,多個線程可以並行執行。在多線程環境中,Java對象的同步,或者說Java類的同步非常重要。

為什麼要同步?

如果代碼在多線程環境下執行,那麼在多個線程中共享的對象之間需要同步,以避免破壞狀態,或者造成任何不可預料的行為。

在深入同步的概念之前先來理解一下這個問題。

class?Table?{

void?printTable(int?n)?{//method?not?synchronized??

for?(int?i?=?1;?i?<=?5;?i++)?{

System.out.print(n?*?i+“?”);

try?{

Thread.sleep(400);

}?catch?(Exception?e)?{

System.out.println(e);

}

}

}

}

class?MyThread1?extends?Thread?{

Table?t;

MyThread1(Table?t)?{

this.t?=?t;

}

public?void?run()?{

t.printTable(5);

}

}

class?MyThread2?extends?Thread?{

Table?t;

MyThread2(Table?t)?{

this.t?=?t;

}

public?void?run()?{

t.printTable(100);

}

}

class?TestSynchronization1?{

public?static?void?main(String?args[])?{

Table?obj?=?new?Table();//only?one?object??

MyThread1?t1?=?new?MyThread1(obj);

MyThread2?t2?=?new?MyThread2(obj);

t1.start();

t2.start();

}

}

運行這段代碼就會注意到,輸出結果非常不穩定,因為沒有同步。我們來看看程序的輸出。

輸出:

100?5?200?10?300?15?20?400?500?25?

class?Table?{

synchronized?void?printTable(int?n)?{//synchronized?method??

for?(int?i?=?1;?i?<=?5;?i++)?{

System.out.print(n?*?i+“?”);

try?{

Thread.sleep(400);

}?catch?(Exception?e)?{

System.out.println(e);

}

}

}

}

class?TestSynchronization3?{

public?static?void?main(String?args[])?{

final?Table?obj?=?new?Table();//only?one?object??

Thread?t1?=?new?Thread()?{

public?void?run()?{

obj.printTable(5);

}

};

Thread?t2?=?new?Thread()?{

public?void?run()?{

obj.printTable(100);

}

};

t1.start();

t2.start();

}

}

給printTable()方法加上synchronized,那麼synchronized的方法在執行結束之前不會讓其他線程進入。下面的輸出結果就非常穩定了。

輸出:

5?10?15?20?25?100?200?300?400?500?

類似地,Java的類和對象也可以同步。

**注意:**我們並不一定需要同步整個方法。有時候最好是僅同步方法的一小部分。Java的synchronized代碼段可以實現這一點。

序列化

Java中的序列化是一種機制,可以將對象的狀態寫入到字節流中。相反的操作叫做反序列化,將字節流轉換成對象。

序列化和反序列化的過程是平臺無關的,也就是說,在一個平臺上序列化對象,然後可以在另一個平臺上反序列化。

序列化時調用ObjectOutputStream的writeObject()方法,反序列化調用ObjectInputStream類的readObject()方法。

下圖中,Java對象被轉換成字節流,然後存儲在各種形式的存儲中,這個過程叫做序列化。圖右側,內存中的字節流轉換成Java對象,這個過程叫做反序列化。

Java 開發者最困惑的四件事,值得一看!,BAT面試文檔_後端開發_02

為什麼要序列化

顯然,創建的Java類在程序執行結束或終止後,對象就銷毀了。為了避免這個問題,Java提供了序列化功能,通過它可以將對象存儲起來,或者將狀態進行持久化,以便稍後使用,或者在其他平臺上使用。

下面的代碼演示了該過程。

public?class?Employee?implements?Serializable?{

private?static?final?long?serialVersionUID?=?1L;

private?String?serializeValueName;

private?transient?int?nonSerializeValueSalary;

public?String?getSerializeValueName()?{

return?serializeValueName;

}

public?void?setSerializeValueName(String?serializeValueName)?{

this.serializeValueName?=?serializeValueName;

}

public?int?getNonSerializeValueSalary()?{

return?nonSerializeValueSalary;

}

public?void?setNonSerializeValueSalary(int?nonSerializeValueSalary)?{

this.nonSerializeValueSalary?=?nonSerializeValueSalary;

}

@Override

public?String?toString()?{

return?“Employee?[serializeValueName=”?+?serializeValueName?+?“]”;

}

}

import?java.io.FileOutputStream;

import?java.io.IOException;

import?java.io.ObjectOutputStream;

public?class?SerializingObject?{

public?static?void?main(String[]?args)?{

Employee?employeeOutput?=?null;

FileOutputStream?fos?=?null;

ObjectOutputStream?oos?=?null;

employeeOutput?=?new?Employee();

employeeOutput.setSerializeValueName(“Aman”);

employeeOutput.setNonSerializeValueSalary(50000);

try?{

fos?=?new?FileOutputStream(“Employee.ser”);

oos?=?new?ObjectOutputStream(fos);

oos.writeObject(employeeOutput);

System.out.println(“Serialized?data?is?saved?in?Employee.ser?file”);

oos.close();

fos.close();

}?catch?(IOException?e)?{

e.printStackTrace();

}?

}

}

輸出:

Serialized?data?is?saved?in?Employee.ser?file.

import?java.io.FileInputStream;

import?java.io.IOException;

import?java.io.ObjectInputStream;

public?class?DeSerializingObject?{

public?static?void?main(String[]?args)?{

Employee?employeeInput?=?null;

FileInputStream?fis?=?null;

ObjectInputStream?ois?=?null;

try?{

fis?=?new?FileInputStream(“Employee.ser”);

ois?=?new?ObjectInputStream(fis);

employeeInput?=?(Employee)ois.readObject();

最後

現在其實從大廠招聘需求可見,在招聘要求上有高並發經驗優先,包括很多朋友之前都是做傳統行業或者外包項目,一直在小公司,技術搞的比較簡單,沒有怎麼搞過分布式系統,但是現在互聯網公司一般都是做分布式系統。

所以說,如果你想進大廠,想脫離傳統行業,這些技術知識都是你必備的,下面自己手打了一份Java並發體系思維導圖,希望對你有所幫助。

Java 開發者最困惑的四件事,值得一看!,BAT面試文檔_Java_03

本文已被 CODING開源項目:【一線大廠Java面試題解析+核心總結學習筆記+最新講解視頻+實戰項目源碼】收錄

版权声明
本文为[HarmonyOS學習]所创,转载请带上原文链接,感谢
https://javamana.com/2021/11/20211125185549189S.html

  1. 图解 Kafka 线程模型及其设计缺陷
  2. Add data files for Oracle tablespaces or temporary tablespaces
  3. Intellij IDEA神器居然还有这些小技巧,mysql集群搭建视频
  4. IntelliJ IDEA(2019)之Web项目创建,掌门一对一java面试题
  5. InnoDB(2,如何访问Redis中的海量数据
  6. InheritableThreadLocal使用详解,java多线程面试题及答案整理
  7. How does Oracle modify the data type of a column
  8. Oracle 12C 12.1.0.1.0 management control file official document translation instructions
  9. Oracle 10g 10.2.0.1 in Oracle Linux 5.4 32bit RAC installation manual (Yimo Xiyang)
  10. Oracle 12C in Oracle Linux 6.5 64bit installation manual
  11. 一天十道Java面试题----第一天(面向对象-------》ArrayList和LinkedList)
  12. Schéma du modèle de fil Kafka et de ses défauts de conception
  13. Starting and shutting down Oracle RAC database cluster
  14. CRS_ Oracle CRS stack is already configured and will be running under init(1M)
  15. Common skills of Oracle stored procedure
  16. Check the number of CPUs, core books and threads of the Linux system
  17. jQuery-实例方法
  18. Oracle de duplicated data
  19. jQuery-dom和jQuery,入口函数(基本知识)
  20. Oracle creates unique constraints on columns that already have duplicate data
  21. JavaScript-拷贝
  22. JavaScript-this指向问题
  23.  There is ^ [[a garbled code problem in the up and down keys in Oracle sqlplus
  24. JavaScript-封装与继承(两种)
  25. JavaScript-包装类型
  26. JavaScript-传值(引用类型,基本类型)
  27. JavaScript-面向对象(构造函数,实例成员,静态成员)
  28. JavaScript-解构赋值
  29. JavaScript-箭头函数
  30. JavaScript-参数
  31. JavaScript-预解析(变量提升)
  32. JavaScript-闭包closure
  33. JavaScript-声明变量的关键字
  34. JavaScript - mot - clé pour déclarer une variable
  35. Fermeture de fermeture JavaScript
  36. JavaScript Pre - parse (promotion des variables)
  37. Paramètres JavaScript
  38. Fonction de flèche JavaScript
  39. JavaScript - déconstruction assignations
  40. Common annotations in springboot
  41. Building CentOS 7.6 with Linux
  42. JavaScript - orienté objet (constructeur, membre d'instance, membre statique)
  43. JavaScript value Transfer (reference type, Basic type)
  44. JavaScript - type d'emballage
  45. linux deepin/ubuntu安装flameshot火焰截图
  46. JavaScript - encapsulation et héritage (deux)
  47. JavaScript JS method for writing 99 multiplication table
  48. 從零開始學java - 第二十五天
  49. Apprendre Java à partir de zéro - jour 25
  50. Les voitures d'hiver, les voitures électriques et les voitures à essence ne sont pas les mêmes?
  51. JavaScript - ceci pointe vers le problème
  52. Copie JavaScript
  53. Spring boot quickly integrates swagger
  54. linux deepin/ubuntu安裝flameshot火焰截圖
  55. Capture d'écran de flamme de l'installateur de flamme Linux deepin / Ubuntu
  56. Jquery DOM et jquery, fonctions d'entrée (bases)
  57. Méthode d'instance jquery
  58. Méthode et démonstration de code dans l'interface de liste en Java
  59. Démarrage du Zookeeper
  60. Java oom Cognition