面试经验

如果一切的努力不是为了让自己更好更优秀的话,那你所表现出来的就是咸鱼现象

为什么要离职

借用马爸爸的话,离职无外乎就是两种情况,1,钱给的不够,2,自己感觉到了委屈,于是乎在前东家呆的有点安逸的时候,我响应到了马爸爸的话,我毅然决然的在8月初的时候提出了离职,这一次离职,个人的总结就是准备不够,有点仓促,加之自己又不太能够沉住气,所以最终还是入职了一个不是互联网公司的公司,尽管中间也拿到了互联网的offer,但是因为一些原因,最终还是没有走向这条路,哎。但是我也给了自己定了一个死目标(有点刚),我一定要好好对待,沉下心来,技术沉淀。

离职的经历

从8月初开始提出离职请求,到九月初入职另一家公司,中间经历了差不多一个月的时间,当然直到27号的时候,我才真正的和我的老东家和平分手(心里还是有点点舍不得),交接完毕,其实真正的找工作开始时间是8月15日,到9月初,前后差不多半个月的时间,断断续续的也是面试了十几家公司,经历过来,艰辛曲折,准备简历,复习知识,饿了肚子去面试,下雨天裤子全部淋湿了差点迟到的面试,自己也怀疑过自己,也陷入了焦虑,也被所谓的公司折腾过。这些都为我以后的面试奠定了不错的经验(裸辞要当心呀)

面经

下面我会以相关问答的形式简要的总结一下相关的面试题
1,http种的request line包含什么?

  (Request Line)请求行由请求方法(method),请求网址Request-URI和协议(Protocol)构成
    (Request Head) 请求头
  			Accept-Charset:指出浏览器可以接受的字符编码。英文浏览器的默认值是ISO-8859-1.
  			Accept-Language:指出浏览器可以接受的语言种类,如en或en-us,指英语
  			Connection:用来告诉服务器是否可以维持固定的HTTP连接。HTTP/1.1使用Keep-Alive为默认值,这样,当浏览器需要多个文件时(比如一个HTML文件和相关的图形文件),不需要每次都建立连接
  			Content-Type:用来表名request的内容类型。可以用HttpServletRequest的getContentType()方法取得
  			Cookie:浏览器用这个属性向服务器发送Cookie。Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
  			User-Agent:是客户浏览器名称。

2,简要的描述一下,如果我在浏览器输入www.mogujie.com,DNS的工作流程是什么?

https://www.jianshu.com/p/03015813f61a

3,在spring事务中,加入一个没有事务的方法调用了有事务的方法然后有事务的方法又调用了其他没有事务的方法,那么事务还生效嘛?

同一个类中a()方法没有@Transactional注解,在其内部调用有@Transactional注解的方法,有@Transactional 注解的方法b()的事务被忽略,不会发生回滚。
声明式事务基于Spring AOP实现,将具体业务逻辑处理解耦,在Spring的Aop代理下,只有目标方法由外部调用,目标方法才由 Spring 生成的代理对象来管理,这会造成自调用问题

4,linux系统中的load率表示什么,如果一个线上系统的load率过高,应该是什么原因导致
5,redis是不是一定能够保证数据去重操作
6,redis和zk分布式锁的区别?

redis分布式锁的原理:setnx(set not exist 如何key值为空,则正常设置,返回1,否则不会进行设置返回0),释放锁是删除key
1,之前存在一个错误的加锁操作
1,首先通过setnx加锁,然后再通过expire设置过期时间 ,这两条语句不是原子性的,不具有原子性,
2,set(key,requestId,nx,px,expireTime)
第一个参数表示的是锁的名字,这个是有具体的业务逻辑控制,保证唯一性
第二个参数是请求的requestId,这样做的目的主要是为了保证加解锁的唯一性。这样我们就可以知道该锁是哪个客户端加的.
第三个参数表示NX,表示当key不存在时我们才进行set操作
第四个参数表示时间戳
第五个参数具体的过期时间
3,redis的解锁操作
使用lua的原语主要是为了保证原子性. Redis 的 eval 可以保证原子性
zookeeper分布式锁的原理:
基于临时顺序节点:(创建临时有序节点)
1.客户端调用create()方法创建名为“locknode/guid-lock-”的节点,需要注意的是,这里节点的创建类型需要设置为EPHEMERAL_SEQUENTIAL。
2.客户端调用getChildren(“locknode”)方法来获取所有已经创建的子节点。
3.客户端获取到所有子节点path之后,如果发现自己在步骤1中创建的节点是所有节点中序号最小的,那么就认为这个客户端获得了锁。
4.如果创建的节点不是所有节点中序号最小的,那么则监视比自己创建节点的序列号小的最大的节点,进入等待。直到下次监视的子节点变更的时候,再进行子节点的获取,判断是否获取锁。
释放锁的过程相对比较简单,就是删除自己创建的那个子节点即可。
两个分布式锁的共同的区别:
1,如何解决死锁的现象:
Zookeeper使用会话有效期方式解决死锁现象。
Redis 是对key设置有效期解决死锁现象
2,性能:因为redis是NOSQL数据库,性能上是比zookeeper上好的
3,可靠性:因为redis的有效期不是很好的控制,可能会产生有效期的延迟,zookeeper就不一样,因为Zookeeper临时节点先天性可控的有效期,所以相对来说Zookeeper比Redis更好

