Java高频面试题复盘系列之小问题集合篇1
==和equals的区别?
1 介绍: 值类型是存储在内存中的栈中的, 而引用类型的变量在栈中存储的只是一个地址值
1 而这个引用类型中的具体数据是存储在堆中的
2 ==操作比较的是两个变量的值是否相等
1 对于引用型变量表示的是两个变量在堆中存储的地址是否相同, 即栈中的内容是否相同
3 equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同
4 ==比较的是两个对象的地址,而equals比较的是两个对象的内容
session的实现原理? session的生命周期? session如何存储数据?
1 session的实现原理
1 客户对向服务器端发送请求后,Session 创建在服务器端,返回Sessionid给客户端浏览器保存在本地,
2 当下次发送请求的时候,在请求头中传递sessionId获取对应的从服务器上获取对应的Sesison
2 session的生命周期
1 一次会话范围, 即打开浏览器到关闭浏览器
2 注意:
1 关闭浏览器后session并不是销毁了, session是保存在服务器端的
1 关闭浏览器只是销毁了客户端保存的sessionid
2 只要拿到这个id, 那么还可以再次获取到对应的session信息
2 一个浏览器只有一个session
3 session如何存储数据
1 在服务器端有一个session池,用来存储每个用户提交session中的数据
类加载机制? 代码块的执行顺序?
1 类加载机制
1 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制
2 类的整个生命周期包括: 加载(Loading)、验证(Verification)、准(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段
3 其中验证、准备、解析3个部分统称为连接(Linking)
4 加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的, 类的加载过程必须按照这种顺序按部就班地开始
1 而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)
2 代码块的执行顺序
1 静态代码块: 在当前类第一次被使用时, 会执行该代码块
2 构造代码块: 在执行类的构造方法之前执行
3 局部代码块: 在方法内部, 执行方法时执行
cookie和session的区别?
1 cookie: 客户端技术, 数据保存在客户端, 数据不安全, 存储数据大小4kb
2 session: 服务器端技术, 数据保存在服务器, 数据相对安全, 存储数据大小根据服务器容量确定
java中字符串方法有哪些? string stringbuild stringbuffer的区别?
1 java中字符串方法
1 获取字符串长度: int length()
2 比较字符串内容
1 boolean equals(Object anObject)
2 boolean equalsIgnoreCase(String anotherString)
3 根据索引获取字符:char charAt(int index)
4 截取字符串中的一部分
1 String substring(int beginIndex)
2 String substring(int beginIndex, int endIndex)
5 大小写转换
1 toUpperCase()
2 toLowerCase()
6 替换字符串中的内容
1 public String replace(String s, String replacement)
2 public String replaceAll(String regex,String replacement)
7 拼接字符串:String concat(String str)
8 判断字符串是否为空:boolean isEmpty()
9 判断字符串中是否包含给定的字符串:boolean contains(CharSequence s)
10 判断字符串是否以给定的字符串结尾:boolean endsWith(String suffix)
11 判断字符串是否以给定的字符串开头:boolean startsWith(String prefix)
12 切分字符串:String[] split(String regex)
13 移除首尾空格:trim()
14 返回字符串对应的字节数组
1 byte[] getBytes()
2 byte[] getBytes(Charset charset)
15 把字符串转换为字符数组:char[] toCharArray();
16 返回指定字符串在此字符串中第一次出现的索引位置: public int indexOf(String str)
2 string stringbuild stringbuffer的区别
1 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象
1 这样不仅效率低下,而且大量浪费有限的内存空间
2 例: string s = "123", s = s + "234"
1 s的变化是指针的变化, 首先指针指向"123", 系统会给"123"开辟一个空间
2 s = s + "234"; "234"开辟一个空间, "123234"有开辟一个空间
3 最终s指向"123234"的空间地址
4 这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费
2 当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类
1 和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
3 StringBuilder 类在 Java 5 中被提出
4 string stringbuild stringbuffer 的区别
1 区别一:
1 string: 不可变字符序列
2 stringbuild: 可变字符序列, 线程不安全, 执行速度快
3 stringbuffer: 可变字符序列, 线程安全, 执行速度慢
2 字符修改上的区别
3 初始化上的区别
1 String可以赋值为null, 另外两个不可以, 会报错
5 使用方式
1 如果要操作少量的数据用 String
2 多线程操作字符串缓冲区下操作大量数据 StringBuffer
3 单线程操作字符串缓冲区下操作大量数据 StringBuilder
java如何跳出循环?
1 continue, break, return
1 continue:中止本次循环,继续下次循环。continue以后的循环体中的语句不会继续执行,下次循环继续执行,循环体外面的会执行
2 break:直接结束一个循环,跳出循环体。break以后的循环体中的语句不会继续执行,循环体外面的会执行
1 注意: 只跳出一层循环
3 return:return的功能是结束一个方法。 一旦在循环体内执行return,将会结束该方法,循环自然也随之结
1 可以跳出多层循环
2 循环标记使用(标签变量)
1 场景: 多层循环,如果在里层循环,达到某个条件后,结束指定循环
2 测试代码
public static void main(String[] args) {
ee:for (int i = 0; i < 3; i++) {
for (int j = 0; j <3 ; j++) {
System.out.println("j==========" + j);
break ee;//跳出指定标记的循环
}
System.out.println("i=" + i);
}
System.out.println("跳出循环");
}
3 测试代码执行结果: j==========0
3 利用try…catch…
1 给整个for循环加上try...catch...
2 如果在循环中需要退出, 就抛出一个异常即可: throw new Exception("跳出循环");
4 利用标识变量
1 即定义一个全局变量, 在for循环中进行判断, 当满足标识变量的值满足某个值时, 就使用break语句退出循环
排序有哪些? 原理是什么?
1 冒泡排序
1 原理: 相邻元素比较, 后面的比前面的小, 就交换位置, 把最大的元素冒泡出来(即排到最后)
2 时间复杂度:n的平方。原地修改数组
3 但是性能会比较差
2 快速排序
3 选择排序
1 原理:
1 先选择出最小的元素, 记录其索引位置, 然后和第一个索引位置的元素交换位置
2 然后选择出第2小的元素, 和第二个索引位置的元素交换
3 ...
2 时间复杂度:n的平方。原地修改数组
4 插入排序
1 原理
1 把所有元素分为两组,已排序的和未排序的
2 找到未排序组中的第一个元素,向已经排序的组中进行插入, 与已排序的数据进行比较, 将元素插入到合适的位置
3 倒序遍历已经排序的元素,
2 时间复杂度:n的平方。原地修改数组
3 简单直观且稳定的排序算法
5 希尔排序(插入排序的改良版)
6 归并排序