记录面试碰到的一些问题

String

  1. String为什么被设计为final

为了安全性考虑,String不被继承并且不可变。
不可变最大的好处就是安全,如果String的值被修改,只是被重新引用到了一个新的对象和地址上,所以它在多线程是线程安全的。
便于常量池管理,当两个String的值相同时,它们会指向同一个内存地址。

  1. String、StringBuilder 和StringBuffer的区别
  1. String是不可变类,任何改变都是生成新的String对象。
  2. 其他两个都是可变类,任何改变都不会生成新的对象。
  3. 在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。

线程

  1. 线程的创建方法

线程的创建包括继承Thread,实现Runnable和实现Callable.

  1. start和run的区别
  1. Start方法启动线程,是真正意义上的启动线程,会出现异步执行的效果,调用start时,线程处于就绪状态,并没有运行,得到cpu时间片之后,JVM会自动调用线程的run方法,run方法运行结束,线程结束。
  2. Run方法只是类的一个普通方法,如果直接调用run方法,它依旧是在main主线程中跑,还是单线程顺序执行,并不是启动了线程。
  1. 线程池
  1. newCachedThreadPool创建一个可缓存线程池程

  2. newFixedThreadPool 创建一个定长线程池

  3. newScheduledThreadPool 创建一个周期性执行任务的线程池

  4. newSingleThreadExecutor 创建一个单线程化的线程池

  1. 一般使用newCachedThreadPool比较多
  2. newCachedThreadPool,是一种线程数量不定的线程池,并且其最大线程数为Integer.MAX_VALUE。
  3. 一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。但是线程池中的空闲线程都有超时限制,这个超时时长是60秒,超过60秒闲置线程就会被回收。调用execute将重用以前构造的线程(如果线程可用)。这类线程池比较适合执行大量的耗时较少的任务,当整个线程池都处于闲置状态时,线程池中的线程都会超时被停止。

execute()和submit()方法的区别

  1. 接收的参数不一样,execute()方法的入参为一个Runnable,返回值为void,sumbit()方法,入参可以为Callable,也可以为Runnable,而且方法有返回值Future,可以告诉我它的执行结果,是成功还是失败,然后继续下面的操作。
  2. submit()可以进行Exception处理; 例如,如果task里会抛出checked或者unchecked exception,而你又希望外面的调用者能够感知这些exception并做出及时的处理,那么就需要用到submit,通过对Future.get()进行抛出异常的捕获,然后对其进行处理。

JDK1.8

  1. jdk1.8的 新特性
    1. default关键字,在接口类中,给方法添加default关键字可以是方法在本类被实现,并且该方法不用在实现类被实现,可以直接调用。
    2. lambad表达式(等我看懂了再写)
    3. Date Api更新

1.8引入了DateTimeFormatter类。
LocalDate,LocalTime ,和 LocalDateTime类,都是线程安全的不可变类。

4. Stream(暂时未使用过)
  1. Stream类似于流,单向,不可往复。可以对集合的所有元素进行筛选,过滤,修改等,但是只能对数据遍历一次,如果需要第二次操作,必须继续创建Stream流。

  2. Stream操作分为三个步骤:创建Stream–》中间操作–》最终操作。

5. map底层的更新

map在1.8之后添加了红黑树,在链表长度超过8之后会转换为红黑树,低于等于6会转换为链表,下面Map中解释。

Map

Map的基础概念

Map是一个双列集合,每个元素都有自己的key和value两个值,并且一一对应。
Key和value可以相同也可以不同,但是key不允许重复。 HashMap是数组加链表组成,jdk1.8之后添加了红黑树。
HashMap的主干是entry数组,每个entry包含了一个key-value键值对。
这个entry数组是静态内部类,包含了key,value,next(指向下一个entry的引用,单链表结构),hash(key的hash值)。
HashMap负载因子默认为0.75,默认空间大小为16,意味着如果大小为16的map,到了第十三个元素,就会扩容为32。
在jdk8的情况下,当链表长度超过8,会自动转换为红黑树,利用红黑树快速增删改查的特点提高性能,因为当使用链表时,空间占用小,并且查询速度不慢,但是如果长度越长,查询越慢,这时转为红黑树,保障查询速度,当长度降低到6,又会自动转换为链表。
HashMap和HashMap是无序的
TreeMap和LinkedHashMap是有序的(TreeMap是根据key的字典顺序来排序,默认升序,LinkedHashMap是记录了key的插入顺序)。
LinkedHashMap底层是哈希表和链表,链表记录了添加数据的顺序。 TreeMap底层是二叉树,二叉树的中序遍历保证了数据的有序性。
前序遍历(根在前,从左往右,一棵树的根永远在左子树前面,左子树又永远在右子树前面 )
中序遍历(根在中,从左往右,一棵树的左子树永远在根前面,根永远在右子树前面)
后序遍历(根在后,从左往右,一棵树的左子树永远在右子树前面,右子树永远在根前面)

MySQL索引

  1. 索引类型
  1. Normal 普通索引。
  2. Unique 唯一索引,不会重复。
  3. Full text 全文搜索的索引,主要搜索长文章。
  1. 索引建立原则
  1. 经常排序,分组,联合查询(连接查询)的字段需要建立索引。
  2. 经常作为查询条件的字段。
  3. 尽量选择数据量少的字段。
  4. 限制索引的数量,包括删除不常使用的索引。
  5. 索引字段尽量选择很少进行插入更新的
  1. 索引实现

哈希表,完全平衡二叉树,B树,B+树等数据结构都可以提高查询速度,但是MySQL使用了B+树。

  1. 为什么通过B+树实现

    参考了一些文章,但是忘记文章地址了,b+树看完感觉有点懂,过了两天感觉又忘记了。

  1. 因为哈希索引查询时,是对查询条件进行hash,然后取出数据并且拿到所对应那一行数据的地址,进而查询数据,但是他只能进行精准查询,不支持范围查询,如:where xxx>’’ 这种就不会生效。
  2. 二叉树是有顺序的,左边的小于右边的,他查询的话查找次数会比哈希次数更多
    在这里插入图片描述
  1. B树同样比二叉树的查询效率要好,因为B树的一个节点可以存储多个元素。
    在这里插入图片描述
  1. B+树是B树的升级,把非叶子节点冗余了一下,这样是为了提高范围查询的效率,B+树同样有序。
    在这里插入图片描述
  1. MySQL只对一下操作符才使用索引:<,<=,=,>,>=,between,in,like %%不会生效,但是likexx%却会生效,not in和<>也不会生效

eureka的原理和实现

eureka是spring cloud的注册中心,主要负责存储并维护服务的注册信息。
服务在启动时会将自身的信息发送给eureka,eureka在接收到之后会进行保存
Eureka Client 会每隔 30 秒发送一次心跳来续约,90s未收到心跳,自动过期剔除。

eureka会将这些信息保存在一个map中

服务实体向eureka注册时,注册名默认是“IP名:应用名:应用端口名”
第一层的key是appName,第二层的key是instanceInfoId
private final ConcurrentHashMap<String, Map<String, Lease>> registry = new ConcurrentHashMap<String, Map<String, Lease>>();

Feign的原理和实现

feign主要用来微服务之间调用,使用是定义接口添加注释即可。
feign封装了HTTP调用流程,每次调用其实是发送http请求。

原理可以查看这篇文章,非常详细

剩余之后碰到或者搞懂再写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值