7,es的文档模型,es的内存机制
8,es的聚合函数的使用
9,es索引原理(DocValues,Fielddata)这个我当时是真不懂
10,es涉及阶段的优化策略

1,采用基于日期的创建索引的策略
2,使用别名进行索引管理
3,合理的设置分词器
es的写入优化
	写入前副本设置0
	写入前关闭refresh_interval设置为-1,禁用刷新机制;
	写入过程中:采取bulk批量写入;
	写入后恢复副本数和刷新间隔;

11,dubbo对组件的扩展
12,发现线上的cpu的使用率是100,或者load很高,如何进行排查

https://mp.weixin.qq.com/s/MpFrTvKg8Gde5FrhmcfePQ

13,mybatis中使用到的设计模式?

1,构造器模式:
2,工厂模式:SqlSessionFactory,ObjectFactory,MapperProxyFactory
3,代理模式,Mybatis实现的核心,比如MapperProxy、ConnectionLogger,用的jdk的动态代理;
4,适配器模式,例如Log的Mybatis接口和它对jdbc、log4j等各种日志框架的适配实现;

14,kafka的其他消息队列的优势?(在项目技术选型的时候为什么选择kafka)这个需要好好理解相关MQ之间的区别

1,kafka的单机吞吐量比较高,单机吞吐量可以达到10万级
2,kafka的数据处理的时效性是毫秒级的
3,kafka的消息可靠性可以通过参数的优化做到0丢失,rocketMQ也是可以,rabbitMQ和activeMQ都会丢失数据
4,kafka的可用性分布式架构,可用性很高
5,kafka主要适用于大数据实时计算和日志收集
kafka和rocketMQ的区别?
kafka在消息存储过程中会根据topic和partition的数量创建物理文件,也就是说我们创建一个topic并指定了3个partition,那么就会有3个物理文件目录,也就说说partition的数量和对应的物理文件是一一对应的。

15,kafka判断一个节点是否还活着的依据是什么?

1,节点必须可以维护和 ZooKeeper 的连接,Zookeeper 通过心跳机制检查每个节点的连接
2,如果节点是个 follower,他必须能及时的同步 leader 的写操作,延时不能太久

16,synchronized和reentrantlock的区别

ReentrantLock是系统层面的加锁
Synchronized是虚拟机层面的加锁

17,redis分布式锁的缺点

redis分布式锁需要不断的尝试获取锁,比较消耗性能
zookeeper分布式锁获取不到之后,只需要监听节点的删除事件,不需要不断的获取锁,性能开销小
redis获取锁的客户端挂了的话,那么只能等待超时后释放锁(这点应该可以通过ttl方法进行检测来删除锁)。而zk是基于临时顺序节点进行的分布式锁,客户端挂的话,临时节点会自动删除,锁就会释放

18,redis的数据类型:string,list,set,zset,hash hypeloglog(这个阿里二面的时候问过)

19,redis为什么能够实现高可用,redis的内存模型(阿里巴巴二面的时候都是问过的)
20,redis单线程和单进程实现高性能的原因?(阿里)

1,纯内存,redis将所有的数据放在内存,内存的响应时间为100纳秒,这是Redis达到每秒万级别访问的重要基础;
2,非阻塞的io,redis使用epoll作为io多路复用技术的实现,在加上Redis自身的事件处理模型将epoll中的链接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间;
3,单线程避免了线程切换和竞态产生的消耗
redis的单线程指的是网络请求模块使用了一个线程。即一个线程处理所有网络请求,其他模块仍用了多个线程。

21,为什么redis采用单线程的模式?

因为redis是基于内存的操作,cpu不是redis的瓶颈,redis的瓶颈最有可能 的是机器内存的大小或者网络带宽,既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了

