我的java面试总结及笔记

1.Euraka自我保护机制:

  某时刻某个微服务不可用了,Euraka不会立刻清理,依旧会对该服务信息进行保存

 

2.谈谈对微服务的理解:

  微服务强调的是一个个的个体,每个个体完成一个具体的任务和功能;

  将单一应用程序划分成一组小的服务,每个服务运行在其独立的自己的进程中

 

3.说一下dubbo和springCloud的区别

  通信机制不一样,dubbo用RPC、springCloud用restful

 

4.谈谈微服务的优点

  每个服务足够内聚、足够小;

  开发简单、开发效率高;

  小团队单独开发;

  送耦合,独立部署;

  不同语言开发;

 

5.SpringCloud是什么?

  分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体

 

6.Euraka和Zookeeper的区别

   C:强一致性    A:可用性   P:分区容错性

     Zookeeper属于CP

     Euraka属于AP(各个节点平等,没有主从)

 

7.Ribbon 客户端的负载均衡

 

8.进程与进程之间如何通信?

   a:管道

   b:消息队列

   c:共享内存

   d:信号量

   e:socket

 

9.Spring的IOC

  实现原理:工程模式加反射机制

 

10.Spring的AOP

  实现原理:代理设计模式

  核心:在方法前或方法后处理事情

  作用:复用和解耦

  应用场景:日志、事务、权限、性能监控、异常处理

 

11.Spring的AOP中的关注点、切面、切入点怎么理解

  关注点:重复代码

  切面:关注点形成的类,可以叫切面类;将重复的代码抽取出来,在运行的时候动态植入

  切入点:哪些方法可以被拦截

 

12.静态代理和动态代理区别

  静态代理需要生成目标代理对象

  动态代理不需要

 

13.jdk代理和CGLIB代理

  jdk动态代理只需要子类实现,基于反射实现(反射虚拟生成代理类)

  CGLIB是基于ASM字节码包装的一个类库(基于ASM字节码虚拟生成代理类)

 

14.阿里规约为什么不建议new线程?

  因为new线程创建了一个size为Integer.MAX_VALUE的线程阻塞队列,可能会堆积大量请求,消耗很大内存

 

15.HashMap扩容怎么实现

  如果大于等于阈值(当前数组长度乘以加载因子)时就扩容,使用一个新的数组代替已有的容量小的数组

 

16.requestBody和requestParam区别

  requestParam在requestHead里面取值,requestBody在requestBody里面取值

 

17.Mysql索引类型

     1.普通索引  create index index_name on mytable (name)

     2.唯一索引  create unique index index_name on mytable (name)

     3.主键索引

     4.组合索引

     5.全文索引  create Full Text index index_name on mytable (name)

 

18.索引的缺点

  索引本身也是表,因此会占用存储空间,在修改数据时(增,删,改)同时还需要修改索引表

 

19.什么时候使用索引

  1.主键自动建立唯一索引

  2.经常作为查询条件在where或者order by 语句中出现的列要建立索引

  3.作为排序的列要建立索引

  4.外键关联建立索引

  5.高并发下倾向组合索引

  6.用于聚合函数的列可以建立索引;例如:max()、count()

 

20.什么时候不要使用索引

    1.经常增删改的列

    2.有大量重复数据的列

    3.表中数据少

 

21.电脑的32位和64位是什么意思?

   指CPU一次处理数据的能力是32(2的32次方)位还是64位,

   32位系统的处理器最大只支持到4G内存,而64位系统支持的内存高达亿位数

 

22. su -root   环境变量一起切换

 

23 谈谈JVM

  JVM由两个子系统(classLoader类装载器和execution engine 执行引擎)

  和两个组件(Runtime data运行时数据区和Native interface 本地接口) 组成

 

24.类加载过程

  类加载器把java代码转换为字节码,运行时数据区再把字节码加载到内存中

  而字节码并不能直接交给底层操作系统去执行

 因此需要特定的命令解析器执行引擎将字节码翻译成底层系统指令,

  再交由CPU去执行,而这个过程需要调用其他语言的本地库接口

 

25.注解 例如:@Override

  @Target(ElementType.METHOD)

  @Retention(RetentionPolicy.SOURCE)

  public @interface Override{}

  Target:定义的注解可以用在什么地方

  Retention:注解声明周期,定义注解存活阶段 (source:源码级别、class:字节码级别、runtime:运行时级别)

 

