第一篇:Java基础——一切从“类“和“Map“开始
别再背定义你只需要知道这东西是干嘛用的写在前面Java基础是面试的入场券。很多人一上来就背封装继承多态、“重载重写区别”、“String和StringBuilder的区别”……背得滚瓜烂熟面试官一问为什么这样设计直接卡壳。这篇文章的任务只有一个让你用常识理解Java基础而不是用记忆力。一、先搞清楚JDK、JRE、JVM到底是什么关系面试官可能不会直接问JDK和JRE的区别但这个概念贯穿整个Java学习。大白话JDK 开发工具包给程序员用的。里面有编译器javac、调试工具、还有下面那个JRE。JRE 运行环境给用户用的。里面有JVM 运行Java程序需要的核心类库。JVM Java虚拟机负责把字节码翻译成机器码执行。Java一次编译到处运行靠的就是它——不同操作系统装不同版本的JVM但跑同一个.class文件。一句话记住写代码用JDK跑代码靠JRE真正干活的是JVM。面试如果问到Java为什么能跨平台就答“因为不同操作系统有不同版本的JVMJVM屏蔽了底层差异。”二、面向对象说白了就三件事面向对象不是什么玄学它就是对现实世界的模拟。封装你家的钱不能让别人随便翻得通过你提供的接口比如妈给我点钱来操作。类里面的private字段加public的getter/setter就这意思。继承你继承了你爸的姓和房产但你可以有自己的新东西。子类继承父类的属性和方法还能扩展自己的。多态同一个方法不同对象干不同的事。“动物叫”——狗汪汪猫喵喵羊咩咩。代码里就是Animal a new Dog(); a.sound();运行时才知道是哪个具体实现。面试追问多态的实现原理是什么答父类引用指向子类对象方法调用时看实际对象的类型。底层靠的是虚方法表vtable——每个类有个表记录实际应该调用哪个方法运行时去查这个表。三、重载 vs 重写永远有人搞混重载Overload同一个类里方法名相同参数列表不同数量、类型、顺序。跟返回值无关跟访问修饰符也无关。voideat(Stringfood){}voideat(Stringfood,intcount){}// 参数数量不同voideat(intcount,Stringfood){}// 参数顺序不同重写Override子类重新实现父类的方法。方法签名必须完全一样方法名参数列表返回值可以是子类类型协变返回访问权限不能比父类更严格。// 父类protectedAnimalget(){returnnewAnimal();}// 子类publicDogget(){returnnewDog();}// 返回值是子类权限放大了OK面试官真正想听的是“重载是编译时决定调用哪个方法静态分派重写是运行时决定调用哪个方法动态分派。” —— 这才是区分两者的本质。四、抽象类 vs 接口Java 8之后区别不大了但核心区别还在经典背法也是对的抽象类可以有构造方法、成员变量、普通方法接口在Java 8之前只能有常量和抽象方法。类只能单继承但可以多实现接口。面试官真正想听的为什么Java设计成单继承多实现因为菱形问题。如果支持多继承两个父类有同名方法子类该用哪个C有这个问题靠虚继承解决但很复杂。Java干脆不让多继承改用接口——接口没有状态没有成员变量只有方法声明所以不存在冲突。但注意Java 8之后接口可以有default方法和static方法了多实现时如果两个接口有同名的default方法子类必须重写。本质上接口越来越抽象类化但核心区别依然在能不能有状态——抽象类可以有成员变量状态接口不行只能有static final的常量。选型建议要描述是什么用抽象类比如Animal要描述能做什么用接口比如Runnable。五、 和 equals()比的是什么基本类型比值。引用类型比内存地址是不是同一个对象。equals()默认Object类里的就是比地址。但很多类重写了它比如String、Integer比的是内容。Strings1newString(abc);Strings2newString(abc);s1s2// false两个不同对象s1.equals(s2)// true内容一样铁律重写equals必须重写hashCode()。为什么HashMap、HashSet这些集合用hashCode判断对象放哪个桶如果两个对象equals相等但hashCode不等你存进去就找不到了。约定是equals相等的两个对象hashCode必须相等。面试官追问两个对象hashCode相等equals一定相等吗不一定。哈希冲突嘛两个不同的key可能落到同一个桶里。反过来才是对的equals相等 → hashCode一定相等。反过来不成立。六、String/StringBuilder/StringBuffer不变 vs 可变安全 vs 不安全String不可变final修饰的char数组。每次修改都会创建新对象。优点线程安全、可以缓存hashCode所以String适合做HashMap的key。缺点频繁修改时性能极差。StringBuilder可变线程不安全但快。单线程环境下用它拼字符串。StringBuffer可变线程安全方法加了synchronized但慢。多线程环境下用它。面试高频场景字符串拼接循环里用会怎样Strings;for(inti0;i10000;i){sa;// 每次循环创建新的String对象旧的变成垃圾}每次都new一个StringBuilder再toString循环10000次创建10000个临时对象。正确做法是循环外用StringBuilder。七、泛型编译完了就不存在了泛型就是类型参数。你写ListString意思是这个List只能装String。但关键是Java的泛型是伪泛型——类型擦除。编译之后ListString和ListInteger在字节码里都是List类型参数被擦掉了替换成Object或对应的上界。ListStringlist1newArrayList();ListIntegerlist2newArrayList();list1.getClass()list2.getClass()// true都是ArrayList.class面试官追问为什么Java要设计成类型擦除为了向后兼容。Java 1.5之前没有泛型如果直接改成真泛型像C模板那样老代码就没法在JVM上跑了。擦除式泛型保证老代码和新代码能共存。泛型中的通配符? extends TT或T的子类可以读不能写因为不知道具体类型。? super TT或T的父类可以写读出来是Object。PECS原则Producer Extends, Consumer Super生产者用extends往外取消费者用super往里放。八、反射运行时扒开类的衣服看内部反射就是在运行时获取类的信息构造器、方法、字段并且能动态调用。能干吗获取Class对象Class.forName()、对象.getClass()、类名.class创建实例clazz.newInstance()或constructor.newInstance()调用方法method.invoke()访问字段field.get()/set()最关键的——反射能打破封装你可以把private字段改成accessible然后读写它。实际应用场景Spring的IoC容器通过反射创建对象、注入依赖。MyBatis通过反射把数据库查询结果映射成Java对象。注解处理器通过反射读取注解信息。性能问题反射比直接调用慢因为有额外开销检查访问权限、动态解析。但Spring这种框架只在启动时用反射不影响运行时性能。面试官追问反射破坏了什么原则破坏了封装性——明明private的字段反射能强行访问。但框架需要这种特权来实现通用功能所以这是一种设计上的权衡。九、序列化把对象变成流动的字节序列化把Java对象转成字节流存文件、传网络。反序列化从字节流恢复成Java对象。怎么用实现Serializable接口标记接口没有任何方法用ObjectOutputStream写ObjectInputStream读。关键点transient修饰的字段不会被序列化比如密码、敏感信息。serialVersionUID版本号。反序列化时会校验不一致就抛异常。强烈建议显式声明否则类变了就反序列化失败。静态变量不会被序列化——它属于类不属于对象。实际工作中很少直接用Java原生序列化性能差、跨语言困难。生产环境更多用JSONJackson/Fastjson或Protobuf。十、面试官真正想听什么背完上面这些你已经有80%的知识储备了。但面试官想听的不是定义是为什么和怎么用。举个例子。面试官问“String为什么设计成不可变的”普通回答“因为String是final的底层char数组也是final的。”面试官想听的“第一为了线程安全不可变对象天然线程安全第二为了性能String的hashCode可以缓存适合做HashMap的key第三为了安全比如数据库连接的用户名密码用String存防止被意外修改。这也是为什么String被设计成final——防止子类破坏不可变性。”再举个例子。面试官问“抽象类和接口的区别”普通回答“抽象类可以有实现方法接口不行。”面试官想听的2026年“Java 8之后接口也能有default方法了所以从语法上区别在缩小。但从设计层面看抽象类强调的是’是什么’is-a接口强调的是’能做什么’can-do。比如人继承哺乳动物人实现跑步接口。另外单继承是为了避免菱形问题这是Java设计者权衡后的选择。”小结知识点本质面试考点JVM虚拟电脑跨平台原理、内存管理封装/继承/多态现实世界的模拟设计原则、多态实现原理重载/重写编译时选/运行时选静态分派 vs 动态分派抽象类/接口是啥 vs 能干啥为什么单继承多实现 / equals地址 vs 内容hashCode约定String系列不可变 vs 可变性能、线程安全泛型类型参数类型擦除、PECS反射运行时扒类Spring底层、封装破坏序列化对象变字节流transient、serialVersionUID记住一句话Java基础从来不考背功考的是你知不知道这东西造出来是解决什么问题的。知道了为什么就不用背是什么了。下一篇我们讲集合框架——从HashMap开始你会发现整个集合体系就是一堆数据结构的Java实现。