大佬教程收集整理的这篇文章主要介绍了面经打怪升级系列【一】,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
1. 自我介绍
2. 具体介绍一下最主要的项目,以及承担的工作,技术难点?
3. 你们使用 redis 具体的使用场景?
1. 热点数据的缓存
由于redis访问速度快、支持的数据类型比较丰富,所以redis很适合用来存储热点数据,另外结合expire,我们可以设置过期时间然后再进行缓存更新操作,这个功能最为常见,我们几乎所有的项目都有所运用。
2. 高并发的读写
将数据库中的库存数据同步到 redis ,业务逻辑直接在redis 中操作数据,在某个时间点将缓存数据同步到数据库
3. 数据共享
将用户的登录信息存储在redis 中,其他模块或工程从redis 中直接获取
4. 分布式锁(为了保证多台服务器在执行某一段代码时保证只有一台服务器执行)
5. 自增长编号的生成
4. 热点数据放缓存的场景?
- 热点数据,频繁查询,放到redis中,降低数据库的压力
- 查询耗时的数据,每次查询耗费时间的请求,每次查询数据库会影响系统的响应速度
5. 技术选型为什么选择 Mybatis,他解决了什么问题?
1. 什么是 MyBatis?
2. 原生JDBC 的问题?
sql夹在Java代码块里,耦合度高导致硬编码内伤
维护不易且实际开发需求中sql是有变化,频繁修改的情况多见
3. Hibernate和JPA 问题?
长、难复杂sql,对于Hibernate而言处理也不容易
内部自动生产的sql,不容易做特殊优化
基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难。导致数据库性能下降
4. MyBatis 优势?
6. Mybatis 是怎么做到防止 sql 注入的?预编译动作是在什么环节发生的?
#{}是经过预编译的,是安全的;
${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在sql注入
7. Spring 的 AOP 讲一下?
8. 线程都有哪些状态,是怎么转换的?
「新建状态(New)」:新创建了一个线程对象。
「就绪状态(RunnablE)」:线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“「可运行线程池」”中,变得可运行,只「等待获取cpu的使用权」。「即在就绪状态的进程除****cpu之外,其它的运行所需资源都已全部获得。」
**阻塞状态(Blocked):**阻塞状态是线程因为某种原因放弃cpu使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
「阻塞的情况分三种:」
(1)、「等待阻塞」:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“**等待池”**中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,
(2)、「同步阻塞」:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入**“锁池”**中。
(3)、「其他阻塞」:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
9. 抽象方法可以加 static 修饰吗?可以加 synchronized 吗?可以加 native 吗?
不可以加 static 修饰
不可以加 native 修饰
native 暗示这些方法是有实现体的,只不过这些实现体是非java 的,但是abstract却显然的指明这些方法无实现体。
不可以加synchronized 修饰
用synchronized的前提是该方法可以被直接调用,抽象方法的抽象类不可以被实例化,自然也无法被调用
10. JVM 类加载的过程?
「加载」:将字节码文件加载到内存中,将其存放到运行时数据区的方法区内,并在堆区中创建一个该类的Class对象,Class对象中封装了方法区内的数据结构,并提供了访问方法区数据结构的接口。字节码可以存在于本地磁盘、网络上、zip或jar等归档包、数据库等地方
「验证」:校验字节码文件的格式,确保加载的类的正确性
「准备」:给类的静态变量分配内存,并初始化默认值,比如int类型就初始化为0,Boolean类型就初始化为false等,而非初始化为代码中显式赋予的值;
「解析」:把类中的符号引用转换为直接引用
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。
符号引用:就是一组符号来描述目标,可以是任何字面量。
直接引用:就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄
「初始化」:为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化
11. java 里 GC 的机制,怎么判断一个对象是可回收的?
「引用计数」
每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题
「可达性分析」
从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象
12. 什么情况下会发生内存泄漏?
「static字段引起的内存泄漏」
大量使用static字段会潜在的导致内存泄漏,在Java中,静态字段通常拥有与整个应用程序相匹配的生命周期。
「静态集合类引起内存泄漏」
这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放
「当集合里面的对象属性被修改后,再调用remove()方法时不起作用」
public static void main(String[] args)
{
Set<Person> set = new HashSet<Person>();
Person p1 = new Person("唐僧","pwd1",25);
Person p2 = new Person("孙悟空","pwd2",26);
Person p3 = new Person("猪八戒","pwd3",27);
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:3 个元素!
p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变
set.remove(p3); //此时remove不掉,造成内存泄漏
set.add(p3); //重新添加,居然添加成功
System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:4 个元素!
for (Person person : set)
{
System.out.println(person);
}
}
「各种连接未关闭」
一般都会在try里面连接,在finally里面释放连接
13. 两个对象 Hashcode 一致的时候,equals 会相等吗?
两个对象的equals() 相等,hashCode()一定相等。
两个对象的hashCode()相等,equals()不一定相等
14. 解释一下什么是 Hashcode?
15. 往一个 Hash 表插入一个键值对的时候的过程是什么?
初始化table
计算hash值
插入或更新节点
扩容
16. 讲一下最熟悉的数据结构?
17. Docker 原理?为什么比虚拟机更轻?
「docker 是什么?」
「为什么Docker比虚拟机快?」
docker有着比虚拟机更少的抽象层。由亍docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在cpu、内存利用率上docker将会在效率上有明显优势。
docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。因而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了整个过程,因此新建一个docker容器只需要几秒钟。
18. 虚拟机的隔离和 docker 容器的隔离有什么区别?
docker属于进程之间的隔离,虚拟机可实现系统级别隔离;
docker 容器 借助 Linux 内核技术Namespace来做到隔离的,Docker 技术由于 还是一个普通的进程,所以隔离不是很彻底,还是共用宿主机的内核,在隔离级别和安全性上没有虚拟机高,这也是它的一个劣势。
容器其实就是Linux下一个特殊的进程;
Docker容器通过namespace实现进程隔离;通过cgroups实现资源限制;
Docker镜像(rootfs)是一个操作系统的所有文件和目录而不包括内核,Docker镜像是共享宿主机的内核的;
19. 为不同的微服务提供统一的网关应该怎么做?
「路由」
微服务服务注册和发现,服务在应用内部被管理而通过网关路由定位,调用不同的服务
「负载均衡」
「聚合」
将多个服务的多个请求结果聚合,合并返回
「鉴权」
通过网关鉴权,更加高效的访问每一个服务,而不用每个都执行鉴权
「断路限流黑白名单」
在网关层面实现断路器, 即超过了指定的阈值,API网关就会停止发送数据到那些失败的模块。这样可以防止服务之间的调用延时造成的雪崩,又有足够的时间来分析日志,修复问题
可以对流量进行限制,实现限流的能力,缓解下层服务的压力
可以通过黑白名单设置,直接禁止某些请求到达下层应用,防止恶意访问等情况
「监控日志」
监控各个应用的基础指标,记录聚合业务日志,标记异常堆栈,方便追踪排查
「灰度发布」
通过网关的流量控制,可以实现新旧版本同时"服役",通过实际流量检验服务情况,并实现服务的平滑升级。
以上是大佬教程为你收集整理的面经打怪升级系列【一】全部内容,希望文章能够帮你解决面经打怪升级系列【一】所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。