26.微服务有哪些模块

  服务注册与发现、服务消费、负载均衡、断路器 、智能路由、配置管理

 

27.springCloud的服务调用

  1.ribbon + testTemplate(可以进行负载均衡)

  2.feign  

      a.采用的是基于接口的注解

     b.整合了Ribbon,具有负载均衡能力

     c.整合了Hystrix,具有熔断能力

 

28.谈谈zuul

  路由转发和过滤器

  filterType:返回一个字符串代表过滤类型(pre:路由前、post:路由后、routing:路由之时、error:发送错误调用)

  filterOrder:过滤的顺序

  shouldFilter:可以写逻辑判断。是否要过滤,true ->永远过滤

  run:过滤器的具体逻辑

 

29.springCloud Bus消息总线

  将分布式的节点用轻量的消息代理连接起来,用于广播文件的更改或者服务间的通讯,也可以用于监控

 

30.redis有哪些数据类型

  string、list(列表)、set(集合)、zset(有序集合)、hash(散列)

  

31.怎么在项目中配置Redis

   1.添加Redis依赖包   2.配置Redis数据库连接

 

32.线程池有哪些参数?都是什么意思?

  new ThreadPoolExecutor(

  corePoolSize:      //核心线程数

  maximumPoolSize:   //线程上限

  keepAliveTime:   //超过corePoolSize的线程idle时间

  timeUnit:   //超过这个时间多余的线程就会被收回

  hanlder:  //拒绝策略

  BlockingQueue    //任务的排队队列

  )

流程:小于核心线程数:每来一个任务就会创建一个线程去执行

           超过核心线程数:则加入到任务队列中

                                     若加入队列成功,则等待空闲线程将它取出去执行

                                     若失败,则创建新的线程

线程数大于maximumPoolSize时则采取任务拒绝策略进行处理

 

33.合理的配置线程池的线程数

  CPU密集型任务:尽可能减少线程,CPU+1 个

  IO密集型任务:2xCPU 个

   java获得CPU个数的方法:Runtime.getRuntime().availableProcessors()

 

34.synchronized和Lock区别

  1.synchronized是java关键字,而Lock是一个接口

  2.synchronized同步时,一条线程用完会自动释放锁;Lock需要手动释放,如果不收到释放,可能会死锁

  3.Lock可以使用响应中断或用规定等待时间的锁(有方法)

  4.Lock可以得知是否获得锁

  应用场景:对于资源竞争不激烈时,但当大量线程同时竞争时用Lock

 

35.锁的种类

  1.类锁:当synchronized指定修饰静态方法或者class对象时,拿到的就是类锁,类锁是所有对象争抢一把

  2.对象锁:每个对象都有一把,如果同一个类有两个对象,不安全

 

36.在JVM中,对象在内存中的布局?

  可分为对象头、实列数据、对齐填充

  每一个对象都有一个moniter监视器,调用moniter就是尝试获取这个对象,成功获取就将值+1,离开值减1

 

37.谈谈TreadLocal

 ThreadLocal是一个线程级别的局部变量,为每个使用该变量的线程提供了一个独立的变量副本,

  每个线程修改副本时不影响其他线程对象的副本

 

38.ConCurrentHashMap是安全的,怎样实现的?

  ConCurrentHashMap将数据分为多个segment,默认16个

  每次操作对一个segment加锁

  其实没有使用锁:用到了volatile,变化可以立刻得知

 

39.java代码平时是怎样优化的?

  1.尽量指定类,方法final修饰符(编译器会内联所有final方法,性能提升50%)

  2.尽量重用对象

  3.尽量使用局部变量

     局部变量保存在栈中,栈中创建的对象随着方法运行结束就没有了,不需要回收

    静态变量,成员变量保存在堆中,较慢

   4.及时关闭流

   5.尽量减少对变量的重复调用

    例如:list.size()    应当 int length = list.size()  用length

  6.String常量之类的,用枚举或者常量代替

  7.for循环中如果要new对象,把引用放到for循环之外,整个for循环就只创建了一个对象

 

40.SQL的执行顺序

 from + join  

 where

 group by 

 having

 select

 order by 

 limit

 

41.sql中的in和exist区别

  in适合主表大,子表小

  exist适合主表小,子表大

 

42.start()方法用来启动一个线程,此时线程处于就绪状态,并没有运行;调用run()来完成运行操作

 

43.线程池有哪些

  newSingleThreadExecutor

  newFixedThreadPool(定长线程池,有最大并发数,超出线程会在队列中等待)

  newCachedThreadPool

  newScheduledThreadPool(处理定时任务)

 

