Java基础笔试核心知识点详解 Java基础是技术笔试的首要考察内容,涵盖了集合框架、反射机制、字符串操作、异常处理、设计模式等核心领域。本文将深入剖析这些知识点,帮助读者系统掌握Java基础的核心内容。
1. 集合框架深度解析 1.1 HashMap与ConcurrentHashMap的实现原理 HashMap实现原理 HashMap基于哈希表实现,采用数组+链表+红黑树的复合结构:
存储结构 :使用Node数组存储键值对,每个Node包含key、value、hash、next四个字段哈希计算 :通过key的hashCode()计算哈希值,然后通过(n-1) & hash确定数组索引冲突处理 :采用链地址法解决哈希冲突,当链表长度≥8且数组长度≥64时转为红黑树扩容机制 :当元素数量超过阈值(容量×负载因子0.75)时触发扩容,容量变为原来的2倍 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 final  V putVal (int  hash, K key, V value, boolean  onlyIfAbsent,                boolean  evict)  {    Node<K,V>[] tab; Node<K,V> p; int  n, i;     if  ((tab = table) == null  || (n = tab.length) == 0 )         n = (tab = resize()).length;     if  ((p = tab[i = (n - 1 ) & hash]) == null )         tab[i] = newNode(hash, key, value, null );     else  {                  Node<K,V> e; K k;         if  (p.hash == hash &&             ((k = p.key) == key || (key != null  && key.equals(k))))             e = p;         else  if  (p instanceof  TreeNode)             e = ((TreeNode<K,V>)p).putTreeVal(this , tab, hash, key, value);         else  {             for  (int  binCount  =  0 ; ; ++binCount) {                 if  ((e = p.next) == null ) {                     p.next = newNode(hash, key, value, null );                     if  (binCount >= TREEIFY_THRESHOLD - 1 )                         treeifyBin(tab, hash);                     break ;                 }                 if  (e.hash == hash &&                     ((k = e.key) == key || (key != null  && key.equals(k))))                     break ;                 p = e;             }         }     } } 
ConcurrentHashMap线程安全机制 ConcurrentHashMap在JDK1.8中采用CAS+synchronized保证线程安全:
存储结构 :与HashMap类似,但Node的val和next字段使用volatile修饰保证可见性并发控制 :
插入时使用CAS操作保证原子性 
当发生哈希冲突时,使用synchronized锁住链表头节点 
扩容时支持多线程协助扩容(ForwardingNode机制) 
 
size计算 :使用baseCount和CounterCell数组来统计元素数量,避免全局锁 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 final  V putVal (K key, V value, boolean  onlyIfAbsent)  {    if  (key == null  || value == null ) throw  new  NullPointerException ();     int  hash  =  spread(key.hashCode());     int  binCount  =  0 ;     for  (Node<K,V>[] tab = table;;) {         Node<K,V> f; int  n, i, fh;         if  (tab == null  || (n = tab.length) == 0 )             tab = initTable();         else  if  ((f = tabAt(tab, i = (n - 1 ) & hash)) == null ) {                          if  (casTabAt(tab, i, null ,                          new  Node <K,V>(hash, key, value, null )))                 break ;         }         else  if  ((fh = f.hash) == MOVED)             tab = helpTransfer(tab, f);         else  {             V  oldVal  =  null ;             synchronized  (f) {                   if  (tabAt(tab, i) == f) {                                      }             }         }     }     addCount(1L , binCount);     return  null ; } 
1.2 Vector与ArrayList的线程安全比较 
特性 
Vector 
ArrayList 
 
 
线程安全 是,所有方法使用synchronized修饰 
否,非线程安全 
 
扩容策略 扩容为原来的2倍 
扩容为原来的1.5倍 
 
性能 较低,方法级同步开销大 
较高,无同步开销 
 
初始容量 10 
10 
 
