多线程编程技术;对JVM内存模型以及性能优化具有深入的理解

Spring原理和实现,对SSM开发框架有独特的见解;

SpringBoot、SpringCloud框架,深刻理解微服务原理及运行机制,并对服务拆分、服务间调用、服务治理有深刻的理解;

具有数据库调优经验;对分库分表技术有深刻的理解;

一般在开发涉及SQL的业务都会去本地环境跑一遍SQL,用explain去看一下执行计划,看看分析的结果是否符合自己的预期,用没用到相关的索引,然后再去线上环境跑一下看看执行时间(这里只有查询语句,修改语句也无法在线上执行)。

数据库优化的八大方式:

  1. 选取最适用的字段属性
  2. 使用连接(JOIN)来代替子查询(Sub-Queries)
  3. 使用联合(UNION)来代替手动创建的临时表
  4. 事务

事务以BEGIN关键字开始,COMMIT关键字结束。在这之间的一条SQL操作失败,那么,ROLLBACK命令就可以把数据库恢复到BEGIN开始之前的状态。

  1. BEGIN;
  2. INSERT INTO salesinfo SET CustomerID=14;
  3. UPDATE inventory SET Quantity=11 WHERE item='book';
  4. COMMIT;
  1. 锁定表

    1. LOCKTABLE inventory WRITE SELECT Quantity FROM inventory WHERE Item='book';
    2. ...
    3. UPDATE inventory SET Quantity=11 WHERE Item='book';
    4. UNLOCKTABLES
  2. 使用外键

  3. 使用索引

索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(),MIN()和ORDERBY这些命令的时候,性能提高更为明显。
那该对哪些字段建立索引呢?
一般说来,索引应建立在那些将用于JOIN,WHERE判断和ORDERBY排序的字段上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。对于一个ENUM类型的字段来说,出现大量重复值是很有可能的情况。

  • 对查询进行优化,要尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引
  • 应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描(最好不要给数据库留NULL,尽可能的使用NOT NULL填充数据库)
  • 应尽量避免在where子句中使用!= 或 <>操作符,否则将引擎放弃使用索引而进行全表扫描
  • 应尽量避免在where子句中使用or来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃索引而进行全表扫描
  • in 和 not in 也要慎用,否则会导致全表扫描,对于连续的数值,能用between就不要用in,很多时候用exists代替in是一个好的选择
  • 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描
  • 不要在where子句中的 “=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引
  • 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