44.IOC常见容器:ApplicationContext、BeanFactory

    IOC是基于反射机制和工厂模式实现的

 

45.多态:不用修改源程序代码就可以让引用变量绑定到各种不同的实现类上,让程序可以选择多个运行状态。

多态:让引用变量绑定到各种不同的类实现上

 

46.toStirng  快于  String.valueOf()   快于    +“” 

 

47.构造方法不能被继承

 

48类中声明的变量(成员变量)有默认初始值;

   方法中的(局部变量)没有,必须定义初始值

 

49.native关键字

 方法对应的实现不是在当前文件,而是在用其他语言实现的文件中

 

50.String s = "abc"

    先去字符数据池中搜索,有,直接用;没有再生成一个;

    new创建字符串时先看字符数据池中有没有,有则拷贝一份到堆中,然后返回堆中地址;没有则在堆中创建一份

   

51.两个Integer类型进行==比较,如果在-128-127,则返回true;否则返回false

 

52.两个基本类型的封装进行equals()比较,首先用equals()比较类型,类型相同,则继续比较值,值也相同则返回true

 

53.transient关键字

  用transient关键字标记的成员变量不参与序列化过程

 

54.ArrayList底层是数组

 可变长度的数组,数组扩容时,会将老的数组中的元素重新拷贝到一个新的数组中

 用到了Fail-Fast机制

 

55HashMap

  HashMap是基于哈希表的Map接口非同步实现

  底层使用数组实现,数组中每一项是一个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树

 将key-value作为一个node对象  放在一个Node[] 数组中

 当存储一个Node时,key的hash算法决定在Node[]中的存储位置,再根据equals()方法决定在Node[]位置上链表中的位置。

超过阈值扩大一倍

 

56.类的初始化顺序

父类 --> 类构造器方法  --> static变量赋值语句 --> static{}代码块

 

57.类的定义信息、常量、静态变量在方法区;

  成员变量、集合在堆;

  引用和私有变量在栈   -->线程私有;

  程序计数器:执行到哪一行;

  native stack:本地方法(和操作系统相关)-->本地栈

 

58.Http默认情况下建立TCP连接不会断开,只有在请求报头中声明connection:close才会在请求完后关闭连接;

  一个TCP连接可以发送多个HTTP请求

 

59.SpringFactoriesLoader从classPath中搜寻所有META/spring.factories文件,并将其中的key -> 全类名的

  EnableAutoConfiguration  对应的value通过反射方式实例化为对应的标注了@Configuration的IOC容器配置类

 

60.@SpringBootApplication注解由哪些注解组合而成?

  @SpringBootConfiguration  标准的standalone类型的java程序的main函数启动类,也没有特殊的东西

  @EnableAutoConfiguration 能实现自动配置的原理

  @ComponentScan  非必须

 

61.FastDateFormat线程安全的

 

62.java11有哪些新特性?

  1.自动类型推断,var s = "java"  等于 String s ="java"   

  2.字符串加强  isBlank(),strip()(去首尾空格) ,repeat()复制,lines().count()行数统计

  3.不可变集合  List.of("a","b");   List.copy(list);

 

63.java强制我们wait()/notify()调用必须在同一个同步代码块中,以避免lost wake up 异常

  lost wake up 异常:消费者在检查count到调用wait()之间,count被改掉了,准备唤醒一个线程,而这个时候消费者还没睡呢,

  所以这个通知丢掉,消费者就睡过去了

 

64. kotlin

  完全兼容java、null safe、支持lamda表达式、支持扩展、体验一致的开发工具

 

65.Docker(go语言开发)

  虚拟化技术(简化配置、快速部署)

  是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植容器中

  然后发布到任何流行的Linux机器上

为什么用? 更快的交付和部署、更轻松的迁移和扩展、更简单的更新管理

 1.解决了运行环境和配置问题,方便发布

  2.更轻量级的虚拟化,节省了虚拟机的性能损耗

 

66.static成员方法

 static方法是类的方法,不需要创建对象就可以调用,并且不能使用this和super关键字

  不能调用非static方法,只能访问所属类的静态成员变量和方法

  因为当static方法被调用时,改类的对象可能还没有被创建,即使创建了,也无法确定是哪个对象的方法

 

67.如果有x.equals(y),那么一定会有x.hashCode()==y.hashCode()

    如果x.hashCode() != y.hashCode(),那么一定会有x.equals(y) == false

   其他情况则不一定

 