遍历方式 支持Enumeration和Iterator 
仅支持Iterator 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public  synchronized  boolean  add (E e)  {    modCount++;     ensureCapacityHelper(elementCount + 1 );     elementData[elementCount++] = e;     return  true ; } public  boolean  add (E e)  {    ensureCapacityInternal(size + 1 );     elementData[size++] = e;     return  true ; } 
1.3 LinkedList的实现机制与适用场景 实现机制 LinkedList基于双向链表实现:
节点结构 :每个节点包含prev、next、item三个字段头尾指针 :维护first和last指针,支持快速头尾操作队列特性 :实现了Deque接口,支持队列和栈的操作 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 private  static  class  Node <E> {    E item;     Node<E> next;     Node<E> prev;     Node(Node<E> prev, E element, Node<E> next) {         this .item = element;         this .next = next;         this .prev = prev;     } } private  void  linkFirst (E e)  {    final  Node<E> f = first;     final  Node<E> newNode = new  Node <>(null , e, f);     first = newNode;     if  (f == null )         last = newNode;     else          f.prev = newNode;     size++;     modCount++; } 
适用场景 
频繁插入删除 :在中间位置插入删除元素时性能优于ArrayList队列/栈实现 :作为队列或栈使用时效率很高内存敏感 :不需要连续的内存空间 
2. 反射机制详解 2.1 反射基本原理 反射机制允许程序在运行时获取类的信息并操作类或对象的属性、方法等:
Class对象 :每个类在JVM中都有对应的Class对象,包含了类的完整结构信息获取方式 :
Class.forName("全限定类名")类名.class对象.getClass() 
 
2.2 反射的应用场景 获取类信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Class<?> clazz = Class.forName("java.util.ArrayList" ); System.out.println("类名:"  + clazz.getName()); System.out.println("简单类名:"  + clazz.getSimpleName()); Package  pkg  =  clazz.getPackage();System.out.println("包名:"  + pkg.getName()); Class<?> superClass = clazz.getSuperclass(); System.out.println("父类:"  + superClass.getName()); Class<?>[] interfaces = clazz.getInterfaces(); for  (Class<?> iface : interfaces) {    System.out.println("接口:"  + iface.getName()); } 
创建对象 1 2 3 4 5 6 7 Class<?> clazz = Class.forName("java.util.ArrayList" ); Object  obj  =  clazz.newInstance();  Constructor<?> constructor = clazz.getConstructor(int .class); Object  obj  =  constructor.newInstance(10 );
调用方法 1 2 3 4 5 6 7 8 9 10 11 Class<?> clazz = Class.forName("java.util.ArrayList" ); Object  list  =  clazz.newInstance();Method  addMethod  =  clazz.getMethod("add" , Object.class);addMethod.invoke(list, "Hello" ); Method  sizeMethod  =  clazz.getMethod("size" );int  size  =  (int ) sizeMethod.invoke(list);
访问字段 1 2 3 4 5 6 7 8 Class<?> clazz = Student.class; Field  nameField  =  clazz.getDeclaredField("name" );nameField.setAccessible(true );   Student  student  =  new  Student ();nameField.set(student, "张三" ); String  name  =  (String) nameField.get(student);
2.3 反射的性能优化 
缓存Class对象 :避免重复获取Class对象setAccessible(true) :关闭安全检查提高性能MethodHandle :JDK7引入的轻量级反射机制 
3. 字符串操作深度分析 3.1 String、StringBuilder、StringBuffer区别 
特性 
String 
StringBuilder 
StringBuffer 
 
 
可变性 不可变 
可变 
可变 
 
线程安全 是(不可变天然线程安全) 
否 
是 
 
性能 低(频繁修改时) 
高 
中等 
 
使用场景 字符串常量 
单线程字符串操作 
多线程字符串操作 
 
