Java 一.java基础
1.八大基础类型
数字型: [字节类型]、短整型 short、整型 int、长整型 Long、单精度浮点数 float、双精度浮点数 double 字符型: 字符类型 char、布尔型: 布尔类型 boolean、
Java 2.java三大特性
封装: 使用 private 关键字,让对象私有,防止无关的程序去使用。继承: 继承某个类,使子类可以使用父类的属性和方法。多态: 同一个行为,不同的子类具有不同的表现形式。
3.重载和重写的区别
重载: 发生在同一类中,函数名必须一样,参数类型、参数个数、参数顺序、返回值、修饰符可以不一样。重写: 发生在父子类中,函数名、参数、返回值必须一样,访问修饰符必须大于等于父类,异常要小于等于父类,父类方法是 private 不 #技术分享能重写。
4.pubilc、protected、(dafault)不写、private修饰符的作用范围
pubilc: 同一个类、同一个包、不同包的子类、不同包的非子类都可以访问。protected: 同一个类、同一个包、不同包的子类可以使用,不同包的非子类不能。(dafault)不写: 同一个类、同一个包可以使用,不同包的子类、不同包的非子类不能。private: 只有同一个类可以。
5.==和equals的区别
==: 基础类型比较的值,引用类型比较的是地址值。equals: 没有重写比较地址值是否相等,重写比较的内容是否相对。列如 String 类重写 equals,源码第一比较是否都是 String 对象,然后再向下比较。
篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记及答案【扫一扫】 即可免费获取**
6.hashcode()值一样,equals就必定为true
不必定,由于 “重地”和”通话”的 hashcode 值就一样,但是 equals()就为 false。但是 equals()为 true,那么 hashcode 必定一样。
7.为什么重写equals(),就要重写hashcode()?
保证同一对象,如果不重写 hashcode,可能会出现 equals 比较一样,但是 hashcode 不一样的情况。
8.short s = 1;s = s + 1;(程序1)和 short s = 1; s += 1;(程序2)是否都能正常运行
程序1会编译报错,由于 s + 1的1是 int 类型,由于类型不兼容。强制转换失败。程序2可以正常运行,由于 java 在复合赋值解释是 E1 += E2,等价于 E1 = (T)(E1 + E2),T 是 E1的类型,因此 s += 1等价于 s = (short)(s + 1),所以进行了强制类型的转换,所以可以正常编译。
9.说出下面程序的运行结果,及缘由
public static void main(String[] args) {
Integer a = 128, b = 128, c = 127, d = 127
System.out.println(a == b)
System.out.println(c == d)
}
结果:false,true
运行本项目 java 运行 123456
由于 Integer = a,相当于自动装箱(基础类型转为包装类),由于 Integer 引入了 IntegerCache 来缓存必定的值,IntegerCache 默认是 -128~127,所以128超过了范围,a 和 b 不是一样对象,c 和 d 是一样对象。可以通过 jvm 启动时,修改缓存的上限。
10.&和&&的区别
&&: 如果一边为假,就不比较另一边。又叫短路运算符。&: 不论一边是真是假,都会比较另一边。如果表达式两边不是 Boolean 类型时候,表明按位运算。
11.String、StringBuffer、StringBuilder的区别
String: 适用于少量字符串。创建之后不可更改,对 String 的修改会生成新的 String 对象。StringBuilder: 适用于大量字符串,线程不安全,性能更快。单线程使用 StringBuffer: 适用于大量字符串,线程安全。多线程使用,用 synchronized 关键字修饰。
12.String rap = new String(“ctrl”);创建了几个对象?
一个或两个,如果常量池存在,那就在堆创建一个实例对象,否则常量池也需要创建一个。
13.什么是反射
在运行过程中,对于任何一个类都能获取它的属性和方法,任何一个对象都能调用其方法,动态获取信息和动态调用,就是反射。
14.浅拷贝和深拷贝的区别
浅拷贝: 基础数据类型复制值,引用类型复制引用地址,修改一个对象的值,另一个对象也随之改变。深拷贝: 基础数据类型复制值,引用类型在新的内存空间复制值,新老对象不共享内存,修改一个值,不影响另一个。
深拷贝相对浅拷贝速度慢,开销大。
15.构造器能被重写吗
不能,可以被重载。
16.并发和并行
并发: 宏观上看是一个处理器”同时”处理多个任务(实际上多个任务轮流使用时间片)。微观上是同一时间只有一个任务在执行。(一个人同时吃两个苹果) 并行: 多个处理器同时处理多个任务。(两个人同时吃两个苹果)
17.实例变量和类变量。
类变量是被 static 所修饰的,没有被 static 修饰的叫实例变量也叫成员变量。同理也存在类对象和实例对象,类方法和实例方法。
public static String kunkun1 = "鸡你太美";
public String kunkun2 = "鸡你不美";
运行本项目 java 运行 12345
18.说出下面程序的运行结果,及缘由
public class InitialTest {
public static void main(String[] args) {
A ab = new B();
ab = new B();
}
}
class A {
static {
System.out.print("A");
}
public A() {
System.out.print("a");
}
}
class B extends A {
static {
System.out.print("B");
}
public B() {
System.out.print("b");
}
}
结果:ABabab
运行本项目 java 运行 123456789101112131415161718192021222324
缘由:①执行顺序是 父类静态代码块(父类静态变量) -> 子类静态代码块(子类静态变量) -> 父类非静态代码块 -> 父类构造方法 -> 子类非静态代码块 -> 子类构造方法 ②静态代码块(静态变量)只执行一次。
19.抽象类和接口的区别
抽象类只能单继承,接口可以实现多个。抽象类有构造方法,接口没有构造方法。抽象类可以有实例变量,接口中没有实例变量,有常量。抽象类可以包含非抽象方法,接口在 java7之前所有方法都是抽象的,java8之后可以包含非抽象方法。抽象类中方法可以是任意修饰符,接口中 java8之前都是 public,java9支持 private。扩展:普通类是亲爹,手把手教你怎么学,抽象类(多个类具有一样的东西,拿出来放抽象类)是师傅,教你一部分秘籍,然后告知你怎么学。接口(规范了某些行为)是干爹,只给你秘籍,怎么学全靠你。
C 20.Error和Exception有什么区别
Error: 程序无法处理,比较严重的问题,程序会立即崩溃,jvm 停止运行。Exception: 程序本身可以处理(向上抛出或者捕获)。编译时异常和运行时异常
21.NoClassDefFoundError和ClassNotFoundException区别
NoClassDefFoundError: 在打包时漏掉了某些类或者打包时存在,然后你把 target 里的类删除,然后 jvm 运行时找不到报错。ClassNotFoundException: 在编译的时候某些类找不到,然后报错。
22.如果try{} 里有一个 return 语句,那么finally{} 里的代码会不会被执行,什么时候被执行,在 return 前还是后?
会执行,在 return 之前执行,如果 finally 有 return 那么 try 的 return 就会失效。
23.看一面代码执行结果是啥
public class TryDemo {
public static void main(String[] args) {
System.out.println(test1());
}
public static int test1() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 3;
}
}
}
结果 2
运行本项目 java 运行 123456789101112131415
由于在 return 前,jvm 会把2暂存起来,所以当 i 改变了,回到 try 时,还是会返回暂存的值。
24.final关键字有哪些用法?
修饰类: 不能被继承。修饰方法: 不能被重写。修饰变量: 声明时给定初始值,只能读取不能修改。如果是对象引用不能改,但是对象的属性可以修改。
25.jdk1.8的新特性
①lambda 表达式 ②方法引用 ③加入了 base64的编码器和解码器 ④函数式接口 ⑤接口允许定义非抽象方法,使用 default 关键字即可 ⑥时间日期类改善
篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记及答案【扫一扫】 即可免费获取**
26.http中重定向和转发的区别
重定向发送两次请求,转发发送一次请求 重定向地址栏会变化,转发地址栏不会变化 重定向是浏览器跳转,转发是服务器跳转 重定向可以跳转任意网址,转发只能跳转当前项目 重定向会有数据丢失,转发不会数据丢失
27.get和post请求的区别 delete、put
get 相对不安全,数据放在 url 中(请求行),post 放在 body 中(请求体),相对安全。get 传送的数据量小,post 传送的数据量大。get 效率比 post 高,是 form 的默认提交方法。
C 28.cookie和session的区别
存储位置不同:cookie 放在客户端电脑,session 放在服务器端内存的一个对象 存储容量不同:cookie <=4KB,一个站点最多保存20个 cookie,session 是没有上限的,但是性能思考不要放太多,而且要设置 session 删除机制 存储数据类型不同:cookie 只能存储 ASCll 字符串,session 可以存储任何类型的数据 隐私策略不同:cookie 放在本地,别人可以解析,进行 cookie 欺骗,session 放在服务器,不存在敏感信息泄露 有效期不同:可以设置 cookie 的过期时间,session 依赖于 jsessionID 的 cookie,默认时间为-1,只需要关闭窗口就会失效
Java 29.java中的数据结构
数组、链表、哈希表、栈、堆、队列、树、图
30.什么是跨域?跨域的三要素
跨域指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制 协议、域名、端口 注意:localhost 和127.0.0.1虽然都指向本机,但也属于跨域
C 31.tomcat三个默认端口及其作用
8005:这个端口负责监听关闭 tomcat 的请求。8009:接受其他服务器的请求 8080:用于监听浏览器发送的请求
32.throw 和 throws 的区别?
throw:抛出一个异常。throws:声明一个异常。
33.说一下你熟悉的设计模式
单例模式: 保证被创建一次,节省系统开销。工厂模式: 解耦代码。观察者模式: 定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。代理模式: 代理对象具备被代理对象的功能,并取代被代理对象完成相应操作,并能够在操作执行的前后,对操作进行增强处理。模板模式: 较少代码冗余。例如:redis 模板。
34.实例化对象有哪几种方式
① new ② clone() ③ 反射 ④先序列化在反序列化
Java 35.java中什么样的类不能被实例化
抽象类: abstract 关键字修饰的类。
36.序列化和反序列化
序列化: 把对象转为字节序列的过程,在传递和保存对象时,保证了对象的完整性和可传递性,便于在网络传输和保存在本地文件中。反序列化: 把字节序列转为对象的过程,通过字节流的状态和信息描述,来重建对象。
37.序列化的优点
将对象转为字节流存储到硬盘上,当 JVM 噶了的话,字节流还会在硬盘上等待,等待下一次 JVM 的启动,把序列化的对象,通过反序列化为原来的对象,减少储存空间和方便网络传输(由于是二进制)。
38.你知道什么是单点登录吗?
单点登录(SSO:Single Sign On): 同一账号在多系统中,只登录一次,就可以访问其他系统。多个系统,统一登录。列如:在一个公司下,有多个系统,列如淘宝和天猫,你登录上淘宝,就不用再去登录天猫了。
39.实现单点登录的方式
① Cookie: 用 cookie 为媒介,存放用户凭证。登录上父应用,返回一个加密的 cookie,访问子应用的时候,会对 cookie 解密校验,通过就可以登录。不安全和不能跨域免登。② 分布式 session 实现: 用户第一次登录,会把用户信息记录下来,写入 session,再次登录查看 session 是否含有对应信息。session 系统不共享,使用缓存等方式来解决。③重定向: 父应用提供一个 GET 方式的登录接口 A,用户通过子应用重定向连接的方式访问这个接口,如果用户还没有登录,则返回一个登录页面,用户输入账号密码进行登录,如果用户已经登录了,则生成加密的 token,并且重定向到子应用提供的验证 token 的接口 B,通过解密和校验之后,子应用登录当前用户,虽然解决了安全和跨域,但是没前两种简单。
40.sso(单点登录)与OAuth2.0(授权)的区别?
单点登录: 就是一个公司多个子系统登录问题。OAuth2.0: 是授权问题,列如微信授权问题。是一种具体的协议。
41.如何防止表单提交
①js 屏蔽提交按钮。②给数据库添加唯一约束。③利用 Session 防止表单重复提交。会有一个 token 标记,表单提交的时候拦截器会检查是否一致,不一致就不通过。④使用 AOP 切入实现。自定义注解,然后新增切入点,然后每次都记录过期时间,然后做比较。
42.泛型是什么?有什么好处?
本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。好处:①类型安全 ②消除强制类型转换 ③提高性能 ④提高代码的复用性
43.值传递和引用传递
值传递: 函数调用时会把实际参数,复制一份到函数中,函数中对参数进行操作,并不会影响参数实际的值。引用传递: 将实际参数的地址值传递到函数中,函数对参数进行操作,会影响到实际参数的值。注意: java 中不存在引用传递(即使传的是对象,那也只是传递了对象的引用地址的副本,也属于值传递)。
Java 二.java集合
**[java 集合框架详解]
**[HashMap 底层原理详解]
1.List、Set、Map的区别
List 集合有序、可重复的单例集合。Set 集合无序、不可重复的单例集合。Map 集合无序、k 不可重复,v 可重复的双例集合。
2.List、Set、Map常用集合有哪些?
List vector: 底层是数组,方法加了 synchronized 来保证线程安全,所以效率较慢,使用 ArrayList 替代。ArrayList: 线程不安全,底层是数组,由于数组都是连续的地址,所以查询比较快。增删比较慢,增会生成一个新数组,把新增的元素和原有元素放到新数组中,删除会导致元素移动,所以增删速度较慢。LinkedList: 线程不安全,底层是链表,由于地址不是连续的,都是一个节点和一个节点相连,每次查询都得重头开始查询,所以查询慢,增删只是断裂某个节点对整体影响不大,所以增删速度较快。
Set HashSet: 底层是哈希表(数组+链表或数组+红黑树),在链表长度大于8时转为红黑树,在红黑树节点小于6时转为链表。实则就是实现了 HashMap,值存入 key,value 是一个 final 修饰的对象。TreeSet: 底层是红黑树结构,就是 TreeMap 实现,可以实现有序的集合。String 和 Integer 可以根据值进行排序。如果是对象需要实现 Comparator 接口,重写 compareTo()方法制定比较规则。LinkedHashSet: 实现了 HashSet,多一条链表来记录位置,所以是有序的。
Map双例结构 TreeMap: 底层是红黑树,key 可以按顺序排列。HashMap: 底层是哈希表,可以很快的储存和检索,无序,大量迭代情况不佳。LinkedHashMap: 底层是哈希表+链表,有序,大量迭代情况佳。
3.ArrayList的初始容量是多少?扩容机制是什么?扩容过程是怎样?
初始容量: 默认10,也可以通过构造方法传入大小。
扩容机制: 原数组长度 + 原数组长度/2(源码中是原数组右移一位,也就相当于除以2) 注意:扩容后的 ArrayList 底层数组不是原来的数组。
扩容过程: 由于 ArrayList 底层是数组,所以它的扩容机制和数组一样,第一新建一个新数组,长度是原数组的1.5倍,然后调用 Arrays.copyof()复制原数组的值,然后赋值给新数组。
4.什么是哈希表
根据关键码值(Key value)而直接进行访问的数据结构,在一个表中,通过 H(key)计算出 key 在表中的位置,H(key)就是哈希函数,表就是哈希表。
5.什么是哈希冲突
不同的 key 通过哈希函数计算出一样的储存地址,这就是哈希冲突。
6.解决哈希冲突
(1)开放地址法 如果发生哈希冲突,就会以当前地址为基准,再去寻找计算另一个位置,直到不发生哈希冲突。寻找的方法有:① 线性探测 1,2,3,m ② 二次探测 1的平方,-1的平方,2的平方,-2的平方,k 的平方,-k 的平方,k<=m/2 ③ 随机探测 生成一个随机数,然后从随机地址+随机数++。
(2)链地址法 冲突的哈希值,连到到同一个链表上。
(3)再哈希法(再散列方法) 多个哈希函数,发生冲突,就在用另一个算计,直到没有冲突。
(4)建立公共溢出区 哈希表分成基本表和溢出表,与基本表发生冲突的都填入溢出表。
7.HashMap的hash()算法,为什么不是h=key.hashcode(),而是key.hashcode()^ (h>>>16)
得到哈希值然后右移16位,然后进行异或运算,这样使哈希值的低16位也具有了一部分高16位的特性,增加更多的变化性,减少了哈希冲突。
8.为什么HashMap的初始容量和扩容都是2的次幂
由于计算元素存储的下标是(n-1)&哈希值,数组初始容量-1,得到的二进制都是1,这样可以减少哈希冲突,可以更好的均匀插入。
9.HashMap如果指定了不是2的次幂的容量会发生什么?
会获得一个大于指定的初始值的最接近2的次幂的值作为初始容量。
10.HashMap为什么线程不安全
jdk1.7中由于使用头插法,再扩容的时候,可能会造成闭环和数据丢失。jdk1.8中使用尾插法,不会出现闭环和数据丢失,但是在多线程下,会发生数据覆盖。(put 操作中,在 putVal 函数里) 值的覆盖还有长度的覆盖。
11.解决Hashmap的线程安全问题
(1)使用 Hashtable 解决,在方法加同步关键字,所以效率低下,已经被弃用。(2)使用
Collections.synchronizedMap(new HashMap<>()),不常用。(3)ConcurrentHashMap(常用)
C 12.ConcurrentHashMap的原理
jdk1.7: 采用分段锁,是由 Segment(继承 ReentrantLock:可重入锁,默认是16,并发度是16)和 HashEntry 内部类组成,每一个 Segment(锁)对应1个 HashEntry(key,value)数组,数组之间互不影响,实现了并发访问。jdk1.8: 抛弃分段锁,采用 CAS(乐观锁)+synchronized 实现更加细粒度的锁,Node 数组+链表+红黑树结构。只要锁住链表的头节点(树的根节点),就不会影响其他数组的读写,提高了并发度。
13.为什么用synchronized取代ReentrantLock
①节省内存开销。ReentrantLock 基于 AQS 来获得同步支持,但不是每个节点都需要同步支持,只有链表头节点或树的根节点需要同步,所以使用 ReentrantLock 会带来很大的内存开销。②获得 jvm 支持,可重入锁只是 api 级别,而 synchronized 是 jvm 直接支持的,能够在 jvm 运行时做出相应的优化。③在 jdk1.6之后,对 synchronized 做了大量的优化,而且有多种锁状态,会从 无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁一步步转换。
AQS (Abstract Queued Synchronizer): 一个抽象的队列同步器,通过维护一个共享资源状态( Volatile Int State )和一个先进先出( FIFO )的线程等待队列来实现一个多线程访问共享资源的同步框架。
14.HashMap为什么使用链表
减少和解决哈希冲突,把冲突的值放在同一链表下。
15.HashMap为什么使用红黑树
当数据过多,链表遍历较慢,所以引入红黑树。
16.HashMap为什么不一上来就使用红黑树
维护成本较大,红黑树在插入新的数据后,可能会进行变色、左旋、右旋来保持平衡,所以当数据少时,就不需要红黑树。
17.说说你对红黑树的理解
①根节点是黑色。②节点是黑色或红色。③叶子节点是黑色。④红色节点的子节点都是黑色。⑤从任意节点到其子节点的所有路径都包含一样数目的黑色节点。红黑树从根到叶子节点的最长路径不会超过最短路径的2倍。保证了红黑树的高效。
18.为什么链表长度大于8,并且表的长度大于64的时候,链表会转换成红黑树?
由于链表长度越长,哈希冲突概率就越小,当链表等于8时,哈希冲突就超级低了,是千万分之一,我们的 map 也不会存那么多数据,如果真要存那么多数据,那就转为红黑树,提高查询和插入的效率。
19.为什么转成红黑树是8呢?而重新转为链表阈值是6呢?
由于如果都是8的话,那么会频繁转换,会浪费资源。
20.为什么负载因子是0.75?
加载因子越大,填满的元素越多,空间利用率越高,但发生冲突的机会变大了;加载因子越小,填满的元素越少,冲突发生的机会减小,但空间浪费了更多了,而且还会提高扩容 rehash 操作的次数。“冲突的机会”与“空间利用率”之间,寻找一种平衡与折中。又由于根据泊松分布,当负载因子是0.75时,平均值时0.5,带入可得,当链表为8时,哈希冲突发生概率就很低了。
21.什么时候会扩容?
元素个数 > 数组长度 * 负载因子 例如 16 * 0.75 = 12,当元素超过12个时就会扩容。链表长度大于8并且表长小于64,也会扩容
22.为什么不是满了扩容?
由于元素越多,空间利用率是高了,但是发生哈希冲突的几率也增加了。
23.扩容过程
jdk1.7: 会生成一个新 table,重新计算每个节点放进新 table,由于是头插法,在线程不安全的时候,可能会出现闭环和数据丢失。jdk1.8: 会生成一个新 table,新位置只需要看(e.hash & oldCap)结果是0还是1,0就放在旧下标,1就是旧下标+旧数组长度。避免了对每个节点进行 hash 计算,大大提高了效率。e.hash 是数组的 hash 值,,oldCap 是旧数组的长度。
24.HashMap和Hashtable的区别
①HashMap,运行 key 和 value 为 null,Hashtable 不允许为 null。②HashMap 线程不安全,Hashtable 线程安全。
