二、MySQL数据库为什么要用innodb:1、支持事务;2、实现了MySQL的mvcc;3、支持行级锁;
三、启动springboot的那个注解:
默认扫描包路径:main方法所在的类下面的所有包和子包
四、@RequestParam 怎么回事,这个居然都忘记了,不过也不能说忘记,因为确实不怎么用,因为这个一般都是get请求的,而我一般都是post,request请求的:SpringCloud
@PathVariable:这个真的没有用过,什么“映射 URL 绑定的占位符”,不懂;
五、redis的优点:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1)基于内存,操作速度快; 2)丰富的数据类型,有STRING,LIST,HASH,SET,SORTEDSET,二那个什么mach的什么什么只支持单一的数据类型STRING; 3)支持事务; 4)原子性操作; 5)支持持久化策略:AOF和RDB 缺点:数据不一致;代码维护成本
六、使用redis应该注意什么,其实就是问 缓存穿透、缓存雪崩、缓存击穿;接着问这三个是怎么回事,以及各自的解决方法;我回答了缓存穿透的解决方法:那个布隆过滤bitmap的厉害之处,对方接着问,如果那个bitmap的hashcode一样(即hash冲突了,怎么解决),我回答了equal方法,对方说不是这样子,然后我就被问死了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
你有什么解决方案来防止缓存雪崩? 1、加锁排队 key: whiltList value:1000w个uid 指定setNx whiltList value nullValue mutex互斥锁解决,Redis的SETNX去set一个mutex key, 当操作返回成功时,再进行load db的操作并回设缓存; 否则,就重试整个get缓存的方法 2、数据预热 缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候, 先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据! 可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key 3、双层缓存策略 C1为原始缓存,C2为拷贝缓存,C1失效时,可以访问C2,C1缓存失效时间设置为短期,C2设置为长期。 4、定时更新缓存策略 失效性要求不高的缓存,容器启动初始化加载,采用定时任务更新或移除缓存 5、设置不同的过期时间,让缓存失效的时间点尽量均匀 缓存穿透: 1、缓存空值 如果一个查询返回的数据为空(不管是数据不 存在,还是系统故障)我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。 通过这个直接设置的默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库 2、采用布隆过滤器BloomFilter 优势占用内存空间很小,bit存储。性能特别高。 将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力
七、如果给7亿数据你,你怎么处理这些数据;我回答了集群,多主多从,一主对多从,读写分离的架构模式;然后对方问在多主的情况下,这7亿数据,你应该怎么分配到这若干台主机上面,如果业务突然要求要额外导3亿数据进来,允许你增加机器,比如说增加了3台,你怎么很好地结合本来的七亿数据;(深入浅出一致性Hash原理:注意:这个是memcached的分配策略) (主要是从关于redis集群的通过CRC32哈希槽节点分配,添加减少节点来考虑)
八、vue的特点,以及优缺点
九、什么时候用到多线程;谈谈你对锁的理解(我主要是回答了synchronized关键字和readwritelock接口(悲观锁),后来发觉还有一个乐观锁那么叼的东西),
十、wait状态和runnable状态之间是什么?我当时很懵逼,不应该是写业务代码吗?
十一、请设计一下电商秒杀系统的实现方式?SETNX;悲观锁思路, FIFO思路,乐观锁思路;(业务分离、限流、降级、熔断、redis集群、消息队列)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
private boolean checkSoldCountByRedisDate(String key, int limitCount, int buyCount, Date endDate, String lock, int expire) { boolean check = false; if (this.lock(lock, expire)) { Integer soldCount = (Integer) redisUtil.get(key); Integer totalSoldCount = (soldCount == null ? 0 : soldCount) + buyCount; if (totalSoldCount <= limitCount) { redisUtil.set(key, totalSoldCount, DateUtil.diffDateTime(endDate, new Date())); check = true; } redisUtil.remove(lock); } else { if (this.unDieLock(lock)) { logger.info("解决了出现的死锁"); } else { throw new ServiceException("活动太火爆啦,请稍后重试"); } } return check; }
十二、springmvc如何实现异步响应?
十三、MySQL根据一组id查结果如何保证顺序?redis如何批量查询多个key?
十四、如何实现分布式锁?(SETNX)
十五、cron表达式 0/15 * * * *?如何解释
十六、至少列出三种rpc方式,并具体到具体所使用的场景 http rpc 调用方式百度
十七、乐观锁的实现方式(版本号,cas,自旋,ABA问题)
十八、try代码块中有return,又有finally代码块:先执行finally代码块里面的,再执行try代码块里面的return语句
十九、关于JAVA中String类以形参传递到函数里面,修改后外面引用不能获取到更改后的值
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
首先得明白为什么会有线程安全这个问题,之所以要考虑线程安全,是因为变量是可变的,可以被其他线程修改。如果这种情况发生了,就是线程不安全了。 如果这个变量本身都不可以变了,也就谈不上那个什么线程安全不安全了,或者说肯定是线程安全的。比如String,因为根本改不了啊。
二十一、AOP的原理:草,代理模式的jdk动态代理我都忘记了,草,innovationHander;或者cglib字节码增强方式
二十二、mybatis怎么引入另外一个xml文件里面的内容:叼,多增加一个namespace的内容就可以了,为什么当时做社保的时候我不去查一下,叼;
二十三、AOP的应用场景:日志埋点(这个自己做过)、用户登录(好像有印象这个有)、权限(当时听讲课的时候听过)、事务(懵逼)
二十四、依赖注入的方式有几种(这个问题我不懂)
二十五、spring的优点
二十六、聊一下jvm内存(我从新生代老年代这个角度回答)
二十七、你在项目中哪里用到了redis,聊一下redis,你的redis内存是多大,过期时间是的多少
二十八、hashmap 你对他的了解? (结构)jdk1.7 :数组+链表 jdk1.8:数组+链表+红黑树 ; hahsmap是怎么初始化的:jdk1.7(new的时候已经分配空间) 1.8(new的时候还没有分配空间,put的时候才分配空间),空间是16,负载因子是0.8; hashmap是怎么找key的;
二十九、arraylist 线程安全的是不是?不是。怎么使她线程安全?vector(过期),DD ARR = sync.xxx(arraylist) (颗粒度很大)?并发容器:copyrigtharrlylist(颗粒度小):数据结构?副本??concurrenthashmap
三十、依赖注入注入的方式
三十一、syncroneze和lock的区别
二、redis为什么这么快:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1)完全基于内存操作; 2)数据结构数据操作简单,也对数据结构进行了专门的优化; 3)采用单线程,避免了不必要的上下文切换以及竞争条件(采用单线程操作就已经很快了,所以就不必要采用多线程了); 4)采用了多路复用IO
四、Redis 内存淘汰机制:在redis.conf里面配:maxmemory <bytes>;
默认:当内存使用达到阈值的时候,所有引起申请内存的命令会报错
在带有过期时间的键中选择最近最少使用的。(推荐)
在所有的键中选择最近最少使用的。(不区分是否携带过期时间)(一般推荐)
六、乐观锁、悲观锁:我们平时看到的:synchronized 以及
就是悲观锁ReentrantLock
乐观锁的版本号方法:当我们要从数据库中读取数据的时候,同时把这个version字段也读出来,如果要对读出来的数据进行更新后写回数据库,则需要将version加1,同时将新的数据与新的version更新到数据表中,且必须在更新的时候同时检查目前数据库里version值 是不是之前的那个version,如果是,则正常更新。如果不是,则更新失败,说明在这个过程中有其它的进程去更新过数据了。
七、分布式锁过程当中,怎么解决setnx,setex的问题:1)用lua脚本,里面就是原子性了;2)后来的新本来setnx,setex可以用一条命令来替代了;
八、你知道Redis读写分离是怎么做数据同步的吗:数据的一致性
九、分布式高可用经典架构环节分析
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
【客户端层】到【反向代理层】的高可用,是通过反向代理层的冗余来实现的。以nginx为例:有两台 nginx,一台对线上提供服务,另一台冗余以保证高可用, 常见的实践是keepalived存活探测 【反向代理层】到【web应用】的高可用,是通过站点层的冗余来实现的。假设反向代理层是nginx, nginx.conf里能够配置多个web后端,并且nginx能够探测到多个后端的存活性。 自动故障转移:当web-server挂了的时候,nginx能够探测到,会自动的进行故障转移,将流量 自动迁移到其他的web-server,整个过程由nginx自动完成,对调用方是透明的。 【服务层】到【缓存层】的高可用,是通过缓存数据的冗余来实现的。 redis天然支持主从同步,redis 官方也有sentinel哨兵机制,来做redis的存活性检测。 【服务层】到【数据库层】的高可用,数据库层用“主从同步,读写分离”架构,所以数据库层的高可 用,又分为“读库高可用”与“写库高可用”两类。 读库采用冗余的方式实现高可用,写库采用keepalived存活探测 binlog进行同步
十、微服务高并发如何处理:ribbon 负载均衡、redis集群(三主三从、读写分离)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
首先业务分离(就是把秒杀服务器与网站其他服务器完全隔离,以防流量过大带着其他服务一起死,要死你就死吧,把配置高的服务器都用来秒杀),最前端的页面要被CDN或反向代理是肯定的,之后限流(比如服务器只能承受10W流量,高于10W的请求直接返回失败),降级(秒杀页面并发高到一定程度时可以断开某些接口查询,如推荐,相似物品,历史价格等等,减少服务器返回时间),熔断(某些接口大于某个流量活并发峰值直接返回失败,或者返回默认数据如:某些产品一直有货 ),然后进入到负载均衡器中,负载均衡器分配到web服务器中,web服务器在进入队列,之后进入一个统一的缓存计数器中,秒杀结束后,通过秒杀日志,worker计算剩余库存(此处为异步处理),并且使用MQ推送下单信息至各个系统(订单,库存,发货,子业务域。。。等等系统),各个系统处理后写入数据库。这么大流量的系统想要保证数据库中与前台库存与缓存的一致性几乎不可能,但是我们只要保证最终落表的数据是正确的就行,如同上文中使用worker读取日志采用异步的方式进行数据落表处理(当然方法还有很多,这里只介绍一个典型方案),这就是传说中的弱一致性保持,分布式系统CAP中通常都会牺牲掉C推荐 @李智慧 的图书《大型网站技术架构》反复阅读后每次都有新的感悟
十一、concurrentHashMap 如何实现线程安全 注意jdk1.7和jdk1.8的区别
十二、多线程-CAS原理
end!