[

](https://blog.csdn.net/baidu_37107022/article/details/77460464)

主流NoSQL数据库(Redis、MongoDB等)的使用和优化;

Redis与Memcached对比

  1. 数据类型:Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB,支持set,list等类型;
  2. 持久性:Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,因此对对可靠性方面要求比较高、做了数据持久化;
  3. 数据一致性:redis是单线程模型,保证了数据按顺序提交,Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。 memcached需要cas保证数据一致性,在高并发下。性能会受到影响,甚至不如redis。

Redis与MongoDB区别

  • 内存管理

Redis 数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的 LRU 算法删除数据。
MongoDB 数据会优先存于内存,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。
需要注意的是Redis 和mongoDB特别消耗内存,一般不建议将它们和别的服务部署在同一台服务器上。

  • 数据结构

Redis 支持的数据结构丰富,包括hash、set、list等。
MongoDB 数据结构比较单一,但是支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。

  • 数据量和性能

当物理内存够用的时候,性能,redis>mongodb>mysql
数据量,mysql>mongodb>redis
注意mongodb可以存储文件,适合存放大量的小文件,内置了GirdFS 的分布式文件系统。

  • 可靠性

mongodb从1.8版本后,采用binlog方式(MySQL同样采用该方式)支持持久化,增加可靠性;
Redis依赖快照进行持久化;AOF增强可靠性;增强可靠性的同时,影响访问性能。
可靠性上MongoDB优于Redis。
[

](https://blog.csdn.net/hu948162999/article/details/81774641)

lucene原理,掌握ElasticSearch搜索引擎的使用;

Elasticsearch 是一个实时分布式存储、搜索、分析的引擎。

消息中间件(如:RabbitMQ、RocketMQ、Kafka)的原理及使用;

大数据开发相关技术

分布式系统的Session共享

分布式Session一致性说白了就是服务器集群Session共享问题。
Session是客户端与服务器通讯会话跟踪技术,服务器与客户端保持整个通讯的会话基本信息。
解决方案:

  • 使用cookie来完成(很明显这种不安全的操作并不可靠)
  • 使用Nginx中的ip绑定策略,同一个ip只能在指定的同一个机器访问(不支持负载均衡)
  • 利用数据库同步session(效率不高)
  • 使用tomcat内置的session同步(同步可能会产生延迟)
  • 使用token代替session
  • 使用spring-session或者集成好的解决方案,session存放在redis中
  1. 基于数据库的Session共享

首选Mysql数据库,并且建议使用内存表Heap,提高session操作的读写效率。这个方案的实用性比较强,经常被使用,它的缺点在于session的并发读写能力取决于Mysql数据库的性能,同时需要自己实现session淘汰逻辑,以便定时从数据表中更新、删除 session记录,当并发过高时容易出现表锁,虽然可以选择行级锁的表引擎,但不得不否认使用数据库存储Session还是有些杀鸡用牛刀的架势。

  1. 基于Cookie的Session共享

这个方案可能比较陌生,但它在大型网站中还是比较普遍被使用。原理是将全站用户的Session信息加密、序列化后以Cookie的方式, 统一 种植在根域名下(如:.host.com),利用浏览器访问该根域名下的所有二级域名站点时,会传递与之域名对应的所有Cookie内容的特性,从而实现户的Cookie化Session 在多服务间的共享访问。
这个方案的优点无需额外的服务器资源;缺点是由于受http协议头信心长度的限制,仅能够存储小部分的用户信息,同时Cookie化的 Session内容需要进行安全加解密(如:采用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证),另外它也会占用一定的带宽资源,因为浏览器会在请求当前域名下任何资源时将本地Cookie附加在http头中传递到服务器。

  1. 基于Memcache的Session共享

Memcache由于是一款基于Libevent多路异步I/O技术的内存共享系统,简单的 Key + Value 数据存储模式使得代码逻辑小巧高效,因此在并发处理能力上占据了绝对优势。另外值得一提的是Memcache的内存hash表所特有的Expires数据过期淘汰机制,正好和Session的过期机制不谋而合,降低了过期Session数据删除的代码复杂度,对比基于数据库的存储方案,仅这块逻辑就给数据表产生巨大的查询压力。

  1. 基于Redis的Session共享

该方案使用Redis来存储用户的登录状态,Redis服务器也存在多做存储数据的淘汰策略,与Session的过期机制非常类型。目前该方案是互联网公司最广泛使用的方案,没有之一。Spring还专门开发了一个分布式Session的组件。

Spring Session:
Spring Session 提供了一套创建和管理 Servlet HttpSession 的方案。Spring Session 提供了集群 Session(Clustered Sessions)功能,默认采用外置的 Redis 来存储 Session 数据(不用手动存储到redis中),以此来解决 Session 共享的问题。

考虑到session中数据类似map的结构,采用redis中hash存储session数据比较合适,如果使用单个value存储session数据,不加锁的情况下,就会存在session覆盖的问题,因此使用hash存储session,每次只保存本次变更session属性的数据,避免了锁处理,性能更好。
如果每改一个session的属性就触发存储,在变更较多session属性时会触发多次redis写操作,对性能也会有影响,我们是在每次请求处理完后,做一次session的写入,并且之写入变更过的属性。
如果本次没有做session的更改, 是不会做redis写入的,仅当没有变更的session超过一个时间阀值(不变更session刷新过期时间的阀值),就会触发session保存,以便session能够延长有效期。

Spring的AOP

AOP(Aspect Oriented Programming):面向切面编程,其宗旨是在不修改源代码的前提下扩展功能。
应用场景:

  • 性能检测
  • 访问控制
  • 事务管理
  • 缓存
  • 日志模块

AOP优点:

  • 集中处理项目的业务问题抽取出来单独编写
  • 减少代码冗余
  • 提高程序的维护性和扩展性

专业术语

  • 通知(Advice)
  • 连接点(JoinPoint)
  • 切入点(Pointcut)
  • 切面(Aspect)
  • 引入(introduction)
  • 目标(target)
  • 代理(proxy)
  • 织入(weaving)

AOP原理
AOP的实现方式其实是代理模式,代理模式是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。