22,io模型

1,阻塞io模型
 当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态。
2,非阻塞io模型
    当用户线程发起一个read操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。
3,io复用,io多路复用
4,信号驱动
5,异步io

23,常用的io多路复用的模型是什么?(这个理解的很费脑子)

目前常用的io复用模型是select,poll,epoll
他们之前的区别是什么
select,poll,epoll都是io多路复用的机制,io多路复用就是一种机制,他能够监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作,但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的
消息传递的方式
select:内核需要将消息传递到用户空间,需要内核的拷贝动作
epoll:通过内核和用户空间共享一块内存来实现,性能高

select 是基于轮询机制,epoll基于操作系统支持的io通知机制
select单个进程可监视的fd数量收到限制

24,mysql中有一个张表,性别字段需要加索引嘛?

不合适

25,如何大批量的插入1000万条数据到mysql表中(涂鸦智能)

1,修改mysql的引擎MyIsam,因为MyISAM引起的插入速率是高于Innodb
2,使用批量的插入语句
3,修改mysql的配置参数:max_allowed_packet

26,项目和对应的接口中是否使用相应的限流技术? (这个因为我的项目中没有使用,当时确实回答的不好)

1,计数器算法:采用计数器算法进行限流有点粗暴,一般我们会限制一秒钟的能够通过的请求数,比如限流qps为100,算法的实现思路就是从第一个请求进来开始计时,在接下去的1s内,每来一个请求,就把计数加1,如果累加的数字达到了100,那么后续的请求就会被全部拒绝。等到1s结束后,把计数恢复成0,重新开始计数。
2,漏桶算法:漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。不能解决对应的某种情况下的突发情况
3,令牌桶算法:令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
guava的RateLimiter,
RateLimiter的采用静态工厂的方式代替构造函数的方式
RateLimiter的原理就是每次调用,RateLimiter的原理就是每次调用acquire时用当前时间和nextFreeTicketMicros进行比较,根据二者的间隔和添加单位令牌的时间间隔stableIntervalMicros来刷新存储令牌数storedPermits。然后acquire会进行休眠,直到nextFreeTicketMicros。
RateLimiter只能用于单机的限流,如果想要集群限流,则需要引入redis或者阿里开源的sentinel中间件,请大家继续关注。

27,redis中get命令的时间复杂度是多少

时间复杂度是O(1)

28,redis的缓存雪崩,和缓存穿透

缓存雪崩:	缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决:1,尽量保证整个redis集群的高可用,选择合适的内存淘汰策略
    2,限流服务降级
    3,利用redis持久化机制保存的数据尽快回复缓存
缓存穿透:   一般是黑客故意去请求缓存中不存在的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决:1,布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉  
           2,如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

29,cas和aqs的区别(粉象)

AQS:AbstractQueuedSynchronized:抽象的队列式同步器 :AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于
AQS就是一个并法包的基础组件,用来实现锁,各种同步组件,它包含了(state变量,加锁线程,等待队列)等并发中的核心组件

30,Arraylist默认的初始数组长度是多少,扩容机制,扩容是针对原来扩了多少?

ArrayList源码
List<String> list = new ArrayList();
默认的初始化容量是10
1,在new ArrayList()的方法中,首先是默认对应的elementDate缺省为 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}
      在new ArrayList(int capacity),默认是赋值对应的elementData对象
2,在add(E e)方法中,首先是检测当前的elementData是不是为缺省的数组,如果是,默认返回10(这个时候我们会看到10是Arraylist的默认容量),否则是返回
      当前elementData实际的容量+1  
3,如果当前需要的容量(这个时候需要算上需要add的一个容量)大于当前elementData的容量,这个时候进行扩容
4,扩容的长度是原始容量的1.5倍  int newCapacity = oldCapacity + (oldCapacity >> 1);
5,
1,ArrayList可以存放null
2,arrayList本质上就是一个elementData数组。
3,arrayList区别于数组的地方在于能够自动扩展大小,其中关键的方法就是gorw()方法。
6, int currentIndex = 12;
int newCurrentIndex = currentIndex << 1;  左移动,是2倍的意思

31,假设一个事务中,存在以下四个sql查询数据,select,update,insert,delete
在这里插入图片描述
如何继续进行优化,保持事务更好的执行(年糕)

select方法不涉及锁,所以可以把select()方法提取到事务外进行执行,update()方法会引发表锁或者行数,导致其他的获取引发阻塞,所以可以放在delete()的下面,

31,kafka和redis是如何保证他的高可用的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值