String不可变性原理 1 2 3 4 5 6 7 8 9 public  final  class  String  {    private  final  char  value[];       private  final  int  hash;                  public  String (String original)  {         this .value = original.value;         this .hash = original.hash;     } } 
StringBuilder实现原理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 abstract  class  AbstractStringBuilder  {    char [] value;       int  count;          public  AbstractStringBuilder append (String str)  {         if  (str == null ) str = "null" ;         int  len  =  str.length();         ensureCapacityInternal(count + len);         str.getChars(0 , len, value, count);         count += len;         return  this ;     } } 
3.2 字符串常量池机制 JVM为了提升性能和减少内存消耗,维护了一块特殊的内存区域——字符串常量池:
1 2 3 4 5 6 7 8 9 10 11 String  s1  =  "hello" ;  String  s2  =  "hello" ;  String  s3  =  new  String ("hello" );  System.out.println(s1 == s2);   System.out.println(s1 == s3);   String  s4  =  s3.intern();  System.out.println(s1 == s4);   
4. 异常处理体系 4.1 Java异常体系结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Throwable ├── Error(系统级错误,程序无法处理) │   ├── OutOfMemoryError │   ├── StackOverflowError │   └── VirtualMachineError └── Exception(程序可处理的异常)     ├── RuntimeException(运行时异常,非受检异常)     │   ├── NullPointerException     │   ├── ArrayIndexOutOfBoundsException     │   ├── ClassCastException     │   └── IllegalArgumentException     └── 非RuntimeException(受检异常)         ├── IOException         ├── SQLException         └── ClassNotFoundException 
4.2 自定义异常实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public  class  BusinessException  extends  Exception  {    private  String errorCode;          public  BusinessException (String message, String errorCode)  {         super (message);         this .errorCode = errorCode;     }          public  String getErrorCode ()  {         return  errorCode;     } } public  class  SystemException  extends  RuntimeException  {    public  SystemException (String message)  {         super (message);     }          public  SystemException (String message, Throwable cause)  {         super (message, cause);     } } 
4.3 异常处理最佳实践 try-with-resources语法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 BufferedReader  br  =  null ;try  {    br = new  BufferedReader (new  FileReader ("file.txt" ));     return  br.readLine(); } catch  (IOException e) {     e.printStackTrace(); } finally  {     if  (br != null ) {         try  {             br.close();         } catch  (IOException e) {             e.printStackTrace();         }     } } try  (BufferedReader  br  =  new  BufferedReader (new  FileReader ("file.txt" ))) {    return  br.readLine(); } catch  (IOException e) {     e.printStackTrace(); } 
异常捕获顺序 1 2 3 4 5 6 7 8 9 10 11 12 try  {     } catch  (FileNotFoundException e) {          log.error("文件未找到" , e); } catch  (IOException e) {          log.error("IO异常" , e); } catch  (Exception e) {          log.error("未知异常" , e); } 
5. 设计模式精讲 5.1 单例模式详解 饿汉式单例 1 2 3 4 5 6 7 8 9 10 public  class  HungrySingleton  {    private  static  final  HungrySingleton  INSTANCE  =  new  HungrySingleton ();          private  HungrySingleton ()  {}          public  static  HungrySingleton getInstance ()  {         return  INSTANCE;     } } 
懒汉式单例(双重检查锁) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public  class  LazySingleton  {    private  volatile  static  LazySingleton INSTANCE;          private  LazySingleton ()  {}          public  static  LazySingleton getInstance ()  {         if  (INSTANCE == null ) {             synchronized  (LazySingleton.class) {                 if  (INSTANCE == null ) {                     INSTANCE = new  LazySingleton ();                 }             }         }         return  INSTANCE;     } } 
静态内部类单例(推荐) 1 2 3 4 5 6 7 8 9 10 11 12 public  class  StaticInnerSingleton  {    private  StaticInnerSingleton ()  {}          private  static  class  SingletonHolder  {         private  static  final  StaticInnerSingleton  INSTANCE  =  new  StaticInnerSingleton ();     }          public  static  StaticInnerSingleton getInstance ()  {         return  SingletonHolder.INSTANCE;     } } 
枚举单例(最推荐) 1 2 3 4 5 6 7 8 public  enum  EnumSingleton  {    INSTANCE;          public  void  doSomething ()  {              } } 
5.2 工厂模式 简单工厂模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public  interface  Car  {    void  run () ; } public  class  Benz  implements  Car  {    @Override      public  void  run ()  {         System.out.println("奔驰在跑..." );     } } public  class  Bmw  implements  Car  {    @Override      public  void  run ()  {         System.out.println("宝马在跑..." );     } } public  class  SimpleCarFactory  {    public  static  Car createCar (String type)  {         switch  (type) {             case  "benz" :                 return  new  Benz ();             case  "bmw" :                 return  new  Bmw ();             default :                 throw  new  IllegalArgumentException ("未知车型" );         }     } } 
工厂方法模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public  interface  CarFactory  {    Car createCar () ; } public  class  BenzFactory  implements  CarFactory  {    @Override      public  Car createCar ()  {         return  new  Benz ();     } } public  class  BmwFactory  implements  CarFactory  {    @Override      public  Car createCar ()  {         return  new  Bmw ();     } } 
5.3 观察者模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public  interface  Subject  {    void  registerObserver (Observer o) ;     void  removeObserver (Observer o) ;     void  notifyObservers () ; } public  interface  Observer  {    void  update (float  temperature, float  humidity, float  pressure) ; } public  class  WeatherData  implements  Subject  {    private  List<Observer> observers;     private  float  temperature;     private  float  humidity;     private  float  pressure;          public  WeatherData ()  {         observers = new  ArrayList <>();     }          @Override      public  void  registerObserver (Observer o)  {         observers.add(o);     }          @Override      public  void  removeObserver (Observer o)  {         observers.remove(o);     }          @Override      public  void  notifyObservers ()  {         for  (Observer observer : observers) {             observer.update(temperature, humidity, pressure);         }     }          public  void  measurementsChanged ()  {         notifyObservers();     }          public  void  setMeasurements (float  temperature, float  humidity, float  pressure)  {         this .temperature = temperature;         this .humidity = humidity;         this .pressure = pressure;         measurementsChanged();     } } 
6. 高频面试题总结 6.1 集合框架相关 
HashMap的put过程是怎样的? 
计算key的hash值 
通过(n-1)&hash计算索引位置 
如果位置为空,直接插入 
如果位置不为空,判断key是否相同,相同则覆盖 
不同则判断是否为树节点,是则插入红黑树 
否则插入链表,链表长度≥8时转为红黑树 
 
