Java高频面试题复盘系列之小问题集合篇1

64 阅读7分钟

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 returnreturn的功能是结束一个方法。 一旦在循环体内执行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 利用trycatch…
          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 归并排序