### 1、String 屬于基礎的數據類型嗎?
String 不屬于基礎類型,基礎類型有 8 種:byte、boolean、char、short、int、float、long、double,而 String 屬于對象。
### 2、如何實現對象克隆?
有兩種方式:
1)、實現Cloneable接口并重寫Object類中的clone()方法;
2)、實現Serializable接口,通過對象的序列化和反序列化實現克隆,可以實現真正的深度克隆,代碼如下。
~~~
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class MyUtil {
private MyUtil() {
throw new AssertionError();
}
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj) throws Exception {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(obj);
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bin);
return (T) ois.readObject();
// 說明:調用ByteArrayInputStream或ByteArrayOutputStream對象的close方法沒有任何意義
// 這兩個基于內存的流只要垃圾回收器清理對象就能夠釋放資源,這一點不同于對外部資源(如文件流)的釋放
}
}
~~~
下面是測試代碼:
~~~
import java.io.Serializable;
/
* 人類
* @author
*
*/
class Person implements Serializable {
private static final long serialVersionUID = -9102017020286042305L;
private String name; // 姓名
private int age; // 年齡
private Car car; // 座駕
public Person(String name, int age, Car car) {
this.name = name;
this.age = age;
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
}
}
~~~
~~~
/
* 小汽車類
* @author
*
*/
class Car implements Serializable {
private static final long serialVersionUID = -5713945027627603702L;
private String brand; // 品牌
private int maxSpeed; // 最高時速
public Car(String brand, int maxSpeed) {
this.brand = brand;
this.maxSpeed = maxSpeed;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
@Override
public String toString() {
return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]";
}
}
~~~
~~~
class CloneTest {
public static void main(String[] args) {
try {
Person p1 = new Person("Hao LUO", 33, new Car("Benz", 300));
Person p2 = MyUtil.clone(p1); // 深度克隆
p2.getCar().setBrand("BYD");
// 修改克隆的Person對象p2關聯的汽車對象的品牌屬性
// 原來的Person對象p1關聯的汽車不會受到任何影響
// 因為在克隆Person對象時其關聯的汽車對象也被克隆了
System.out.println(p1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
~~~
> 注意:基于序列化和反序列化實現的克隆不僅僅是深度克隆,更重要的是通過泛型限定,可以檢查出要克隆的對象是否支持序列化,這項檢查是編譯器完成的,不是在運行時拋出異常,這種是方案明顯優于使用Object類的clone方法克隆對象。讓問題在編譯的時候暴露出來總是好過把問題留到運行時。
### 3、Java最頂級的父類是哪個?
Object
### 4、如何通過反射創建對象?
**1、**方法1:通過類對象調用newInstance()方法,例如:String.class.newInstance()
**2、**方法2:通過類對象的getConstructor()或getDeclaredConstructor()方法獲得構造器(Constructor)對象并調用其newInstance()方法創建對象,例如:String.class.getConstructor(String.class).newInstance(“Hello”);
### 5、Java 中堆和棧有什么區別?
JVM 中堆和棧屬于不同的內存區域,使用目的也不同。棧常用于保存方法幀和局部變量,而對象總是在堆上分配。棧通常都比堆小,也不會在多個線程之間共享,而堆被整個 JVM 的所有線程共享。
### 6、volatile 能使得一個非原子操作變成原子操作嗎?
**1、**關鍵字volatile的主要作用是使變量在多個線程間可見,但無法保證原子性,對于多個線程訪問同一個實例變量需要加鎖進行同步。
**2、**雖然volatile只能保證可見性不能保證原子性,但用volatile修飾long和double可以保證其操作原子性。
**所以從Oracle Java Spec里面可以看到:**
**1、**對于64位的long和double,如果沒有被volatile修飾,那么對其操作可以不是原子的。在操作的時候,可以分成兩步,每次對32位操作。
**2、**如果使用volatile修飾long和double,那么其讀寫都是原子操作
**3、**對于64位的引用地址的讀寫,都是原子操作
**4、**在實現JVM時,可以自由選擇是否把讀寫long和double作為原子操作
**5、**推薦JVM實現為原子操作
### 7、為什么選擇使用框架而不是原生?
框架的好處:
**1、**組件化: 其中以 React 的組件化最為徹底,甚至可以到函數級別的原子組件,高度的組件化可以是我們的工程易于維護、易于組合拓展。
**2、**天然分層: JQuery 時代的代碼大部分情況下是面條代碼,耦合嚴重,現代框架不管是 MVC、MVP還是MVVM 模式都能幫助我們進行分層,代碼解耦更易于讀寫。
**3、**生態: 現在主流前端框架都自帶生態,不管是數據流管理架構還是 UI 庫都有成熟的解決方案。
**4、**開發效率: 現代前端框架都默認自動更新DOM,而非我們手動操作,解放了開發者的手動DOM成本,提高開發效率,從根本上解決了UI 與狀態同步問題.
### 8、你能寫出一個正則表達式來判斷一個字符串是否是一個數字嗎?
一個數字字符串,只能包含數字,如 0 到 9 以及 +、- 開頭,通過這個信息,你可以下一個如下的正則表達式來判斷給定的字符串是不是數字。
~~~
首先要import java.util.regex.Pattern 和 java.util.regex.Matcher
public boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if( !isNum.matches() ){
return false;
}
return true;
}
~~~
### 9、運行時棧幀包含哪些結構?
**1、**局部變量表
**2、**操作數棧
**3、**動態連接
**4、**返回地址
**5、**附加信息
### 10、什么是Java程序的主類?應用程序和小程序的主類有何不同?
一個程序中可以有多個類,但只能有一個類是主類。在Java應用程序中,這個主類是指包含main()方法的類。而在Java小程序中,這個主類是一個繼承自系統類JApplet或Applet的子類。應用程序的主類不一定要求是public類,但小程序的主類要求必須是public類。主類是Java程序執行的入口點。
- 常見面試題
- 一.Java常見面試題
- 1.Java基礎
- 3.面向對象概念
- 10.Java面試題
- Java基礎知識面試題(總結最全面的面試題)
- 設計模式面試題(總結最全面的面試題)
- Java集合面試題(總結最全面的面試題)
- JavaIO、BIO、NIO、AIO、Netty面試題(總結最全面的面試題)
- Java并發編程面試題(總結最全面的面試題)
- Java異常面試題(總結最全面的面試題)
- Java虛擬機(JVM)面試題(總結最全面的面試題)
- Spring面試題(總結最全面的面試題)
- Spring MVC面試題(總結最全面的面試題)
- Spring Boot面試題(總結最全面的面試題)
- Spring Cloud面試題(總結最全面的面試題)
- Redis面試題(總結最全面的面試題)
- MyBatis面試題(總結最全面的面試題)
- TCP、UDP、Socket、HTTP面試題(總結最全面的面試題)
- 二、MySQL面試題
- 1.基礎部分
- MySQL面試題(總結最全面的面試題)
- HBase相關面試題整理
- Nginx面試題(總結最全面的面試題)
- RabbitMQ面試題(總結最全面的面試題)
- Dubbo面試題(總結最全面的面試題)
- ZooKeeper面試題(總結最全面的面試題)
- Tomcat面試題(總結最全面的面試題)
- Linux面試題(總結最全面的面試題)
- 超詳細的Django面試題
- SSM面試題
- 15個高頻微信小程序面試題
- VUE面試題
- Python面試題
- 二、常見問題解答列表
- 1.查看端口及殺死進程
- 三、學習電子書