HashMap为什么线程不安全? 
多线程put可能导致数据丢失 
扩容时可能导致链表成环(JDK1.7) 
非原子操作导致的数据不一致 
 
ConcurrentHashMap如何实现线程安全? 
使用CAS操作保证原子性 
synchronized只锁定链表头节点 
使用volatile保证可见性 
扩容时支持多线程协助 
 
 
6.2 反射机制相关 
反射的优缺点? 
优点:动态性、灵活性、框架设计基础 
缺点:性能开销、安全限制、代码复杂 
 
如何防止反射破坏单例? 
在构造方法中检查实例是否已存在 
使用枚举实现单例 
使用SecurityManager检查权限 
 
 
6.3 字符串相关 
String为什么设计成不可变? 
线程安全 
支持字符串常量池 
作为HashMap的key安全 
避免被恶意修改 
 
StringBuilder和StringBuffer的区别? 
StringBuilder非线程安全,性能高 
StringBuffer线程安全,方法使用synchronized 
 
 
6.4 异常处理相关 
finally块一定会执行吗? 
正常情况下会执行 
System.exit()时不会执行 
JVM崩溃时不会执行 
线程被中断时可能不执行 
 
try-with-resources原理? 
编译器自动生成close方法调用 
要求资源实现AutoCloseable接口 
异常抑制机制 
 
 
6.5 设计模式相关 
单例模式的实现方式? 
工厂模式的作用? 
解耦对象的创建和使用 
统一管理对象的创建 
符合开闭原则 
 
 
参考资料 
《Java编程思想》 
《Effective Java》 
《Java并发编程实战》 
JDK 1.8源码 
《设计模式:可复用面向对象软件的基础》 
 
本文档会持续更新,如有疑问或建议,欢迎留言讨论!