- 反射
- java中通过反射机制操作字节码文件
- 通过三种方式获取类实例
- Classs.forName
- 类.class
- 类.getClass
- 通过类实例操作类属性、方法,改变其值
- 多线程
- 线程和进程有什么区别
- 线程是最小单位,线程属于进程中
- 一个应用程序就代表一个进程,一个进程中包含多个线程
- 多线程怎么使用
- 通过继承thread类或实现Runnable接口
- 使用runnable好处,避免单继承局限性,更好的分离线程代码逻辑与程序业务逻辑,符合面向对象设计思想
- 为什么要用多线程,解决什么问题
- 如一个请求需要10s,但我如果创建10线程同时执行,那么最终只需要耗时1s。
- 使用场景可以是读取多个文件内容,大数据量使用多线程分批读取,达到资源最大化利用,以及提升系统响应性能
- 多线程怎么保证数据安全
- 通过sync关键字或lock锁来锁住共同访问的代码块,这样同时只有一个线程进行访问,操作数据
- 多线程生命周期有哪些
- 新建、就绪、(阻塞)、运行、终止
- 线程有哪些方法
- wait等待、notify唤醒线程、notifyAll唤醒所有睡眠线程
- 线程池有哪些,怎么使用,分别用在什么场景
- newSingleThreadExexcutor:单线程数的线程池(核心线程数=最大线程数=1)
- newFixedThreadPool:固定线程数的线程池(核心线程数=最大线程数=自定义)
- newCacheThreadPool:可缓存的线程池(核心线程数=0,最大线程数=Integer.MAX_VALUE)
- newScheduledThreadPool:支持定时或周期任务的线程池(核心线程数=自定义,最大线程数=Integer.MAX_VALUE)
- 上面四种线程池类都继承ThreadPoolExecutor,在创建时都是直接返回new ThreadPoolExecutor(参数),它们的区别是定义的ThreadPoolExecutor(参数)中参数不同,而ThreadPoolExecutor又继承ExecutorService接口类
- 线程池能够节约资源使用,能够使线程重复使用,统一管理。可以在多任务同时处理使用,如,查询商品详情,可以分多个线程同时去查询商品库存、商品基础信息、商品价格等
- 缺点:使用了LinkBlockQueue的链表型阻塞队列,当任务的堆积速度大于处理速度时,容易堆积任务而导致OOM内存溢出
- 线程和进程有什么区别
- 集合
- 常用集合有哪些,哪些是安全的,哪些是不安全的
- ArrayList、LinkedList、Vector、HashTable、HashMap、HashSet、TreeSet
- 线程安全的:Vector、HashTable
- 线程不安全的:ArrayList、LinkedList、HashMap、HashSet、TreeSet
- 数组和集合有什么区别
- 数组长度是不可变的,集合可以
- 数组可以存基本数据类型和引用数据类型,集合只能存引用数据类型
- ArrayList、LinkdedList、Vector有什么区别
- ArrayList:底层数组实现,线程不安全,查找快
- LinkdedList:底层双向链表实现,线程不安全,增加、删除快
- Vector:底层数组实现,线程安全
- ArrayList底层使用什么数据结构,默认大小是多少
- 数组,初始容量10,每次扩容为当前大小1.5倍
- ArrayList和HashSet有什么区别
- ArrayList:值可以重复,通过下标访问,有序
- HashSet:值不可以重复,没有下标,无序
- HashSet和TreeSet有什么区别
- HashSet:底层数组,链表,红黑树实现
- TreeSet:底层红黑树实现,还实现了sortedSet接口,可以对插入的元素进行排序
- HashMap、HashTable、TreeMap区别
- HashMap:key不能重复,值可以重复,线程不安全的,底层使用数组+链表+红黑树实现,初始容量16,当存储的数量大于当前容量乘以0.75后,扩容为原来的2倍
- HashTable:线程安全的
- TreeMap:线程不安全的,底层使用红黑树实现,可以对key进行自动排序
- 常用集合有哪些,哪些是安全的,哪些是不安全的
- 锁、CAS
- cas原理是什么
- 用于实现多线程同步的原子指令。当多个线程对同一个资源进行cas操作时,只有一个线程会成功,其他线程会操作失败,但不会阻塞其他线程继续访问,cas也是一个乐观锁的实现
- 为什么要用,解决什么问题
- 解决多个线程操作同一个资源时,造成脏数据问题,如:有a=1,线程1获取a并加1,线程2同时获取a加1,然后线程1写入a变成2,线程2也写入a变成2,那么数据最终只加1,但实际最终结果是要3
- cas 是怎么实现的
- 利用unsafe 这个类提供的 cas 操作
- 依赖jvm 针对不同的操作系统实现的 Atomic
- Atomic 的实现使用了汇编的 cas 操作,并使用 cpu 硬件提供的 lock信号保证其原子性
- CAS存在什么问题
- ABA问题:原子类 AtomicStampedReference类compareAndSet方法,或追加版本号
- 循环时间长开销大:JVM能支持处理器提供的pause指令
- 只能保证一个共享变量的原子操作:一个变量可以使用cas保证原子性,如果是多个可以使用AtomicReference类把多个变量放到一个对象中进行cas操作,也可以通过合并多个变量变成一个来cas操作
- AQS是什么,运行原理是什么
- aqs是多线程同步器,提供了两种锁机制,分别是排它锁和共享锁。它的内部实现的关键就是维护了一个先进先出的队列以及state状态变量
- cas原理是什么
- io流
- io流有哪些
- 按功能划分:输入流、输出流
- 按处理类型划分:字节流、字符流
- 字节流:
- InputStream
- FileInputStream
- FilterInputStream
- BufferedInputStream
- OutputStream
- FileOutStream
- FilterOutStream
- BufferedOutStream
- InputStream
- 字符流:
- Reader
- BufferReader
- InputStreamReader
- FileReader
- Writer
- BufferWriter
- OutputStreamWriter
- FileWriter
- Reader
- 字节流:
- io有什么用,解决什么问题
- 读取txt文本、excel表格内容
- io和nio有什么区别
- io是阻塞流,面向流,无选择器
- nio非阻塞流,面向缓冲,用到块,效率比io高,有选择器
- nio有什么缺点
- 每次数据处理要判断缓冲区数据是否完整或者已经读取完毕
- nio使用场景有哪些
- nio:使用多个连接,但每次只发送少量数据场景
- io:使用少量连接,但发送大量数据场景
- nio组件有哪些
- channels、buffers、selectors,其他pipe、FileLock建立在基础组件上更好的使用工具类
- io流有哪些
- 事务
- 在JAVA中什么是事务?
- 使用java程序jdbc操作数据库增、删、改方法,称为事务。可以理解为是一组原子操作单元,从sql角度理解就是一组sql命令,要么都成功,要么都不成功
- 为什么要使用事务?
- 当我们处理数据时中间过程抛出异常,要保证数据一致性、完整性时
- 什么时候使用事务?
- 事务是为了解决数据安全操作而提出的,如:银行转账,a转账给b,a扣款成功后,由于网络中断b没有收到,那么整个业务是失败的,这时就需要事务要么全部执行成功,要么全部执行失败
- Java事务的类型
- jdbc事务,在一个数据库连接内
- 容器事务,j2ee应用服务器提供的事务管理
- jpa事务,可以跨多个数据库
- java事务原则
- ACID:原子性、一致性、隔离性、持久性
- springboot事务开启方式
- 启动类添加注解@EnableTransactionManagement开启事务,然后在使用事务的类或方法上面添加注解@Transactional(rollbackFor = Exception.class)
- 逻辑上手动回滚: TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
- 在JAVA中什么是事务?
- JVM虚拟机
- jvm内存结构是怎么样的
- 堆:用来存放对象、数组,所有线程都共享
- 栈:存放的是栈帧,每个栈帧对应一个调用的方法,在栈帧中包括局部变量表、方法返回地址、运行时常量池引用等
- 本地方法区:与java栈原理类似,区别就是java栈是为java方法服务的,而本地方法区是为执行本地方法服务的
- 方法区:所有线程都共享,存放了类的信息,包括类名称、方法名称、字段,静态变量、常量等
- 程序计数器:能够在线程切换后恢复到切换之前的程序执行位置,每个线程都一个独立程序计数器,并不会相互干扰
- jvm中怎么判断一个对象是否存活
- 引用计数法:给每个对象设置一个引用计数器,每次引用就加1,引用失效就减1,如果引用计数器为0时被垃圾回收
- 可达性算法:从GC Roots对象开始向下搜索,如果一个对象到GC Roots没有任何引用链相连时,则说明此对象不可用
- jvm调优参数有哪些,给你个8g内存怎么分配
- 在JVM中,主要是对堆(新生代)、方法区和栈进行性能调优
- 堆:-Xms、-Xmx
- 新生代:-Xmn
- 方法区(元空间):-XX:MetaspaceSize、-XX:MaxMetaspaceSize
- 栈(线程):-Xss
- 按照经验分配:java ‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐jar xxx.jar
- 在JVM中,主要是对堆(新生代)、方法区和栈进行性能调优
- jvm内存溢出怎么排查解决
- dump内存溢出日志进行分析
- 定位是堆内存满了、代码死循环、没有释放连接、多线程阻塞等问题
- 然后在排查项目调用链路,是在哪里引发内存溢出的
- java代码执行过程是怎么样的
- 加载.class文件
- 管理并分配内存
- 执行垃圾收集
- jvm生命周期是怎么样的
- jvm实例是一个进程级别的,是由启动、运行、消亡组成的生命周期
- jdk、jre、jvm是什么关系
- jdk是用来编译、调试程序用的开发包
- jre是java运行平台,用来运行java程序
- jvm是jre的一部分,是一个虚拟计算机,有完善的硬件架构,如寄存器、堆、栈、处理器等,而java最重要的特点就是跨平台,使用jvm就是为了跨平台。jvm在执行字节码时,最终会把字节码解释成具体平台机器指令执行
- jvm原理
- 通过编译器把源代码编译成字节码
- 由类加载器进行加载
- 在通过字节码校验器
- 然后在到解释器转成机器指令到硬件
- jvm双亲委派机制是什么?为什么要使用?
- 先使用父类加载器加载,如果找不到目标类,就使用子加载器自己加载
- 为了保证代码安全性,也就是沙箱安全机制,才使用双亲委派机制
- 类加载过程,以及加载类有哪些
- 加载、验证、准备、解析和初始化
- 引导类加载器:加载lib目录下jar包
- 扩展类加载器:加载ext目录下jar包
- 应用类加载器:加载用户类路径上所指定的类库
- jvm内存结构是怎么样的
- 设计模式
- 常用设计模式有哪些
- 设计模式有23种,分为三大类:创建型模式、结构型模式、行为型模式
- 创建型模式:创建型模式用于解耦对象实例化过程
- 单例模式
- 工厂模式
- 抽象工厂模式
- 建造者模式
- 原型模式
- 结构型模式:把类或对象结合形成一个更大的结构
- 适配器模式
- 代理模式
- 桥接模式
- 组合模式
- 装饰模式
- 外观模式
- 享元模式
- 行为型模式:类和对象如何交互,及划分责任和算法
- 责任链模式
- 策略模式
- 访问者模式
- 命令模式
- 迭代器模式
- 解释器模式
- 观察者模式
- 备忘录模式
- 状态模式
- 模板模式
- 中介者模式
- 为什么要用,解决什么问题
- 提高代码可读性、可扩展性和可复用性,解决在写代码过程遇到的设计问题
- 设计模式有哪些原则
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换原则:子类可以替换父类任何功能(体现父类的可扩展性)
- 依赖倒转原则:尽可能面向接口编程,依赖接口而不依赖类
- 接口隔离原则:一个类能实现多个接口,尽可能实现多个,为了降低依赖和耦合
- 最少知道原则:实体之间尽可能不要产生关联关系,能够将实体功能独立
- 合成复用原则:尽量使用合成、聚合的方式,而不使用继承
- 常用设计模式有哪些
面试Java高级工程师之基础总结
于 2022-07-17 19:08:06 首次发布