Docker   发布时间:2022-05-13  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了面经打怪升级系列【一】大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

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 优势?

  1. sql语句与代码分离,存放于xml配置文件中,便于维护

  2. 用逻辑标签控制动态sql的拼接

  3. 查询的结果集与java对象自动映射

  4. 编写原生sql,比较灵活

6. Mybatis 是怎么做到防止 sql 注入的?预编译动作是在什么环节发生的?

#{}是经过预编译的,是安全的;

${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在sql注入

7. Spring 的 AOP 讲一下?

8. 线程都有哪些状态,是怎么转换的?

  1. 「新建状态(New)」:新创建了一个线程对象。

  2. 「就绪状态(RunnablE):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“「可运行线程池」”中,变得可运行,只「等待获取cpu的使用权」「即在就绪状态的进程除****cpu之外,其它的运行所需资源都已全部获得。」

  3. **运行状态(Running):**就绪状态的线程获取了cpu,执行程序代码。

  4. **阻塞状态(Blocked):**阻塞状态是线程因为某种原因放弃cpu使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

    「阻塞的情况分三种:」

    (1)「等待阻塞」:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“**等待池”**中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,

    (2)、「同步阻塞」:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入**“锁池”**中。

    (3)、「其他阻塞」:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

  5. **死亡状态(Dead):**线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

9. 抽象方法可以加 static 修饰吗?可以加 synchronized 吗?可以加 native 吗?

  1. 不可以加 static 修饰

    用static声明方法表明这个方法在不生成类的实例时可直接被类调用,而Abstract方法不能被调用,两者矛盾。

  2. 不可以加 native 修饰

    native 暗示这些方法是有实现体的,只不过这些实现体是非java 的,但是abstract却显然的指明这些方法无实现体。

  3. 不可以加synchronized 修饰

    用synchronized的前提是该方法可以被直接调用,抽象方法的抽象类不可以被实例化,自然也无法被调用

10. JVM 类加载的过程?

  1. 「加载」:将字节码文件加载到内存中,将其存放到运行时数据区的方法区内,并在堆区中创建一个该类的Class对象,Class对象中封装了方法区内的数据结构,并提供了访问方法区数据结构的接口。字节码可以存在于本地磁盘、网络上、zip或jar等归档包、数据库等地方

  2. 「验证」:校验字节码文件的格式,确保加载的类的正确性

  3. 「准备」:给类的静态变量分配内存,并初始化默认值,比如int类型就初始化为0,Boolean类型就初始化为false等,而非初始化为代码中显式赋予的值;

  4. 「解析」:把类中的符号引用转换为直接引用

    解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。

    符号引用:就是一组符号来描述目标,可以是任何字面量。

    直接引用:就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄

  5. 「初始化」:为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化

11. java 里 GC 的机制,怎么判断一个对象是可回收的?

  • 「引用计数」

    每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题

  • 「可达性分析」

    从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象

12. 什么情况下会发生内存泄漏?

  1. 「static字段引起的内存泄漏」

    大量使用static字段会潜在的导致内存泄漏,在Java中,静态字段通常拥有与整个应用程序相匹配的生命周期。

  2. 「静态集合类引起内存泄漏」

    这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放

  3. 「当集合里面的对象属性被修改后,再调用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);
    }
    }
    
  4. 「各种连接未关闭」

    一般都会在try里面连接,在finally里面释放连接

13. 两个对象 Hashcode 一致的时候,equals 会相等吗?

  1. 两个对象的equals() 相等,hashCode()一定相等。

  2. 两个对象的hashCode()相等,equals()不一定相等

14. 解释一下什么是 Hashcode?

15. 往一个 Hash 表插入一个键值对的时候的过程是什么?

  1. 初始化table

  2. 计算hash值

  3. 插入或更新节点

  4. 扩容

16. 讲一下最熟悉的数据结构?

17. Docker 原理?为什么比虚拟机更轻?

  1. 「docker 是什么?」

  2. 「为什么Docker比虚拟机快?」

    1. docker有着比虚拟机更少的抽象层。由亍docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在cpu、内存利用率上docker将会在效率上有明显优势。

    2. docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。因而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了整个过程,因此新建一个docker容器只需要几秒钟。

18. 虚拟机的隔离和 docker 容器的隔离有什么区别?

  1. docker属于进程之间的隔离,虚拟机可实现系统级别隔离;

  2. docker 容器 借助 Linux 内核技术Namespace来做到隔离的,Docker 技术由于 还是一个普通的进程,所以隔离不是很彻底,还是共用宿主机的内核,在隔离级别和安全性上没有虚拟机高,这也是它的一个劣势。

  3. 容器其实就是Linux下一个特殊的进程;

  4. Docker容器通过namespace实现进程隔离;通过cgroups实现资源限制;

  5. Docker镜像(rootfs)是一个操作系统的所有文件和目录而不包括内核,Docker镜像是共享宿主机的内核的;

19. 为不同的微服务提供统一的网关应该怎么做?

  1. 「路由」

    微服务服务注册和发现,服务在应用内部被管理而通过网关路由定位,调用不同的服务

  2. 「负载均衡」

  3. 「聚合」

    将多个服务的多个请求结果聚合,合并返

  4. 「鉴权」

    通过网关鉴权,更加高效的访问每一个服务,而不用每个都执行鉴权

  5. 「断路限流黑白名单」

    1. 在网关层面实现断路器, 即超过了指定的阈值,API网关就会停止发送数据到那些失败的模块。这样可以防止服务之间的调用延时造成的雪崩,又有足够的时间来分析日志,修复问题

    2. 可以对流量进行限制,实现限流的能力,缓解下层服务的压力

    3. 可以通过黑白名单设置,直接禁止某些请求到达下层应用,防止恶意访问等情况

  6. 「监控日志」

    监控各个应用的基础指标,记录聚合业务日志,标记异常堆栈,方便追踪排查

  7. 「灰度发布」

    通过网关的流量控制,可以实现新旧版本同时"服役",通过实际流量检验服务情况,并实现服务的平滑升级。

                               

                                编程·技术·经验
                                         欢迎扫码关注
 

                  

面经打怪升级系列【一】

                                      1024快乐编程

大佬总结

以上是大佬教程为你收集整理的面经打怪升级系列【一】全部内容,希望文章能够帮你解决面经打怪升级系列【一】所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: