一、Java概述
1.1 编程与Java的定义
编程是用程序设计语言编写代码解决问题并得到结果的过程。Java是一门面向对象编程语言,具有功能强大、简单易用的特点,吸收了C++优点并摒弃了复杂概念。
1.2 JDK版本、JVM、JRE和JDK的关系
- JDK版本:JDK1.5之后有Java SE(标准版,用于开发和部署桌面等环境应用程序)、Java EE(企业版,用于开发服务器端应用程序,后更名为Jakarta EE)、Java ME(微型版,用于移动和嵌入式设备应用程序)三大版本。
- JVM、JRE和JDK关系:JVM是Java虚拟机,Java程序运行其上实现跨平台;JRE包括JVM和核心类库,运行Java程序只需安装JRE;JDK提供给开发人员,包含开发工具和JRE。
1.3 跨平台性原理及Java语言特点
- 跨平台性原理:Java程序通过JVM在系统平台运行,只要系统能安装JVM,就能运行Java程序。
- Java语言特点:包括简单易学(语法与C、C++接近)、面向对象(封装、继承、多态)、平台无关性(JVM实现)、支持网络编程、支持多线程、健壮性(强类型机制、异常处理、垃圾自动收集)、安全性。
1.4 字节码及Java程序主类
- 字节码:Java源代码经虚拟机编译器编译后的文件(.class文件),面向虚拟机,解决了传统解释型语言执行效率与可移植性问题。
- Java程序主类:应用程序主类包含main()方法,小程序主类继承自JApplet或Applet且必须是public类,主类是程序执行入口点。
1.5 Java应用程序与小程序差别及Java与C++区别
- Java应用程序与小程序差别:应用程序从主线程main()方法启动,小程序嵌在浏览器页面运行(调用init()或run()启动)。
- Java与C++区别:Java不提供指针,类单继承(接口可多继承),有自动内存管理机制;C++支持指针、多重继承,需手动释放内存。
1.6 Oracle JDK和OpenJDK对比
Oracle JDK版本发布周期长,更稳定,性能更好,不完全开源,根据二进制代码许可协议获得许可;OpenJDK版本发布频繁,是参考模型且完全开源,根据GPL v2许可获得许可,部分情况下可能出现应用程序崩溃问题。
二、基础语法
2.1 数据类型
Java数据类型包括基本数据类型(数值型:整数类型byte、short、int、long,浮点类型float、double;字符型char;布尔型boolean)和引用数据类型(类、接口、数组)。switch可作用于byte、short、char、int、enum(Java 5引入)、String(Java 7引入),不能作用于long。计算2乘以8最有效率方法是2<<3。Math.round(11.5)返回12,Math.round(-11.5)返回 -11。float f = 3.4错误,需强制类型转换。short s1 = 1; s1 = s1 + 1错误(s1 + 1结果为int型,需强制转换),short s1 = 1; s1 += 1正确(隐含强制类型转换)。
2.2 编码、注释、访问修饰符
Java语言采用Unicode编码标准。注释分为单行注释(//)、多行注释(/* /)、文档注释(/* */)。访问修饰符有public(所有类可见)、private(同一类内可见)、protected(同一包内及子类可见)、default(同一包内可见)。
2.3 运算符、关键字、流程控制语句
&有按位与和逻辑与两种用法,&&是短路与运算。Java有保留字goto但未使用。final用于修饰类、属性和方法,修饰的类不能被继承,方法不能被重写,变量不能被改变(引用不可变,引用指向内容可变)。finally在try - catch代码块中,不管是否异常都会执行,常用于关闭资源。finalize是Object类方法,垃圾回收器调用回收垃圾。this代表对象本身,可用于区分形参与成员变量重名、引用本类构造函数。super指向父类对象,可访问父类成员、区分同名成员、调用父类构造函数。break跳出总上一层循环,continue跳出本次循环继续下次循环,return结束当前方法返回。跳出多重嵌套循环可在外面循环定义标号,用带标号的break语句。
三、面向对象
3.1 面向对象与面向过程区别
面向过程性能高但不易维护、复用和扩展,面向对象易维护、复用和扩展但性能低。面向过程具体化、流程化,面向对象模型化,将面向过程抽象成类封装,底层仍是面向过程。
3.2 面向对象三大特性
- 抽象:总结对象共同特征构造类,包括数据抽象和行为抽象,关注属性和行为,不关注行为细节。
- 封装:隐藏对象属性和实现细节,提供公共访问方式,提高复用性和安全性。
- 继承:子类拥有父类非private属性和方法,可扩展自己的属性和方法,用自己方式实现父类方法,提高代码复用性,是多态前提。
- 多态:程序运行时确定引用变量指向对象及调用方法,通过继承(子类重写父类方法)和接口(实现接口并覆盖方法)实现,有编译时多态(方法重载,静态绑定)和运行时多态(动态绑定)。
3.3 面向对象五大基本原则(可选)
单一职责原则(SRP):类功能单一;开放封闭原则(OCP):对拓展开放,对修改封闭;里式替换原则(LSP):子类可替换父类;依赖倒置原则(DIP):高层次模块依赖抽象,抽象不依赖具体实现;接口分离原则(ISP):多个与特定客户类有关的接口优于通用接口。
四、类与接口
4.1 抽象类和接口对比
抽象类捕捉子类通用特性,接口是抽象方法集合。相同点是都不能实例化,位于继承顶端,包含抽象方法需子类覆写。不同点在于设计层面抽象类是类的抽象(模板设计),接口是行为抽象(行为规范)。Java 8中接口可定义默认方法和静态方法。优先选用接口定义行为模型,需定义子类行为并提供通用功能时选择抽象类。
4.2 普通类和抽象类区别及创建对象
普通类不能含抽象方法,可直接实例化;抽象类可含抽象方法,不能直接实例化。抽象类不能用final修饰。创建对象用new关键字,对象实例在堆内存,对象引用存栈内存,一个对象可多个引用指向,一个引用可指向0或1个对象。
五、变量与方法
5.1 成员变量与局部变量区别
成员变量在类内方法外,局部变量在方法内或语句体内。成员变量作用域针对整个类,存储在堆内存,随对象创建消失,有默认初始值;局部变量只在局部范围有效,存储在栈内存,方法或语句结束释放,无默认初始值,使用前需赋值。
5.2 构造方法相关
定义不做事且无参数的构造方法用于子类构造方法调用父类无参构造方法,若父类无此构造方法且子类未用super()调用特定构造方法,编译出错。调用子类构造方法前先调用父类无参构造方法帮助子类初始化。构造方法名与类名相同,无返回值,不能用void声明,生成对象时自动执行。
5.3 静态变量、实例变量、静态方法、实例方法区别及方法返回值
静态变量属于类,内存一份,类加载时分配内存初始化;实例变量属于实例对象,每次创建对象分配内存。静态方法可通过“类名.方法名”或“对象名.方法名”调用,只能访问静态成员;实例方法只能通过“对象名.方法名”调用,可访问静态和实例成员。静态方法内调用非静态成员非法,因静态方法可不通过对象调用,无法确定访问哪个对象的非静态成员。方法返回值是方法执行结果,用于其他操作。
六、内部类
6.1 内部类定义、分类及特点
内部类定义在其他类内部,可分为成员内部类、局部内部类、匿名内部类和静态内部类。成员内部类可访问外部类所有变量和方法,依赖外部类实例;静态内部类可访问外部类静态变量,通过“外部类.静态内部类”创建;局部内部类定义在方法内,实例方法中可访问外部类所有变量和方法,静态方法中只能访问静态变量和方法,在对应方法内创建;匿名内部类无名字,必须继承抽象类或实现接口,不能定义静态成员和方法,所在方法形参需被使用时声明为final,创建方式为“new 类/接口{实现部分}”。
6.2 内部类优点、应用场景及访问局部变量问题
内部类优点包括可访问外部类私有数据、封装性好、实现“多重继承”、方便定义回调。应用场景有多算法场合、解决非面向对象语句块、使代码灵活扩展、类仅被外部类使用时。局部内部类和匿名内部类访问局部变量需加final,因局部变量存储在栈中,方法结束销毁,加final可确保内部类使用变量与外层区分开,避免出错。
七、重写与重载
7.1 构造器重写与重载
构造器不能被继承,不能被重写,但可重载。
7.2 重载与重写区别
重载发生在同一类中,方法名相同参数列表不同(参数类型、个数、顺序),与返回值和访问修饰符无关;重写发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出异常小于等于父类,访问修饰符大于等于父类(父类方法为private时子类不是重写),重载实现编译时多态,重写实现运行时多态。
八、对象相等判断
8.1 ==和equals区别
用于判断基本数据类型值是否相等或引用数据类型地址是否相等;equals在类未覆盖时等价于,覆盖后一般用于判断对象内容是否相等。
8.2 hashCode与equals关系
hashCode()用于获取哈希码确定对象在哈希表中的索引位置。HashSet检查重复时先比较hashCode值,若不同则认为对象不重复,若相同再调用equals()检查。若两个对象相等,hashCode一定相同;若hashCode相同,对象不一定相等。equals方法被覆盖时,hashCode方法也必须被覆盖。
8.3 对象相等与引用相等不同
对象相等比较内存中存放内容,引用相等比较指向的内存地址。
九、值传递
9.1 Java参数传递方式
Java方法调用采用值传递,对象实例作为参数传递时,传递的是对象引用的拷贝,方法可改变对象属性,但不能改变对象引用。
9.2 值传递和引用传递区别
值传递传递参数值的拷贝,传递后互不相关;引用传递传递引用地址,传递前后指向同一内存空间。
十、Java包
10.1 JDK常用包
常用包有java.lang(系统基础类)、java.io(输入输出类)、java.nio(完善io包性能)、java.net(网络相关类)、java.util(系统辅助类,特别是集合类)、java.sql(数据库操作类)。
10.2 import java和javax区别
起初java开头包是Java API必需,javax是扩展API包,后javax成为标准API一部分,二者无本质区别。
十一、IO流
11.1 IO流分类及相关类
IO流按流向分输入流和输出流,按操作单元分字节流和字符流,按角色分节点流和处理流。相关类从InputStream/Reader(字节/字符输入流基类)、OutputStream/Writer(字节/字符输出流基类)派生。
11.2 BIO、NIO、AIO区别
BIO是同步阻塞式IO,模式简单但并发处理能力低;NIO是同步非阻塞IO,基于通道通讯实现多路复用;AIO是异步非阻塞IO(NIO 2),基于事件和回调机制,操作异步执行,目前应用不太广泛。
11.3 Files常用方法
包括exists()(检测文件路径是否存在)、createFile()(创建文件)、createDirectory()(创建文件夹)、delete()(删除文件或目录)、copy()(复制文件)、move()(移动文件)、size()(查看文件大小)、read()(读取文件)、write()(写入文件)。
十二、反射
12.1 反射机制定义、优缺点及应用场景
反射机制可在运行时获取类的属性和方法,动态调用对象方法。优点是运行期类型判断、动态加载类、提高代码灵活度;缺点是性能比直接Java代码慢。应用场景包括框架设计(如JDBC加载驱动、Spring框架配置装载Bean)、模块化开发、动态代理设计模式等。
12.2 Java获取反射的三种方法
通过new对象实现(对象.getClass())、通过路径实现(Class.forName(“路径”))、通过类名实现(类名.class)。
十三、网络编程
(详见重学TCP/IP协议和三次握手四次挥手文章,包含TCP/IP协议、三次握手四次挥手、计算机网络体系结构、HTTP协议、get与post请求区别、session与cookie区别等内容)
十四、常用API
14.1 String相关
字符型常量是单引号引起的单个字符,字符串常量是双引号引起的若干字符;字符常量相当于整形值(ASCII值)可参与运算,字符串常量代表地址值;字符常量占一个字节,字符串常量至少占一个字符结束标志字节。字符串常量池位于堆内存,存储字符串常量,提高内存使用率,创建字符串时先检查常量池,存在则返回引用,否则实例化并放入池中返回引用。String不是基本数据类型,底层是char数组,具有不变性(对其操作会创建新对象)、常量池优化(创建后缓存引用)、final定义(不能被继承)特点。可通过StringBuilder或StringBuffer的reverse()方法反转字符串。数组无length()方法有length属性,String有length()方法。String常用方法有indexOf()、charAt()、replace()、trim()、split()、getBytes()、length()、toLowerCase()、toUpperCase()、substring()、equals()等。用String做HashMap的key,因字符串不可变,hashcode被缓存,查找更快。
14.2 String、StringBuffer、StringBuilder区别及int与Integer区别
String不可变,StringBuffer和StringBuilder可变且继承自AbstractStringBuilder。String线程安全,StringBuffer线程安全(方法加同步锁),StringBuilder非线程安全。操作少量数据用String,单线程操作大量数据用StringBuilder,多线程操作大量数据用StringBuffer。int是基本数据类型,Integer是其包装类型,Java 5引入自动装箱/拆箱机制使二者可相互转换。整型字面量值在 -128到127之间时,自动装箱不会创建新Integer对象,直接引用常量池中的对象,超过范围则创建新对象。