68.存储过程和函数有什么区别?

 1.函数有返回值

  2.函数在创建中没有declare关键字,而是用is或者as关键字代替

 

69. 堆 = 年轻代 + 老年代 +持久代(类定义在持久代)

  年轻代:老年代 = 1:4

  回收15次后进入老年代

  复制算法

 

70.RPC:远程过程调用协议

  通过网络从远处计算机程序上请求服务,而不需要了解底层网络技术的协议

 

71. Nginx: (HTTP server) 常做静态内容服务器和代理服务器

    Tomcat/JBoss/jetty :(Application Server) 应用容器

 

72.怎样对sql进行优化?

 1.首先考虑在where及order by涉及的列上建立索引

  2.应尽量避免在where中对字段进行null判断,使用!=或大于小于,否则导致索引失效

  3.尽量避免用or来连接条件,可以用union all

  4.in和not in 会导致全表扫描,能用between 不用in

  5.索引不适合超过6个

  6.任何地方都不要使用select *

  7.like 'name%' 索引有效

  8.避免在where后进行函数操作

 

73.Netty 是把NIO封装后的一个框架

  本质:JBoss做的一个jar包

  目的:快速开发高性能、高可靠的网络服务器和客户端服务器

  优点:提供异步的、事件驱动的网络应用程序框架和工具

  一句话就是一个好使处理socket的东西

  NIO:NoneBlocking IO  非阻塞IO(同步非阻塞)

         NIO用的事件机制,用一个线程把Accept,Read,Write 请求处理的逻辑全干了,如果什么事都没有做,它也

         不会死循环,它会将线程休眠起来,直到下个事件来了再继续干活

 

  BIO:Blocking IO 阻塞IO (同步阻塞)例如:Read是阻塞的,只有请求来了,Read才能返回,子线程才能继续

 

74.分布式事务的解决方案?

  1.基于可靠消息服务的分布式事务

  2.TCC(补偿事务)

  3.最大努力通知

   分布式系统:部署在不同节点上的系统通过网络交互来完成协同工作

   事务:由一组操作组成的一个工作单元,这个单元具有原子性、一致性、隔离性、持久性

   幂等性:指同一个操作无论请求多少次,其结果都相同

    实现幂等性方法有:1操作之前在业务方法进行判断,如果执行过了就不再执行

                                     2缓存所有请求和处理结果,已处理的直接返回结果

                                    3在数据库中加一个状态字段(未处理、已处理)

 

 用RocketMQ实现可靠消息事务:

   1.发送Prepared消息

   2.update DB

   3.根据上一步成功或失败,confirm或者取消Prepared消息

      RocketMQ会定期(默认一分钟)扫描所有Prepared消息,询问到底是发送这条消息还是取消

 

  74.消息队列并不仅为了解决通讯问题,更重要的,它主要用来实现异步处理、服务解耦、流量控制

 

75.JDK的克隆是浅度克隆,它只将对象中的基础数据类型克隆到新的对象中,引用类型只克隆一个引用,克隆后的引用还是指向原对象

深克隆对象可以用:mapstruct、反射、序列化和反序列化

 

76. 对象由什么组成?

  一个对象包含对象头、实列数据、对齐填充

  对象头:GCage、hashCode、synchronized

 

77.Synchronized

  1.synchronized加锁对象为A,叫对象锁,进入同步代码块之前要获取锁

    synchronized (a) {}

  2.在静态方法上加锁。加锁类型是这个方法对应的类锁

    public static synchronized void test(){}

  3.实例锁:实列方法上加锁。加锁类型是这个方法对应的对象

    public synchronized void test() {}

 

78. 谈谈mybatis的二级缓存?

    Mybatis默认支持一级缓存

   一级缓存是sqlSession级别

  二级缓存是跨sqlSession的,是mapper级别(同一个命名空间namespace)的缓存,不同的sqlSession是可以共享的

 

缓存的数据结构:map 

key:hashcode + sql +sql参数 +结果 

value:用户信息

 

怎样开启二级缓存:

   1.配置文件

    

       

   

  2.对应的映射文件mapper里加 

  3.需要将查询结果映射的pojo实现序列化接口,不实现则抛出异常(二级缓存可以将内存数据写到磁盘,存在序列化和反序列化,所有需要实现serializable接口)

 

什么时候不适合用二级缓存?

  对于变化频率较高的sql,需要禁用二级缓存