主要模块
Java:Java基础、容器、多线程、反射、对象拷贝(JDBC)、Java Web模块(Servlet Tomcat)、异常模块、网络模块、设计模式(查找 排序算法);
框架:Spring、Spring事务、SpringMVC(Ajax Struts)、Mysql数据库、Mybatis、JVM、SpringBoot、
注解总结、Maven&Git&Linux常用命令、
MybatisPlus、Lambda表达式、Excel解析(poi easyExcel)
(SpringBoot、Redis、SpringCloud、Linux、kafka)
包含十九个模块:Java基础、容器、多线程、反射、对象拷贝、Java Web、异常、网络、设计模式、Spring/SpringMVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM。如下图所示:
一、Java基础
0. Object类常用方法?
equals()、hashCode()、toString()、clone()、getClass()、finalize()以及多线程中常用的wait()、notify()、notify All()等
1. JDK和JRE有什么区别?
JDK包含了: Java运行环境JER、Java开发工具(javac、java、javadoc)、和 Java基础类库。
JDK剖析:
bin:JDK包含的一些开发工具执行文件(eg:java、javac、javadoc);
lib:Java开发工具要用的一些库文件(eg:非核心类库tools.jar、dt.jar等);
db:一个开源的 Java开发的关系数据库 (eg:derby);
include:C语言头文件,支持用 Java本地接口编程;
jre:Java运行环境(JRE)的根目录;
src.zip:归档的 Java源代码;
2. == 和 equals 有什么区别?
【==:①基本数据类型:比较值是否相等;②引用数据类型:比较堆内存当中的地址是否指向同一个对象的引用(每 new一次都会开辟一个新的空间,值为 false;除非只 new了一次,是同一个 new对象,则值为 true)
equals:比较堆内存当中的内容】
2_1. == 比较两个 String对象?
①String str=“i”;
②String str=new String(“i”);
eg1:String str1=“i”; String str2=“i”; (先去字符串池中查找,有就用,没有就创建)
str1 == str2 ——》true
eg2:String str1=new String(“i”); ②String str2=new String(“i”)(无论有没有都创建)
str1 ==str2 ——》false
3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
3_1. a.hashCode()有什么用,与 a.equals()有什么关系?
hashCode:hashCode()方法提供了对象的 hashCode值,是一个 native方法,返回的默认值与 System.identityHashCode(obj)一致;通常这个值是对象头部的一部分二进制位组成的数字,具有一定的标识对象的意义存在,但不等于地址。作用是:用一个数字来标识对象,如在 HashMap、HashSet等类似的集合类中,如果用某个对象本身作为 Key,即要基于这个对象实现 Hash的写入和查找,那么对象本身如何实现这个呢?:就是基于 hashCode这样一个数字来完成的,只有数字才能完成计算和对比操作。
hashCode是否唯一: hashCode只能是标识对象,在 hash算法中可以将对象相对离散开,这样就可以在查找数据时根据这个 key快速缩小数据的范围,但 hashCode不一定是唯一的,所以哈希算法中定位到具体的链表后,需要循环链表,然后通过 equals方法来对比 key是否是一样的。
hashCode与 equals关系:hashCode相等的两个对象 equals不一定相等,但 equals相等的的两个对象 hashCode一定相等。(如果两个对象根据 equals方法比较是 相等的,那么调用两个对象中任意一个对象的 hashCode方法 都产生同样的整数结果;如果两个对象根据 equals方法比较是 不相等的,那么调用两个对象中任意一个对象的 hashCode方法 不一定产生同样的整数结果;)
3_2. 两个对象值相同即(x.equals(y)==true),但可以有不同的hashcode? 错
3_3. 若要重写一个对象的 equals方法,还要考虑什么? hashcode
4. final在 Java中有什么作用?
【 static 】:
① 修饰类成员即属性、方法,成为类变量,代表此属性、方法不属于任何一个对象,属于类,通过 类名. 来调用;
② 当类被加载时就会被加载,优先于对象的存在,优先于构造方法的执行,且只会被执行一次;
③ 静态方法只能访问外部的静态成员;静态方法中不能有 this关键字(this是指当前对象的引用,而无对象);
【 final 】:常量类不能被继承,常量方法不能被重写(修饰类、变量、方法);
【 abstract 】:抽象类不能实例化,抽象方法不能被调用(只能修饰类、方法,不能修饰属性);
abstract不能与 static、final同时使用,abstract不能用 private修饰;
【 普通代码块的执行优先于构造方法 】:因为普通代码块是做初始化的,在创建对象之前执行,构造方法是最后一步调用的,因为构造方法一旦执行完毕,对象就创建成功了。
4_1. final、finally、finalize区别?
final:修饰类、变量、方法。修饰的类 代表常量类,不能被继承(因此一个类不能既被声明为 abstract,又被声明为 final);修饰 的变量是一个常量,常量必须初始化,即一旦赋值就不能被修改(被初始化在两个地方:一是在定义处,即在 final变量定义时直接给其赋值;二是在构造函数或普通代码块中。两个地方只能任选其一);修饰 的方法不能被重写。
finally:异常处理中做善后处理工作,无论是否发生异常,代码总能执行,一般用来释放资源。(除非在其之前执行了 System.exit(0); 这种情况 finally块才不会被执行,其他情况都会执行)
finalize:方法名(finalize())此方法是垃圾收集器在删除对象时,确定这个对象没有被引用时对这个对象调用的,在 Object类中定义的,因此所有的类都继承它。
Object类中常用方法:toString()、equals()、hashCode()、clone()、getClass()、finalize()…
5. Java中 Math.ceil(-1.5)、Math.floor(-1.5)、Math.round(-1.5)、Math.abs(-1.5)?
Math.ceil( ):向上取整;
Math.floor( ):向下取整;
Math.abs( ):取绝对值;
Math.round( ):四舍五入;
(Math.round(-1.4)=-1;Math.round(-1.5)=-1;Math.round(-1.6)=-2
Math.round(1.4)=1;Math.round(1.5)=2;Math.round(1.6)=2)
6. JAVA中的几种基本类型,各占用多少字节?
【引用数据类型:类、接口、数组、String、空类型null;】
下图单位是 bit,非字节 1B=8bit
(Bit与 Byte的区别:bit 意为“位”或“比特”,是计算机运算的基础;
byte 意为“字节”,是计算机文件大小的基本计算单位。byte=字节即 1byte=8bits,两者换算 1:8的关系。)
7. String属于基本数据类型吗?
7_1. String str="i"与String str=new String(“i”)一样吗?
平常我们定义的String str=”a”;其实和String str=new String(“a”)还是有差异的。
前者默认调用的是String.valueOf来返回String实例对象,至于调用哪个则取决于你的赋值,比如String num=1,调用的是
public static String valueOf(int i) {
return Integer.toString(i);
}
后者则是调用如下部分:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
最后我们的变量都存储在一个char数组中
private final char value[];
7_2. String能被继承吗?为什么?
不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。平常我们定义的String str=”a”;其实和String str=new String(“a”)还是有差异的。
前者默认调用的是String.valueOf来返回String实例对象,至于调用哪个则取决于你的赋值,比如String num=1,调用的是
public static String valueOf(int i) {
return Integer.toString(i);
}
后者则是调用如下部分:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
最后我们的变量都存储在一个char数组中
private final char value[];
8. Java中操作字符串都有哪些类,它们之间有什么区别?
(若对字符串内容进行操作修改时用 StringBuffer,最后需要用 String,则用 StringBuffer的 toString()(eg: sb.append(“b”).toString() );)
不同点:② StringBuffer 自jdk1.0起就已经出现。其中的绝大多数方法都进行了同步处理,包括常用的Append方法也做了同步处理(synchronized修饰)。其toString方法会进行对象缓存,以减少元素复制开销。
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBuilder 字符串变量(非线程安全)其自jdk1.5起开始出现。与StringBuffer一样都继承和实现了同样的接口和类,方法除了没使用synch修饰以外基本一致,不同之处在于最后toString的时候,会直接返回一个新对象。
public String toString() {
// Create a copy, don’t share the array
return new String(value, 0, count);
}
8_1. String, Stringbuffer, StringBuilder 的区别?
String 字符串常量(final修饰,不可被继承),String是常量,当创建之后即不能更改。(可以通过StringBuffer和StringBuilder创建String对象(常用的两个字符串操作类)。)
StringBuffer 字符串变量(线程安全),其也是final类别的,不允许被继承,其中的绝大多数方法都进行了同步处理,包括常用的Append方法也做了同步处理(synchronized修饰)。其自jdk1.0起就已经出现。其toString方法会进行对象缓存,以减少元素复制开销。
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBuilder 字符串变量(非线程安全)其自jdk1.5起开始出现。与StringBuffer一样都继承和实现了同样的接口和类,方法除了没使用synch修饰以外基本一致,不同之处在于最后toString的时候,会直接返回一个新对象。
public String toString() {
// Create a copy, don’t share the array
return new String(value, 0, count);
}
9. String对象的声明方式?
①String str=“i”;
②String str=new String(“i”);
eg1:String str1=“i”; String str2=“i”; (先去字符串池中查找,有就用,没有就创建)
str1 == str2 ——》true
eg2:String str1=new String(“i”); ②String str2=new String(“i”)(无论有没有都创建)
str1 ==str2 ——》false
9_2. 如何将字符串反转?
9_3. String类的常用方法有哪些?
charAt():返回指定索引处的字符;
indexOf():返回指定字符的索引;
equals():字符串比较;
getBytes():返回字符串的byte类型的数组;
length():返回字符串的长度;
substring():截取字符串;
split():分割字符串,返回一个分割后的字符串数组;
trim():去除字符串两端空白;
replace():字符串替换;
toUpperCase():将字符串转成大写字母;
toLowerCase():将字符串转成小写字母;
10. 抽象类必须有抽象方法吗?
10_1. 抽象类和接口有什么区别?
【抽象类和接口区别:】
同: 两者都不能实例化;
异:
① 抽象类有构造方法(抽象类虽不能实例化,但有构造方法,提供给子类调用),接口没有构造方法;
② 类只能继承一个抽象类,可实现多个接口;(接口不能继承类,不能实现接口,但可继承多个接口,接口与接口之间是继承关系)
③ 抽象类可以不含抽象方法,可以含有具体的方法;接口只能含有静态常量和抽象方法,接口中不能有静态方法;如果一个方法是 abstract,则此类一定是 abstract(abstract方法不能是 private,因为要被重写,private无法重写了)(静态常量:默认 public static final,修饰符可全部省略或省略一个;抽象方法:可省略 abstract、public或任一个,但子类实现时会自动添加 public,因为默认是 public)
④ 一旦一个类去继承抽象类,则此类要么实现抽象类中的抽象方法,要么继续抽象下去;
【 instanceof运算符 】: 可用来决定某对象的类是否实现了接口,通过返回一个布尔值来指出对象是否是指定类或它子类的一个实例:
result=object instanceof class:若object是class类或其子类的一个实例,则此运算符返回true;
X instanceof Y:对象X是Y这个类的一个实例
10_2. 抽象类和接口
接口是否可以继承接口?(可以)
抽象类是否可以实现接口?(可以)
抽象类是否可以继承具体类?(可以)
抽象类是否可以有静态的 main 方法?(可以)
抽象类是否可以有内部类?(可以)
接口是否可以有内部类?(可以,但必须是 static内部类,但不一定是 final的)
11. Java中的IO流分为几种?
12. Files常用的方法有哪些?
Files.createFile():创建文件;
Files.createDirectory():创建文件夹;
Files.copy():复制文件;
Files.delete():删除一个文件或目录;
Files.exists():检测文件路径是否存在;
Files.move():移动文件;
Files.size():查看文件个数;
Files.read():读取文件;
Files.write():写入文件;
13. overload重载 和 override重写
overload 重载是一个类中多态性的一种表现; 一个类中:同名不同参
override 重写是父类与子类间多态性的一种变现;父子间:同名同参同返回类型;
(子类重写方法的访问权限 大于等于 父类被重写的方法的访问权限;父类私有的方法不能被重写)
13_1. Java实现多态的机制是什么?
方法重写 override和重载 overload是 Java多态性的不同表现;
14. 内部类
四种内部类:局部内部类、成员内部类、静态内部类、匿名内部类。
一、静态内部类: 静态内部类不能与其外部类具有相同的名字,只能访问外部的静态成员;非静态内部类不能有静态成员。
匿名内部类:
① 是一个没有名字的类,使用 new关键字,它要求内部类必须继承一个父类实现一个接口;( new 父类/接口( ){ }; )
② 适合那种只需要使用一次的类(即只能创建匿名内部类的一个实例);
③ 没有构造方法,可使用普通代码块来初始化;(不能定义静态成员、方法、类)
eg1:(若类中有一个特有的方法 play(),而接口中无此方法,Dog dog父类的引用变量无法调用子类特有的方法,只能通过 子类对象名.子类特有的方法名 来调用;)
interface Dog{
public abstract void eat();
}
public class A{
public static void main(String[] args) {
//吃两次
Dog dog=new Dog(){
public void eat(){
System.out.println("吃");
}
};
dog.eat();
dog.eat();
//吃一次
new Dog(){
public void eat(){
System.out.println("吃");
}
}.eat();
//类中特有的接口没有的方法
new Dog(){
public void eat(){
System.out.println("吃");
}
public void play(){
System.out.println("玩");
}
}.play();
}
}
abstract class Animal{
public abstract void eat();
}
class Person{
public void feed(Animal animal){
animal.eat();
}
}
public class Test{
public static void main(String[] args) {
Person p=new Person();
//喂两次,new出来的是两个不同对象,喂的是两条dog
p.feed(new Animal(){
public void eat(){
System.out.println("啃");
}
};)
p.feed(new Animal(){
public void eat(){
System.out.println("啃");
}
};)
p.feed(new Animal(){//喂的其他动物
public void eat(){
System.out.println("吃鱼");
}
};)
//喂的是同一对象,喂2次(若想调用自己特有的方法。
//new出来的是子类对象再子类赋值给父类即父类的
//引变引用子类对象,父类的引变只能调用父类的方法,
//不能调用子类所特有的方法)
Animal dog=new Animal(){
public void eat(){
System.out.println("啃");
}
};
p.feed(dog);
p.feed(dog);
//若想在构造对象前对属性赋值,{ }代码块对属性作初始化,
//比构方先执行——>运行:"哈哈,吃"。若加static——>运行报错
private String name="aa";
/*static*/{
name="哈哈";
}
public void show(){
System.out.println(name);
}
new Animal(){
public void eat(){
System.out.println("吃");
}
}.show();
}
}
二、
OuterClass outer=new OuterClass();
InnerClass inner=outer.newInnerClass();
//outer可换成 new OuterClass() 外部类对象
① 外部类修饰符:public、默认;
内部类修饰符:public、protected、default、private。
② 一个类对应一个 class文件,内部类编译形成的 class文件命名方式:外部类名$内部类名.class;
③ 内部类访问外部类成员可直接访问:外部类名.this.成员;
外部类访问内部类成员通过内部类对象访问:外部类对象.内部类对象.成员;
15. 作用域 public、protected、default、private的区别
16. 面向对象特征
四个方面:抽象、封装、继承、多态;
把相同的行为抽象出来归纳为类;通过类的封装隐藏内部细节;通过继承让父类的引用变量引用子类对象;通过多态使程序具有扩展性和可维护性。
17. & 和 && 的区别是什么?
&【位运算符、逻辑运算符】:
位运算符时:只有对应的两位二进制均为 1时,结果位才为 1,否则为 0;逻辑运算符时:与,同真为真,若 1为假,2还需要继续判断;
&&【逻辑运算符】: 短路与,同真为真,若1为假,则不判断2;
18. 向上、向下转型问题
19. 值传递、引用传递
八种基本数据类型是值传递,其他都是引用传递(包括八大基本数据类型的包装类、String等都是引用传递,但由于它们是不可变类,可理解为值传递,但字符串数组中的元素会变,不会开辟新空间)。
一、基本数据类型值传递:主方法中声明一个 int age=10;一旦调用一个方法(此中主方法)会在栈中分配一个栈桢,此栈桢中分配一个变量 age为 10;当调用上面 method() 时,又产生一个栈桢(上)中也声明了一个变量 age,其值是从下面的 age复制过来的,一开始也是 10,在上面方法中操作的是上面栈桢中的 age,即为 11,未影响到下面栈桢中的 age变量。上一个方法调用完毕,上面的栈桢就出栈了,但主方法未运行完,在主方法中打印 age,是下面 age中的 10;
二、引用数据类型:主方法中一旦,主方法开辟一个栈桢(下),里面开辟了一个整型数组 arr放在堆中,地址为 1AFF即 arr保存为 1AFF;调用 method() ,主方法中有形参,又是一个数组,栈中也开辟了引用变量 arr,此 arr是下面栈桢 arr传过来的,传的是地址;一旦一个变量保存的是堆中的地址可认为此变量引用指向堆内存空间,即现在两个指针指向同一内存空间,方法运行完毕后,上面的栈桢出栈,栈桢没了,指针也没了;当主方法运行完毕后,下面的栈桢也出栈了,只剩堆中对象,此堆中对象会被垃圾收集器回收。
问题:当一个对象被当做参数传递到一个方法后,此方法可改变此对象的属性,并可返回变化后的结果,此处是值传递还是引用传递?
值传递,Java语言只能由值传递来传递参数,当一个对象实例作为一个参数被传递到方法中时,参数值就是该对象的引用。对象的内容可在被调用的方法中改变,但对象的引用是不会改变的。
20. int 与 Integer区别?
原始数据类型与封装类型:
① 原始数据类型传递参数时都按值传递,封装类型都是按引用传递的;
② int 默认值为 0,Integer默认值为 null(即 Integer可以区分未赋值和值为 0 的情况,int 无法表达出未赋值情况);
③ 当引用数据类型和原始数据类型用作某个类的实例数据时所指定的缺省值:对象引用实例变量的缺省值为 null,而原始数据类型实例变量的缺省值与它们的类型有关。
21. 数组、String的 length、length()?
数组有 length属性,String有 length()方法。
22. switch(exp)中,exp是一个整数表达式,传递给 switch和 case语句的参数应是 byte、short、int、char,JDK1.5之后多了 enum,JDK1.7之后可比对字符串 String?
Switch适合作等值判断,不适合做区间判断;
多重 if else 功能比 switch更全面。
eg:
switch(number){
case:1
System.out.println("1");
break;
case:2
System.out.println("2");
break;
default:
System.out.println("error");
break;
}
23. 大致说一下 JDK1.7和 JDK1.8区别?
① 1.8中 Switch语句支持 String类型比对;
② 泛型实例的创建可通过类型推断来简化;(eg:List<String> strList=new ArrayList<>();
,即 <>中原本 String可以省略)
③ JDBC中可通过 try-with-resource 语句自动关闭 Connection、ResultSet、Statement资源对象;
④Java8新特性,Lambda表达式:
Lambda表达式介绍①;
Lambda表达式介绍②
⑤HashMap数组+链表+红黑树,JDK1.8引入了红黑树部分;
24. 使用随机数对数组进行初始化
25. 常用的类、包、接口有哪些?
常用类:String、Integer、List、HashMap、java.util.Date、FileReader、FileWrite;
常用包:java.lang、java.io、java.sql、java.util、javax.servlet;
常用接口:List、map、Servlet、HttpServlet、HttpServletRequest、HttpServletResponse、HttpSession;
26. UML类图(Unified modeling Language 统一建模语言)
三大块:类名、属性、方法
27. break、continue在循环中的用法
27_1. Java中如何跳出当前的多重嵌套循环
① 使用 break+ 标签;(eg)
② 使用 多个条件判断;
③ 使用方法的 retun。
ok:for ( : ) {
for ( : ) {
System.out.println("...");
if (j==5) {
break ok;
}
}
}
28. 如果mian方法被声明为private会怎样?main方法中去掉static修饰符会怎么样?
如果mian方法被声明为private: 能正常编译,但运行时会提示“main方法不是 public的”;
如果main方法中去掉static修饰符: 程序能正常编译,但运行时会抛出“NoSuchMethod异常”;
29. Java的“一次编写,处处运行”如何实现的?
Java程序会被编译成 .class字节码文件,这些字节码文件可运行在任何平台上,因此 Java是平台独立的;