京东2021年面经汇总
仅作为笔记,码字不易,转载请标明出处。
文章目录
前言
仅作为笔记
2.讲一下什么是线程池 答:4个工程,7个参数 3.spring中的ioc你怎么理解 答:工厂模式。ioc初始化三大步骤 4.aop呢 答:动态代理,jdk方式和cglib方式。 6.知道netty吗 讲一下一个设计模式吧 reactor模式 (反应器设计模式) 答:没用过,看需不需要补充。 7.说了下单例模式和迭代器模式
8.什么是原子性(atomicity)
9.有一条mysql查询很慢,你有什么优化手段,请讲一下
答:开启慢日志,explain分析,看type和extra两个参数
应该从哪些方面来保护网站
答:
1.域名解析的安全策略
一般性企业或者个人都会忽略域名解析的安全性,随便将域名托管到一些免费域名解析平台上进行解析,但是经过测试大部分域名解析存在问题,域名解析生效时间长,解析出现错误,甚至被别人非法劫持。
2.网站加速防护策略
有网站被攻击的现象的可以使用云加速,如加速乐、百度云加速、360DNS等,但是目前免费的加速防护基本上被人破解了,而且加速后网站部分地区打不开,所以如果有需要的企业或者网站请选择付费型加速产品,如果没有网站被攻击现象产生的不要随意选择加速类产品,选择后反而产生不利影响。
3.服务器安全防护策略
服务器安全性相当重要,很多企业或者个人购买了独立服务器、云主机等之后,配置一下就开始挂网站,但是发现网站打开很慢,服务器流量很大,这样的服务器一定要注意,你的服务器可能正在被别人攻击。这时候你需要在服务器上安装安全狗、360网站卫士和云锁等相关软件,这样可以防御一定的攻击。如果你对服务器有专业的研究,你也可以制定一套自己的服务器安全策略。
4.网站安全防护策略
服务器安全防护可以保护整个服务器的安全,但是针对每个网站,安全策略肯定不一样,所以这时候如果还有攻击的话,请针对网站再进行如iis防护的网站安全防护。这时候可以安装一些网站安全软件或者通过防火墙等进行安全防护。特别是dedecms一定要进行安全防护。
5.网站代码安全防护
在进行网站代码的编写的时候,一定要注意代码安全,如php或asp一定要查找漏洞,只有弥补好漏洞才能减少攻击。特别是对一些网上流行的网站系统,在编写或者开发的时候,一定要注意修复网站系统存在漏洞。
6.网站后台安全防护
一些新站长在进行网站系统安装的时候,都是默认后台或者默认密码,如dedecms,安装的时候默认后台:域名/dede/和账号密码都是默认admin,这样方便了自己也方便了别人,造成网站后台被盗进行挂马。所以一定要注意网站后台的安全防护。
传输加密如何保证?
答:http://www.360doc.com/content/19/1126/07/99071_875506862.shtml
客户端的代码我都可以看到,那我可以改数据啊,我请求你的秘钥把它传到后端,你怎么解决,数据篡改应该怎么解决
答:
举个例子,你的系统上有个发短信功能,怎么防止短信轰炸
答:redis过期键
我从中拦截了数据包,我用你的包来登录怎么防
答:禁止跨域
类加载的时机
答:
有且仅有的五个需要初始化情况:
1)遇到new、getstatic、putstatic、invokestatic这四条指令的时候(被final修饰、已在编译期把结果放入常量池的静态字段除外),如果类没有初始化就需要先触发初始化,生成这四个指令的情况是:使用new关键字、读取或设置一个类的静态字段的时候、调用类的静态方法的时候。
2)使用反射的时候,如果没有进行初始化那就要触发初始化。
3)当初始化一个类时,他的父类还没初始化的话先初始化他的父类。
4)当虚拟机启动时,先初始化主类。
5)使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。
类的加载过程(具体干什么,过程说了,具体干什么忘了准备和解析)
答:加载、链接(准备、验证、解析)、初始化
我用一个boolean的变量,准备阶段是把它赋值成true了吗
答:不会,这时候只是零值。引用类型为null
这个变量从准备阶段由false变为true会造成什么问题
答:不知道、待解决。
介绍一下JMM
答:…
volatile的实现原理
答:1.介绍
2.内存结构。。。。主内存,工作内存
3.内存屏障(loadload、loadstore、storestore、storeload)
怎么保证可见性的
答:加内存屏障
哪些可以保证原子性,CAS做乐观锁吧
答:synchronized、reentrantlock、cas、final不变性原理。
CountDownLatch有什么作用?在什么场景用过,减是用什么方法?
答:栅栏,可以使一批线程在满足某种情况下再被触发或唤醒,也就是可以搭配condition条件。
信号量用来做什么
答:也是同步控制方法种的一种。同时允许多个线程对临界区资源的访问控制。
我一个请求进来,通过隐式方式在线程内如何隐式的传递uuid
答:可以使用threadlocal。
ThreadLocal用过吗
答:用过1.7 1.8介绍一下 1.7已threadmap为主,是一个固定的,每增加一个线程就是会再threadmap中增加一个节点。节点以线程为key,value里面存放的是变量。
抽象类和接口的区别
spi了解吗
答:
SPI(Service Provider Interface)
服务提供者接口的意思
简单理解:SPI机制为一种服务扩展机制,首先在配置文件中定义好接口的实现类,然后根据这个接口从配置文件中加载该接口的所有实现类,以供使用。
模板模式怎么用
自增主键和随机主键的区别
答:
也就是一个用自动增长的id作为主键,一个用随机产生的字符串作为主键,在数据量大的时候,自增主键的插入效率大于随机主键。
存储结构 B+数
答:…
自增主键和随机主键的索引有什么区别
答:如果主键是按照顺序递增地,则新插入的数据只需追加到末尾或生成新的叶子节点即可,不会对前面的节点造成修改。而假如主键是随机并非递增的,则新插入的主键有可能需要插入到之前的叶子节点中,这就可能导致叶子节点的分裂以及B+树的重新平衡,这造成的代价是比较大的。这也是为什么主键索引建议顺序递增,而不建议采用类似md5作为主键或索引。这他妈不是很天然的问题吗???问这个脑子有毛病吧。
范围查询会用到索引吗
答:看情况。。。脑瘫问题
什么是索引覆盖
答:覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。
建了一个表,索引应该怎么定义它的数据结构,比如varchar
IO次数和什么有关系,IO一次取决于什么,磁盘页的大小
答:b+树的结构,取决于B+树的深度,磁盘也4
kb,innodb默认16kb。
对深度分页知道吗
答:看这里https://www.cnblogs.com/651434092qq/p/14253516.html
三种策略:1.业务层面解决,让你看不到后面的数据。2.在查询下一页时把上一页的行id作为参数传递给客户端程序。3.延迟字段关联
Redis和MQ接触过吗
答:接触过
Redis常用数据结构
答:八大数据结构,五大数据类型
五种数据类型
String类型
List(集合)
Set(集合)
Hash(哈希)
Zset(有序集合)
八种数据结构:
1.简单动态字符串
2.压缩列表
3.双端链表
4.字典
5.整数集合
6.跳跃表
7.embstr编码的简单动态字符串
8.可以存储long类型的整数
ZSET用来作什么,为什么用zset不用set
答:https://zhuanlan.zhihu.com/p/147912757 看看这个
zset有序,靠一个score来排序。set是无序的,他们都是不可重复的。
zset的性能和什么有关系,时间复杂度是多少,会随着我的数据越大耗时越多吗
答:看看这个https://blog.csdn.net/qq_40351478/article/details/88665084
zset的编码实现有两种方式,压缩链表和跳跃表,当服务器属性server.zset_max_ziplist_entries 的值大于 0
元素的member长度小于服务器属性server.zset_max_ziplist_value的值(默认64)
时就使用的是压缩列表,否则就是跳跃表。
Redis分布式锁,用哪个函数
答:(1)获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。(2)获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
(3)释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。
作者:亲亲猪儿虫
链接:https://www.nowcoder.com/discuss/722899?source_id=discuss_experience_nctrack&channel=-1
来源:牛客网
2、Redis缓存穿透、缓存雪崩,解决方案
3、类和接口的区别
4、集合有哪些
答:
7、spring中的设计模式
答:
1.简单工厂
又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。
2.工厂方法(Factory Method)
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。Spring中的FactoryBean就是典型的工厂方法模式。
3.单例(Singleton)
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
Spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例,这是因为Spring管理的是是任意的Java对象。
4.适配器(Adapter)
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
Spring中在对于AOP的处理中有Adapter模式的例子
5.包装器(Decorator)
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。Spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。
6.代理(Proxy)
为其他对象提供一种代理以控制对这个对象的访问。从结构上来看和Decorator模式类似,但Proxy是控制,更像是一种对功能的限制,而Decorator是增加职责。
Spring的Proxy模式在aop中有体现,比如JdkDynamicAopProxy和Cglib2AopProxy。
7.观察者(Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。Spring中Observer模式常用的地方是listener的实现。如ApplicationListener。
8.策略(Strategy)
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。Spring中在实例化对象的时候用到Strategy模式
9.模板方法(Template Method)
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。Template Method模式一般是需要继承的。这里想要探讨另一种对Template Method的理解。Spring中的JdbcTemplate,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用到JdbcTemplate已有的稳定的、公用的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出来作为一个参数传入JdbcTemplate的方法中。但是变化的东西是一段代码,而且这段代码会用到JdbcTemplate中的变量。怎么办?那我们就用回调对象吧。
8、锁升级过程
答:锁升级的方向是:无锁——>偏向锁——>轻量级锁——>重量级锁,并且膨胀方向不可逆。
14、手写算法题:共享屏幕
一个数组,有一个数是一个,其余数是两个,升序排列,找出这个数。
equals和==
答: 如果不重写equals,那么就是一样的
== 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。
equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。
算法题:两个大数相加,如何做?
3.java动态代理有几种方式,cglib底层原理(不懂)
答:两种,jdk和cglib方式。
CGLib 底层原理:
通过查看 Enhancer 类源码,最终也是生成动态代理类的字节码,动态代理类继承要被代理的类,然后实现其方法。
和 JDK Proxy 的实现代码比较类似,都是通过实现代理器的接口,再调用某一个方法完成动态代理的,唯一不同的是,CGLib 在初始化被代理类时,是通过 Enhancer 对象把代理对象设置为被代理类的子类来实现动态代理的。
实现步骤:
1.创建被代理的类及方法;
2.创建一个实现接口 MethodInterceptor 的代理类,重写 intercept 方法;
3.创建获取被代理类的方法 getInstance(Object target);
4.获取代理类,通过代理调用方法。
具体的看这里:https://blog.csdn.net/weixin_32716541/article/details/113051368
7.消息队列如何保证消息可靠性
答:
消息流程可以分为三大部分:
1.生产阶段:生产方发送失败,可以使用同步发送(发送丢失)+自动重试机制(失败或超时)+多个Master节点(broker宕机)。
2.存储阶段(持久化阶段):同步刷盘+集群部署并等待slave刷盘完成。
3.消费阶段:等待业务逻辑完成后再进行手动ack+消费失败自动重试(默认15次,超过就会称为死信消息放进死信队列)。
8.消息队列实现分布式事务如果服务发送方挂了怎么处理
答:增加事务反查机制,这时候broker没收到任何提交或者回滚的消息,那么将会回查本地事务的状态。然后根据结果判断是回滚还是提交。在订单系统的例子中,反查本地事务的逻辑只要根据消息中的订单ID,在订单库中查询这个订单是否存在即可,如果订单存在则返回成功,否则返回失败。消息队列会自动根据事务反查的结果提交或者回滚事务消息。真挂了就从其他节点得到数据。
9.消息队列如何保证消息顺序性(我只说了用标志位,他问还有吗,我说想不到了)
答:rocketMQ采取的方法是将消息都放在一个topic的一个队列当中,提供了api MessageQueueSelector可以选择队列。
12.cms回收步骤
答:
1.初始标记
2.并发标记
3.重新标记
4.并发清除
CMS:侧重于响应优先的收集器,主要用于互联网站和B/S的服务端上。基于标记清除算法,四个步骤。1初试标记 2.并发标记 3.重新标记 4.并发清除。缺点是对CPU资源敏感,无法处理浮动垃圾、以及标记清理算法导致的内存碎片可能会导致Full GC提前的问题
13.cms重新标记的时候三色算法了解吗(不了解)
答:
为什么CMS的GC线程可以和用户线程一起工作?是因为有三色标记算法的存在,那什么是三色标记算法呢?
标记流程如下:
1.刚开始,所有的对象都是白色,没有被访问。
2.将GC Roots直接关联的对象置为灰色。
3.遍历灰色对象的所有引用,遍历后灰色对象本身置为黑色,引用置为灰色。
4.重复步骤3,直到没有灰色对象为止。
5.结束时,黑色对象存活,白色对象回收。
详细知识看这个,写得相当的好https://blog.csdn.net/qq_45798556/article/details/117667870
14.线程池如果满了会怎么样
答:拒绝策略
1.Java中的switch中的case后的量可否使用String,为什么?
答:从 Java 7 开始,我们可以在 switch case 中使用字符串,但这仅仅是一个语法
糖。内部实现在 switch 中使用字符串的 hash code。在java8的时候才是真的支持了。
3. 抽象类和接口的区别(说出所有不同的点);抽象类中能否用lambda函数?
答:不可以
5. HashMap的底层原理?初始大小?如何resize/扩容?红黑树插入元素的过程?
答:1.7 1.8 16 ,
resize:
最后我们再来总结一下之前提到的3个问题,
什么时候进行resize操作?
有两种情况会进行resize:1、初始化table;2、在size超过threshold之后进行扩容
扩容后的新数组容量为多大比较合适?
扩容后的数组应该为原数组的两倍,并且这里的数组大小必须是2的幂
节点在转移的过程中是一个个节点复制还是一串一串的转移?
从源码中我们可以看出,扩容时是先找到拆分后处于同一个桶的节点,将这些节点连接好,然后把头节点存入桶中即可 .新位置实际上是老位置加上oldcap。详细的看这里:https://blog.csdn.net/weixin_41565013/article/details/93190786
红黑树插入元素:
红黑树的特性:
红黑树中的每个结点包含五个域:color、key、left、right和parent。如果某结点没有一个子结点或父结点,则该结点相应的指针parent域包含值为NIL(NIL并不是空指针,后面会讲到)。把NIL视为指向红黑树的外结点(叶子)的指针,而把带关键字的结点视为红黑树的内结点。红黑树结点结构如下所示:
1.每个节点或为红色或为黑色。
2.根节点是黑色。
3.每个叶子节点(NIL)是黑色。
4.如果一个节点是候色,那么它的两个儿子都是黑色。
5.对每个节点,从该节点到其孙子结点的所有路径上包含相同数目的黑色节点。
基于二叉树,使用左右旋的方式维护红黑树的那几个定义。
6.线程的终止方式?interrupt/stop?
答:
1.使用退出标志位终止线程(实际上就是在程序语言的逻辑层面上让线程达到某个条件停止)
2.中断(interrupt)
3.使用stop方法终止线程
8.spring注解?@Configuration @Service
答:
@Configuration用于定义配置类,定义的配置类可以替换xml文件,一般和@Bean注解联合使用。
@Configuration注解主要标注在某个类上,相当于xml配置文件中的
@Bean注解主要标注在某个方法上,相当于xml配置文件中的
@Service(“serviceName”)注解相当于applicationContext.xml配置文件中配置的,表示给当前类命名一个别名,方便注入到其他需要用到的类中。@Service注解也可以不指定serviceName,如果不指定相当于,com.study.service.ServiceName就是这个类的全限定名,不加的话,默认别名就是当前类名,但是首字母小写。
10.平时如何使用日志?用的哪种日志?
答:一般不会使用到java的日志,可能会用的就是mysql的慢日志了。
11.Redis中有哪些数据结构?其中zset是有序集合,如何保证有序的?
答:
redis有8大数据结构:
1.普通编码的SDS
2.embstr编码的SDS
3.双端链表
4.压缩列表
5.可以存储Long的整数
6.字典
7.跳跃表
8.整型集合
五大数据类型:
1.字符串
2.set
3.zset
4.hash
5.list
zset介绍
有序集合对象的编码可以是ziplist或者skiplist。同时满足以下条件时使用ziplist编码:
元素数量小于128个
所有member的长度都小于64字节
以上两个条件的上限值可通过zset-max-ziplist-entries和zset-max-ziplist-value来修改。
ziplist编码的有序集合使用紧挨在一起的压缩列表节点来保存,第一个节点保存member,第二个保存score。ziplist内的集合元素按score从小到大排序,score较小的排在表头位置。
skiplist编码的有序集合底层是一个命名为zset的结构体,而一个zset结构同时包含一个字典和一个跳跃表。跳跃表按score从小到大保存所有集合元素。而字典则保存着从member到score的映射,这样就可以用O(1)的复杂度来查找member对应的score值。虽然同时使用两种结构,但它们会通过指针来共享相同元素的member和score,因此不会浪费额外的内存。
12.MySQL的底层B+树的实现原理?索引的生成策略?最后一层节点和其余节点的保存值是整条记录还是索引还是部分记录?
2.redis怎么使用的
答:回答项目里怎么使用的,本项目里使用了redis的hash功能(用户名为key,权限列表为value)。以及redis 的string用来缓存主页面热点数据。
3.redis怎么保证和数据库的数据一致
答:延时双删+过期时间
延迟双删
在写库前后都进行redis.del(key)操作,并且第二次删除通过延迟的方式进行。
1)先删除缓存;
2)再写数据库;
3)休眠500毫秒(根据具体的业务时间来定);
4)再次删除缓存。
那么,这个500毫秒怎么确定的,具体该休眠多久呢?
需要评估自己的项目的读数据业务逻辑的耗时。这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。
而设置缓存过期是为了防止双删失败的情况。
4.为什么要双删?第一遍清的意义是什么?
答:
详细的讲一下双删的过程,总的来说双删是为了保持缓存和数据库的一致性。第一遍删除的意义是:线程读取某个数据的时候肯定是先读取redis中的数据,如果此时又有写的线程又有读的线程,如果读的线程比写的线程速度快了写,那么读线程就会读到和数据库不一样的数据。
5.还有什么方法可以保证缓存和数据库的一致性
答:有,将双删中保证缓存删除成功的方式换成使用消息队列来重试完成,而不是使用
6.RabbitMQ和kafka的区别
答:未解决
8.如何保证数据不重复消费?
答:
保证幂等性(重复消费)
要保证消息的幂等性,这个要结合业务的类型来进行处理。下面提供几个思路供参考:
(1)、可在内存中维护一个set,只要从消息队列里面获取到一个消息,先查询这个消息在不在set里面,如果在表示已消费过,直接丢弃;如果不在,则在消费后将其加入set当中。
(2)、如何要写数据库,可以拿唯一键先去数据库查询一下,如果不存在在写,如果存在直接更新或者丢弃消息。
(3)、如果是写redis那没有问题,每次都是set,天然的幂等性。
(4)、让生产者发送消息时,每条消息加一个全局的唯一id,然后消费时,将该id保存到redis里面。消费时先去redis里面查一下有么有,没有再消费。
(5)、数据库操作可以设置唯一键,防止重复数据的插入,这样插入只会报错而不会插入重复数据。
10.倒排索引
答:es的内容,未解决。
15.hashmap的put的过程
答:
jdk1.7如下:
1.判断当前数组是否需要初始化。
2.如果 key 为空,则 put 一个空值进去。如果不为空根据 key 计算出 hashcode。
3.根据计算出的 hashcode 定位出所在桶。
4.如果桶是一个链表则需要遍历判断里面的 hashcode、key 是否和传入 key 相等,如果相等则进行覆盖,并返回原来的值,如果没发现一样的值那么就将值插入这个链表的后面(头插法,多线程环境下可能导致循环链表)。
5.如果桶是空的,说明当前位置没有数据存入;新增一个 Entry 对象写入当前位置。
6.新增Entry对象时,调用 addEntry 写入 Entry 时需要判断是否需要扩容。如果需要就进行两倍扩充,并将当前的 key 重新 hash 并定位。
7.而在 createEntry 中会将当前位置的桶传入到新建的桶中,如果当前桶有值就会在位置形成链表。
详细图解:
jdk1.8大致内容和上面一样,唯一不同的是要考虑红黑树的情况。
16.头插法和尾插法
答:
头插法:这是jdk1.7的插入方式,头插法在多线程环境下可能导致形成循环链表。
形成循环链表的过程:
头插法:这是jdk1.8的特色。在扩容时,头插法会改变链表中元素原本的顺序,以至于在并发场景下导致链表成环的问题,而尾插法,在扩容时会保持链表元素原本的顺序,就不会出现链表成环的问题。这也是1.8在1.7上的优化。
17.如何判断链表是否有环
18.SpringBean的生命周期
答:简述其过程,爱咋咋地:
实例化->设置依赖->初始化->spring容器进行管理->销毁前处理->正式消亡。
19.常用注解
答:
20.@ResponseMapping和@ResponseBody的区别
答:
国际惯例先介绍什么是@RequestMapping,@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径;用于方法上,表示在类的父路径下追加方法上注解中的地址将会访问到该方法,此处需注意@RequestMapping用在类上可以没用,但是用在方法上必须有。
@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
5.怎么实现持久化登录的
答:
1.cookie
使用的方法
登录验证后,创建登录凭证(比如:用户id+登录时间+过期时间),将登录凭证进行加密(为了避免暴露信息),加密后写到浏览器的cookie,以后,每次请求都发送cookie,服务器根据对应的解密算法对其进行验证(或者将加密过的cookie内容存储到数据库,请求服务器的时候,服务器在数据库进行查找)。
存在的问题
每次访问都提交cookie,增加请求量
其他访问可能需要cookie(比如说购物车的信息存放在cookie),浏览器对每个域存储的cookie的大小有限制,那么需要控制加密后的凭证。
2.session
存在的问题
高并发情况下,会占用服务器大量内存
分布式(一个业务分成几个子业务,部署在多个服务器)或者集群(一个业务部署在多个服务器)的时候,session不能共享。
解决方案
高并发的时候可以将session存储到redis,如果用户长时间没有访问,将session存储到redis,就减少了服务器的压力。
分布式或者集群的时候,先通过redis来判断用户状态也可以实现session共享.
3.token
使用方法
cookie 和session依赖于浏览器,如果客户端不是浏览器,那么需要手动添加token(和cookie类似,也是登录凭证),将token添加到http header或者做为参数添加到url。
存在的问题
每次访问的时候手动添加token
和cookie 的方式一样增加了请求量
cookie和session的区别
答:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上.
简单的说,当你登录一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上面,客户端每次请求服务器的时候会发送 当前会话的session_id,服务器根据当前session_id判断相应的用户数据标志,以确定用户是否登录,或具有某种权限。由于数据是存储在服务器 上面,所以你不能伪造,但是如果你能够获取某个登录用户的session_id,用特殊的浏览器伪造该用户的请求也是能够成功的。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
3、设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
4、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。
5、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)
6、 两者最大的区别在于生存周期,一个是IE启动到IE关闭.(浏览器页面一关 ,session就消失了),一个是预先设置的生存周期,或永久的保存于本地的文件。(cookie)
7.cookie只能存取ascii码,但是session可以保存任意类型的数据。
6.为什么要生成随机的token
答:
7.不使用token会怎么样
答:使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。详细分析token和session cookie,token在不是浏览器的时候也可以用,但是cookie不行。并且token相对cookie来说更安全,毕竟token由三部分组成,token头、数据,hash生成的防伪。
8.为什么cooike安全性不好
答:因为cookie是保存在浏览器本地的,很容易被查看到。
10.如果有大量不存在的请求过来如何处理
答:1.布隆过滤器。
2.缓存空值。
11.缓存预加载
答:
1.什么是预加载?
提前加载图片,当用户需要查看时可直接从本地缓存中渲染
2.为什么要使用预加载?
图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度。这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速、无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验。
也就是将资源提前的加载然后缓存起来,使用的时候会很快。
14.热点数据的更新时机
答:
15.需要实时性要求很高的,但不是热点信息怎么保证时效性
18.有没有关注服务器的性能方面的
19.除了吞吐量还关注过什么参数
20.Spring如何处理一个请求
22.如果一个对象有两个成员变量 但是值重写了一个hashcode,放到hashmap中去会有什么后果
哪些redis操作是不推荐使用的
3.MySQL索引的调优
4.如果一个系统运行了两周之后,突然变慢了,怎么排查(说实际能行的)
5.你认为你的优势和缺点(两个)
2.redis缓存的bigkey问题如何解决
3.springboot的依赖注入
5、redis基本数据类型、讲一下SDS,redis高级数据结构
9、linux命令知道哪些
12、单例DLC讲下,动态代理的jdk和CGLib讲一下
14、rocketmq在项目中如何防止重复消费
4、查询慢怎么办?explain中有哪些字段,详细说一下索引那列字段都会在什么场景产生
7、sql注入问题,到JDBC相关的statement对象
9、符号引用和直接引用
10、线程池相关,execute和submit,核心参数、拒绝策略等八股文
1、哪些情况下的对象会被垃圾回收机制处理掉?
1.1哪些对象可以被看做是GCRoots呢?
2)方法区中的类静态属性引用的对象,常量引用的对象;
3)本地方法栈中JNI(Native方法)引用的对象;
1.2对象不可达,一定会被垃圾收集器回收么?
2、讲一下常见编码方式?
3、utf-8编码中的中文占几个字节;int型几个字节?
4、静态代理和动态代理的区别,什么场景使用?
5、Java的异常体系Java中Throwable是所有异常和错误的超类,两个直接子类是Error(错误)和Exception(异 常):
6、谈谈你对解析与分派的认识。
7、修改对象A的equals方法的签名,那么使用HashMap存放这个对象实例的时候,会调用哪个
8、Java中实现多态的机制是什么?
9、如何将一个Java对象序列化到文件里?ObjectOutputStream.writeObject()负责将指定的流写入,ObjectInputStream.readObject()从指 定流读取序列化数据。
10、说说你对Java反射的理解 在运行状态中,对任意一个类,都能知道这个类的所有属性和方法,对任意一个对象,都能 调用它的任意一个方法和属性。这种能动态获取信息及动态调用对象方法的功能称为java语言的反射机制。
反射的作用:开发过程中,经常会遇到某个类的某个成员变量、方法或属性是私有的,或只对系统应用开放,这里就可以利用java的反射机制通过反射来获取所需的私有成员或是方 法。
1)获取类的Class对象实例Classclz=Class.forName(“com.zhenai.api.Apple”);
2)根 据Class对 象 实 例 获 取Constructor对 象Constructor appConstructor = clz.getConstructor();
3)使 用Constructor对 象 的newInstance方 法 获 取 反 射 类 对 象Object appleObj = appConstructor.newInstance();
4)获取方法的Method对象MethodsetPriceMethod=clz.getMethod(“setPrice”,int.class);
5)利用invoke方法调用方法setPriceMethod.invoke(appleObj,14);
6)通过getFields()可以获取Class类的属性,但无法获取私有属性,而getDeclaredFields()可 以获取到包括私有属性在内的所有属性。带有Declared修饰的方法可以反射到私有的方法, 没有Declared修饰的只能用来反射公有的方法,其他如Annotation\Field\Constructor也是如 此。
11、说说你对Java注解的理解 注解是通过@interface关键字来进行定义的,形式和接口差不多,只是前面多了一个@
public@interfaceTestAnnotation{
}
使用时@TestAnnotation来引用,要使注解能正常工作,还需要使用元注解,它是可以注解 到注解上的注解。元标签有@Retention@Documented@Target@Inherited@Repeatable五种
@Retention说明注解的存活时间,取值有RetentionPolicy.SOURCE注解只在源码阶段保留, 在编译器进行编译时被丢弃;RetentionPolicy.CLASS注解只保留到编译进行的时候,并不会 被加载到JVM中。RetentionPolicy.RUNTIME可以留到程序运行的时候,它会被加载进入到JVM中,所以在程序运行时可以获取到它们。
@Documented注解中的元素包含到javadoc中去
@Target限 定 注 解 的 应 用 场 景 ,ElementType.FIELD给 属 性 进 行 注 解 ;ElementType.LOCAL_VARIABLE可以给局部变量进行注解;ElementType.METHOD可以给方法 进行注解;ElementType.PACKAGE可以给一个包进行注解ElementType.TYPE可以给一个类型 进行注解,如类、接口、枚举
@Inherited若一个超类被@Inherited注解过的注解进行注解,它的子类没有被任何注解应用 的话,该子类就可继承超类的注解;
注解的作用:
1)提供信息给编译器:编译器可利用注解来探测错误和警告信息
2)编译阶段:软件工具可以利用注解信息来生成代码、html文档或做其它相应处理;
3)运行阶段:程序运行时可利用注解提取代码
注解是通过反射获取的,可以通过Class对象的isAnnotationPresent()方法判断它是否应用了 某个注解,再通过getAnnotation()方法获取Annotation对象
12、说一下泛型原理,并举例说明 泛型就是将类型变成参数传入,使得可以使用的类型多样化,从而实现解耦。Java泛型是在Java1.5以后出现的,为保持对以前版本的兼容,使用了擦除的方法实现泛型。擦除是指在 一定程度无视类型参数T,直接从T所在的类开始向上T的父类去擦除,如调用泛型方法, 传入类型参数T进入方法内部,若没在声明时做类似publicTmethodName(TextendsFather t){},Java就进行了向上类型的擦除,直接把参数t当做Object类来处理,而不是传进去的T。 即在有泛型的任何类和方法内部,它都无法知道自己的泛型参数,擦除和转型都是在边界上 发生,即传进去的参在进入类或方法时被擦除掉,但传出来的时候又被转成了我们设置的T。 在泛型类或方法内,任何涉及到具体类型(即擦除后的类型的子类)操作都不能进行,如newT(),或者T.play()(play为某子类的方法而不是擦除后的类的方法)
13、Java中String的了解1)String类是final型,固String类不能被继承,它的成员方法也都默认为final方法。String对象一旦创建就固定不变了,对String对象的任何改变都不影响到原对象,相关的任何改变 操作都会生成新的String对象。
2)String类是通过char数组来保存字符串的,String对equals方法进行了重定,比较的是 值相等。
Stringa=“test”;Stringb=“test”;Stringc=newString(“test”);
a、b和字面上的test都是指向JVM字符串常量池中的"test"对象,他们指向同一个对象。而new关键字一定会产生一个对象test,该对象存储在堆中。所以newString(“test”)产生了两 个对象,保存在栈中的c和保存在堆中的test。而在java中根本就不存在两个完全一模一样 的字符串对象,故在堆中的test应该是引用字符串常量池中的test。
例:
Stringstr1=“abc”;//栈 中 开 辟 一 块 空 间 存 放 引 用str1,str1指向池中String常量"abc"
Stringstr2=“def”;//栈 中 开 辟 一 块 空 间 存 放 引 用str2,str2指向池中String常量"def"
Stringstr3=str1+str2;//栈 中 开 辟 一 块 空 间 存 放 引 用str3 //str1+str2通 过StringBuilder的 最 后 一 步toString()方 法 返 回 一 个 新 的String
对象"abcdef"
//会 在 堆 中 开 辟 一 块 空 间 存 放 此 对 象 ,引 用str3指向堆中的(str1+str2)所 返 回 的 新String对象。System.out.println(str3==“abcdef”);//返 回false因 为str3指 向 堆 中 的"abcdef"对 象 , 而"abcdef"是 字 符 池 中 的 对 象 , 所 以 结 果 为false。JVM对Stringstr="abc"对 象 放 在 常 量 池 是 在 编 译 时 做 的 , 而Stringstr3=str1+str2是在运行时才知道的,new
对象也是在运行时才做的。14、String为什么要设计成不可变的?1)字符串常量池需要String不可变。因为String设计成不可变,当创建一个String对象时, 若此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。 如果字符串变量允许必变,会导致各种逻辑错误,如改变一个对象会影响到另一个独立对象。
2)String对象可以缓存hashCode。字符串的不可变性保证了hash码的唯一性,因此可以缓 存String的hashCode,这样不用每次去重新计算哈希码。在进行字符串比较时,可以直接
比较hashCode,提高了比较性能;
3)安全性。String被许多java类用来当作参数,如url地址,文件path路径,反射机制所 需的Strign参数等,若String可变,将会引起各种安全隐患。
11、RDB保存时的现象
3、HashMap的put过程,hash冲突的解决方法,为什么会发生hash冲突
5、慢sql优化的例子,除了建索引还有其他方法嘛?大表join大表有什么优化方法嘛
6、设计表,写个sql,学生表,科目表,成绩表?
查询某个班级学生所有科目的所有成绩
查询每门科目的最高分
查询每门科目的前两高的分数
7、SpringBoot相比于SpringMVC有什么好处
11、分布式锁有哪些?
10、TCC有用过嘛,分布式事务了解嘛
手撕算法题:
- 求连续最大子序列和,及子序列index
- 反转链表
操作系统内存管理了解吗
刚才提到虚拟内存,操作系统如何保证各个进程的地址空间隔离?
算法题:最长不重复子串,讲思路
介绍下Hash原理,出现哈希冲突时怎么在链表或红黑树中找到对应的元素,链表怎么转换为红黑树(不会)
了解JVM可达性分析算法具体的实现机制吗?让你实现GC roots的搜索过程该怎么实现,用什么数据结构
如何保证垃圾回收时的线程安全,防止多个线程同时对一片内存区域进行操作(没太理解问的什么意思)
Java有哪些锁
synchronized怎么实现互斥,线程获取不到锁时怎么进入阻塞状态(不知道啥意思,就答了通过监视器对象的entrylist维护阻塞的线程列表)
类加载器
垃圾收集器,G1为什么高吞吐量
静态变量和实例变量的区别
int和Integer的区别
final关键字
final修饰变量不能改变是指引用不能改变还是值不能改变
深拷贝和浅拷贝
static的用法
start()方法和run()的区别
都了解那些MQ
springboot自动装配原理
springboot中有很多starter,你了解的starter都有哪些,这些starter有什么作用
redis的集群,都说一下
redis数据恢复的方式,AOF和RDB的区别
4、GcRoots是哪些
5、java基础
6、mysql索引
2、springcloud作用
3、为什么用springboot
4、Nacos原理,如何保证nacos和服务实例发生网络分区服务丢失问题(集群就可以了吧)
5、为什么需要同步锁
说说AQS源码
算法:最长不重复子串的长度
6.1最长无重复字串
6.2 找到A2+B2 = C
计组
二进制有原码,为什么还要有反码和补码
用Post方法,服务端Post JSON数据,怎么让Spring把Body变成一个对象
接上面,PostMapping需要指定什么,参数怎么写
JDK动态代理涉及到哪几个类
Spring Boot对于Spring而言里面增加了哪些新的注解?
SpringBoot的starter实现原理是什么?为什么不需要再像原来配置那么多Bean对象出来
知道怎么写一个starter吗?
Spring事务了解不
Spring事务传播行为
List里面几个实现类区别和特点
Map里面实现类的各自区别和特点,数据结构
workQueue阻塞队列主要实现有几种?
ClassLoader用过吗?用在哪些方面(依赖冲突,热加载,热部署,加密保护)
一个SQL题目,一个表有学生学号成绩学科,找所有科目对应的最高成绩和学生学号
HTTP报文结构
Header里面有哪些常用的
和缓存相关的Header是哪些?(Expires,Cache-Control,Last-Modified…)
HTTP响应码(3开头的有哪些)
跨域了解吗
网络攻击行为了解吗?csrf攻击原因是什么
CDN了解吗?
CDN工作机制清楚吗
一道算法:有序数组中数字两两一对,找出只出现一次的数字(写了位运算,面试官说再优化一下—二分)
2,虚拟内存与物理内存(问物理内存200M,可以申请2g的内存吗,我直接答其实分配的是虚拟内存,当需要使用才去建立物理内存,如果物理内存不够,将不运行的页调出,把需要运行的换入)
3,redis的设置过期时间底层原理(不懂,直接说定时器和ttl)
4,函数内部加锁,如果遇到多个语句有return,会导致解锁未完成,怎么解决(我直接goto或者封装处理)
8,缓存雪崩,击穿,穿透
算法题:求字符串数组中位数的字符串
java 泛型
6.token具体怎么实现的身份认证(结合项目说的token实现原理和过程)
7.客户端保存生成token的密钥吗,客户端能解析出token中的用户内容吗(引出了token被劫持等)
8.为什么使用token(特点优点,对比了session)
9.如何解决token劫持
10.https为什么能防止token被劫持(加密原理)
11.https能防止中间人攻击吗
13.A方法@Transactional,B方法没有,B中直接调用A方法那A的@Transactional能生效吗(不会,提示主要和AOP的工作模式有关)
14.介绍Atomic原子库的底层实现机制(CAS,ABA问题怎么解决,版本号)
17.缓存一致性方案(先删缓存的作用是什么)
18.场景:A服务生产,B服务消息队列,中间使用消息队列,收到挤压上升,初步判断是什么原因(生产量增大),怎么快速解决积压(扩容),扩容后消费能力只增加了一点问题在哪里
- Nacos原理,与zk的区别,与nginx的区别,为什么不用nginx呢?
2、在项目中如何避免我们多个人同时添加相同的数据?(数据库,唯一索引)
6、token机制如何实现的?有效期设置了多久?我在一个浏览器登录后,换另外一个浏览器还需要登录吗?
7、系统是前后端分离的吗?(是)。如何解决跨域问题的?
11、数据库中除了添加索引还有哪些优化手段?
12、数据量多大适合分表?
14、算法题说思路:数组中有n个数,分别为0-n(无序,值唯一),且缺失一个,如何高效找出缺失的这个数?时间复杂度是多少?
如:1,0,3。 找出:2。
4.不可变设计的好处
5.集合类空数组的好处
7.mvc框架的好处
8.servlet filfter listener的加载顺序
9.用过的rpc框架
11.递归和深度优先遍历的区别
12.spring的核心思想
项目中的nginx负载均衡(正向代理,反向代理,几种负载方法(自我感觉奇差,因为我忘光了),还有静态文件访问的设置。
Java 中有个 Object 基类,里面有两个方法:hashcode()、equals(),他们是做什么的
雪花算法原理、如何解决时钟回拨、为啥顺序的ID
异步是啥、有啥缺点、和同步对比
lua+Redis为啥保证原子性、集群下lua失效怎么办
JRE和JDK区别
synchronized锁升级
讲讲AQS
多读少写用啥锁
数据结构
数据结构:用两个栈实现一个队列。
终止线程的方式?
thread.stop()在java1.8中是什么情况?
如何将三种终止线程的方式进行结合?使线程结束的更加优雅?
MyBatis
MyBatis二级缓存如何实现的?尽可能深入的讲解一下。
二级缓存和一级缓存的区别是什么?
zset底层如何实现的?用score值保证有序,score值可以重复吗?
如果score值一样,用什么排序?两次取值一样吗?
基本数据类型有哪些
给定一个场景:一个数组中的数字两两重复,现在在里面随机位置中插入一个,你要怎么找出来呢?(脑淤血直接答了暴力解法)后来问了面试官可以用 map 或者异或
count(*)与count(1)区别(这块拉了)
7、class.forName和classloader.loadclass区别(这块拉跨)
5、volatiel能保证线程安全吗
6、拦截器和过滤器的区别
MySQL buffer pool和doublewrite buffer
RocketMQ事务性消息
RocketMQ相对于其他消息队列的优点(Kafaka权威指南那本书真该做笔记的)
JVM Runtime逻辑结构和解释
锁升级过程. (好久没看了, 大概说了一下, 值得一提的是JDK15以后取消了对偏向锁的使用).
简单算法题: 求链表中倒数第k个元素
异步事务具体过程
高并发下的文件事件调度器
依赖注入和循环依赖
自动配置全流程(ImporterSelector, Registry, ConfigurationPostProcessor, loadFactoryName, META-INF/spring.factories)
RedLock算法(这个聊了很久, 其实单看Redis的doc是没用的, 我建议看看DDIA的第二部分, 尤其是分布式系统的麻烦中, 一致和共识那两部分).
Git版本控制
• 父类什么样的方法需要被重写
• 为什么有了字节流还需要字符流
• JDK,JRE,JVM区别
• 帖子的敏感词过滤,前缀树
• 前缀树这种数据结构本身的缺陷
数据库
• InnoDB引擎怎么解决幻读
• 间隙锁,偏向锁
• CMS垃圾回收器为什么快
了解红黑树的特性吗
红黑树的根结点是什么颜色的
输入URL到浏览器显示页面的过程,越细越好(说到SSL之后我就准备结束了,面试官要我继续讲Tomcat的处理流程,我…)