springmvc和spring-boot区别

springmvc和spring-boot区别

  • Spring 是一个“引擎”;
  • Spring MVC 是基于Spring的一个 MVC 框架;
  • Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。 SpringBoot和SpringMVC的区别

    @Autowired的实现原理

  • 通过接口BeanPostProcessor的实现类 AutowiredAnnotationBeanPostProcessor解析注解@Autowired
  • DefaultLiableBeanFactory工厂类实例化与装配
  • 执行装配,方法populateBean执行了最终的Autowired动作

Spring MVC 解读——@Autowired

Bean的默认作用范围是什么?其他的作用范围?

在Spring中使用Scope来表示一个bean定义对应产生实例的类型,也可以说是对应实例的作用范围。Spring内置支持的scope严格来说默认是有五种,分别是:

  • singleton:这是默认Scope,表示在整个bean容器中或者说是整个应用中只会有一个实例。
  • prototype:多例类型,表示每次从bean容器中都会获取到一个对应bean定义全新的实例。
  • request:仅适用于Web环境下的ApplicationContext,表示每一个HttpRequest生命周期内会有一个单独的实例,即每一个Http请求都会拥有一个单独的实例。
  • session:仅适用于Web环境下的ApplicationContext,表示每一个HttpSession生命周期内会有一个单独的实例,即每一个HttpSession下都会拥有一个单独的实例,即每一个用户都将拥有一个单独的实例。
  • globalSession:仅适用于Web环境下的ApplicationContext,一般来说是Portlet环境下。表示每一个全局的Http Session下都会拥有一个单独的实例。
  • application:仅适用于Web环境下的ApplicationContext,表示在ServletContext生命周期内会拥有一个单独的实例,即在整个ServletContext环境下只会拥有一个实例。

Spring(10)——bean作用范围

索引是什么概念有什么作用?MySQL里主要有哪些索引结构?哈希索引和B+树索引比较?

来自百科

在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构, 它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。 索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

优点

  • 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
  • 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
  • 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
  • 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
  • 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

缺点

  • 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
  • 第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间 就会更大。
  • 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度

Mysql索引结构及常见索引的区别

由 B-/B+树看 MySQL索引结构

从 MongoDB 及 Mysql 谈B/B+树

Java线程池的原理?线程池有哪些?线程池工厂有哪些线程池类型,及其线程池参数是什么?

线程池的实现原理

提交一个任务到线程池中,线程池的处理流程如下:

  • 1、判断线程池里的核心线程是否都在执行任务,如果不是(核心线程空闲或者还有核心线程没有被创建)则创建一个新的工作线程来执行任务。如果核心线程都在执行任务,则进入下个流程。
  • 2、线程池判断工作队列是否已满,如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程。
  • 3、判断线程池里的线程是否都处于工作状态,如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。

五种线程池的分类和作用

hashmap原理,处理哈希冲突用的哪种方法?

Java GC机制?GC Roots有哪些?

Java GC机制

在Java语言里,可作为GC Roots对象的包括如下几种:

  • a.虚拟机栈(栈桢中的本地变量表)中的引用的对象
  • b.方法区中的类静态属性引用的对象
  • c.方法区中的常量引用的对象
  • d.本地方法栈中JNI的引用的对象

Java怎么进行垃圾回收的?

java什么时候进行垃圾回收,垃圾回收的执行流程

  • 一个对象实例化时 先去看伊甸园有没有足够的空间
  • 如果有 不进行垃圾回收 ,对象直接在伊甸园存储.
  • 如果伊甸园内存已满,会进行一次minor gc
  • 然后再进行判断伊甸园中的内存是否足够
  • 如果不足 则去看存活区的内存是否足够.
  • 如果内存足够,把伊甸园部分活跃对象保存在存活区,然后把对象保存在伊甸园.
  • 如果内存不足,向老年代发送请求,查询老年代的内存是否足够
  • 如果老年代内存足够,将部分存活区的活跃对象存入老年代.然后把伊甸园的活跃对象放入存活区,对象依旧保存在伊甸园.
  • 如果老年代内存不足,会进行一次full gc,之后老年代会再进行判断 内存是否足够,如果足够 同上.
  • 如果不足 会抛出OutOfMemoryError.

image

什么对象会进老年代?

  • 对象每在Survivor中熬过一次Minor GC,年龄就增加1岁,当他的年龄增加到最大值15时,就将会被晋升到老年代中。
  • 如果在Survivor空间中所有相同年龄的对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无需等到MaxTenuringThreshold中要求的年龄。

垃圾回收算法有哪些?

  • 1.标记-清除算法

等待被回收对象的“标记”过程在上文已经提到过,如果在被标记后直接对对象进行清除,会带来另一个新的问题——内存碎片化。如果下次有比较大的对象实例需要在堆上分配较大的内存空间时,可能会出现无法找到足够的连续内存而不得不再次触发垃圾回收。

  • 2.复制算法(Java堆中新生代的垃圾回收算法)

此GC算法实际上解决了标记-清除算法带来的“内存碎片化”问题。首先还是先标记处待回收内存和不用回收的内存,下一步将不用回收的内存复制到新的内存区域,这样旧的内存区域就可以全部回收,而新的内存区域则是连续的。它的缺点就是会损失掉部分系统内存,因为你总要腾出一部分内存用于复制。

在Java堆中被分为了新生代和老年代,这样的划分是方便GC。Java堆中的新生代就使用了GC复制算法。在新生代中又分为了三个区域:Eden 空间、To Survivor空间、From Survivor空间

新的对象实例被创建的时候通常在Eden空间,发生在Eden空间上的GC称为Minor GC,当在新生代发生一次GC后,会将Eden和其中一个Survivor空间的内存复制到另外一个Survivor中,如果反复几次有对象一直存活,此时内存对象将会被移至老年代。可以看到新生代中Eden占了大部分,而两个Survivor实际上占了很小一部分。这是因为大部分的对象被创建过后很快就会被GC(这里也许运用了是二八原则)。

  • 3.标记-压缩算法(或称为标记-整理算法,Java堆中老年代的垃圾回收算法)

对于新生代,大部分对象都不会存活,所以在新生代中使用复制算法较为高效,而对于老年代来讲,大部分对象可能会继续存活下去,如果此时还是利用复制算法,效率则会降低。标记-压缩算法首先还是“标记”,标记过后,将不用回收的内存对象压缩到内存一端,此时即可直接清除边界处的内存,这样就能避免复制算法带来的效率问题,同时也能避免内存碎片化的问题。老年代的垃圾回收称为“Major GC”。

为什么新生代使用复制算法?

  • 新生代中,每次垃圾收集时都发现大批对象死去,仅仅有少量存活,那就选用复制算法。
  • 老年代由于对象存活率高,没有额外空间对它进行分配担保,那就必须使用“标记-清理”或者“标记-整理”等重量级算法来进行回收

HashMap的时间复杂度?

分四步:

  • 1.判断key,根据key算出索引。
  • 2.根据索引获得索引位置所对应的键值对链表。
  • 3.遍历键值对链表,根据key找到对应的Entry键值对。
  • 4.拿到value。

分析: 以上四步要保证HashMap的时间复杂度O(1),需要保证每一步都是O(1),现在看起来就第三步对链表的循环的时间复杂度影响最大,链表查找的时间复杂度为O(n),与链表长度有关。我们要保证那个链表长度为1,才可以说时间复杂度能满足O(1)。但这么说来只有那个hash算法尽量减少冲突,才能使链表长度尽可能短,理想状态为1。因此可以得出结论:HashMap的查找时间复杂度只有在最理想的情况下才会为O(1),而要保证这个理想状态不是我们开发者控制的。

HashMap, HashTable,HashSet,TreeMap 的时间复杂度

HashMap中Hash冲突是怎么解决的?

  • HashMap的数据结构是:数组Node[]与链表Node中有next Node.
  • 动态扩容,增加数组长度

链表的上一级结构是什么?

数组

Java8中的HashMap有什么变化?

JDK1.8引入红黑树大程度优化了HashMap的性能。

红黑树需要比较大小才能进行插入,是依据什么进行比较的?

hash和B+树的区别?分别应用于什么场景?哪个比较好?

  • 简单地说,哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值, 检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。
  • B+树索引和哈希索引有如下四点明显区别:
    • a、如果是等值查询,那么哈希索引明显有优势,因为只需要经过一次算法即可找到相应的键值; 当然了,这个前提是,键值都是的。如果键值不是的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据;
    • b、如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索; 同理,哈希索引也没办法利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);
    • c、哈希索引也不支持多列联合索引的最左匹配规则;
    • d、B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题。

项目里有个数据安全的,aes和md5的区别?

aes是对称加密

MD5算法具有以下特点:

  • 1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
  • 2、容易计算:从原数据计算出MD5值很容易。
  • 3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
  • 4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

为什么MyISAM查询性能好?

INNODB在做SELECT的时候,要维护的东西比MYISAM引擎多很多:

  • 1)数据块,INNODB要缓存,MYISAM只缓存索引块,这中间还有换进换出的减少;
  • 2)innodb寻址要映射到块,再到行,MYISAM记录的直接是文件的OFFSET,定位比INNODB要快
  • 3)INNODB还需要维护MVCC一致;虽然你的场景没有,但他还是需要去检查和维护MVCC (Multi-Version Concurrency Control)多版本并发控制

注释:

InnoDB:通过为每一行记录添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建, 另外一个记录这行数据何时过期(或者被删除)。但是InnoDB并不存储这些事件发生时的实际时间,相反它只存储这些事件发生时的系统版本号。这是一个随着事务的创建而不断增长的数字。每个事务在事务开始时会记录它自己的系统版本号。每个查询必须去检查每行数据的版本号与事务的版本号是否相同。让我们来看看当隔离级别是REPEATABLEREAD时这种策略是如何应用到特定的操作的:

SELECT InnoDB必须每行数据来保证它符合两个条件:

  • 1、InnoDB必须找到一个行的版本,它至少要和事务的版本一样老(也即它的版本号不大于事务的版本号)。这保证了不管是事务开始之前,或者事务创建时,或者修改了这行数据的时候,这行数据是存在的。
  • 2、这行数据的删除版本必须是未定义的或者比事务版本要大。这可以保证在事务开始之前这行数据没有被删除

事务特性(acid)

  • 原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
  • 一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
  • 隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
  • 持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

隔离级别

事务隔离级别|脏读|不可重复读|幻读 —|—|—|— 未提交读(read-uncommitted)RUC|是|是| 是 已提交读(read-committed)RC|否|是| 是 可重复读(repeatable-read)RR|否|否| 是 可串行化(serializable)S| 否| 否| 否

  • 提交读(RC):只能读取到已经提交的数据。
  • 可重复读(RR):在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。
  • 串行化(serializable)会锁表,因此不会出现幻读的情况,这种隔离级别并发性极低, 开发中很少会用到
  • Mysql InnoDB 默认事务隔离级别为RR

SQL慢查询的常见优化步骤?

  • 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

  • 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num is null

可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

select id from t where num=0
  • 3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

  • 4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num=10 or num=20	
可以这样查询:	
select id from t where num=10	
union all	
select id from t where num=20
  • 5.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)

对于连续的数值,能用 between 就不要用 in 了:

select id from t where num between 1 and 3
  • 6.下面的查询也将导致全表扫描:
select id from t where name like '%abc%'
  • 7.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100	
应改为:	
select id from t where num=100*2
  • 8.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id	
应改为:	
select id from t where name like 'abc%'
  • 9.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

  • 10.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引, 否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

  • 11.不要写一些没有意义的查询,如需要生成一个空表结构:

select col1,col2 into #t from t where 1=0

这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:

create table #t(...)
  • 12.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)	
用下面的语句替换:	
select num from a where exists(select 1 from b where num=a.num)
  • 13.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引, 如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

  • 14.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率, 因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。 一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

  • 15.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。 这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

  • 16.尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间, 其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

  • 17.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

  • 18.避免频繁创建和删除临时表,以减少系统表资源的消耗。

  • 19.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。

  • 20.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log , 以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

  • 21.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

  • 22.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

  • 23.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

  • 24.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。 在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

  • 25.尽量避免大事务操作,提高系统并发能力。26.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

说下乐观锁,悲观锁(select for update),并写出sql实现

  • 悲观锁
    //0.开始事务
    begin;/begin work;/start transaction; (三者选一就可以)
    //1.查询出商品信息
    select status from t_goods where id=1 for update;
    //2.根据商品信息生成订单
    insert into t_orders (id,goods_id) values (null,1);
    //3.修改商品status2
    update t_goods set status=2;
    //4.提交事务
    commit;/commit work;
    

    上面的查询语句中,我们使用了 select…for update 的方式, 这样就通过开启排他锁的方式实现了悲观锁。此时在t_goods表中,id为1的 那条数据就被我们锁定了, 其它的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。

上面我们提到,使用 select…for update 会把数据给锁住,不过我们需要注意一些锁的级别, MySQL InnoDB默认行级锁。行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的, 会使用表级锁把整张表锁住,这点需要注意。

  • 乐观锁
    1.查询出商品信息
    select (status,status,version) from t_goods where id=#{id}
    2.根据商品信息生成订单
    3.修改商品status2
    update t_goods 
    set status=2,version=version+1
    where id=#{id} and version=#{version};
    

    使用版本号实现乐观锁 使用版本号时,可以在数据初始化时指定一个版本号,每次对数据的更新操作都对版本号执行+1操作。 并判断当前版本号是不是该数据的最新的版本号。

SQL-乐观锁,悲观锁之于并发

sql 乐观锁与悲观锁

TCP协议的三次握手和四次挥手过程?

TCP 建立连接的三次握手过程,以及关闭连接的四次握手过程

image

贴一个 telnet 建立连接,断开连接的使用 wireshark 捕获的 packet 截图。

image

用到过哪些rpc框架

dubbo kiev

数据库连接池怎么实现

数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。 预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时, 只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。 更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。

谈谈数据库连接池的原理

Java web过滤器的生命周期

  • 1、Filter的创建

  Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作,filter对象只会创建一次,init方法也只会执行一次。通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。

  • 2、Filter的销毁

  Web容器调用destroy方法销毁Filter。destroy方法在Filter的生命周期中仅执行一次。在destroy方法中,可以释放过滤器使用的资源。

  • 3、FilterConfig接口

  用户在配置filter时,可以使用为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时, 会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得:

  String getFilterName()得到filter的名称
  String getInitParameter(String name) 返回在部署描述中指定名称的初始化参数的值如果不存在返回null.
  Enumeration getInitParameterNames()返回过滤器的所有初始化参数的名字的枚举集合
  public ServletContext getServletContext()返回Servlet上下文对象的引用

ConcurrentHashMap 在Java7和Java8中的区别?

高并发编程系列:ConcurrentHashMap的实现原理(JDK1.7和JDK1.8)

  • 1.7中采用ReentrantLock+Segment+HashEntry的方式进行实现
  • 1.8中放弃了Segment臃肿的设计,取而代之的是采用synchronized+CAS+HashEntry+红黑树来保证并发安全进行实现

为什么Java8并发效率更好?什么情况下用HashMap,什么情况用ConcurrentHashMap?

高并发Java 十 JDK8对并发的新支持

  • ConcurrentHashMap1.8中放弃了Segment臃肿的设计,取而代之的是采用synchronized+CAS+HashEntry+红黑树来保证并发安全进行实现
  • HashMap尾部遍历死循环优化,通过增加tail指针,既避免了死循环问题(让数据直接插入到队尾),又避免了尾部遍历
  • LongAdder与AtomicLong都是使用了原子操作来提高性能。但是LongAdder在AtomicLong的基础上进行了热点分离
    • 基于这个思路,打击应该可以想到一种对传统AtomicInteger等原子类的改进方法,虽然在CAS操作中没有锁, 但是像减少锁粒度这种分离热点的思路依然可以使用,一种可行的方案就是仿造ConcurrengHashMap, 将热点数据分离,比如,可以将AtomicInteger的内部核心数据value分离成一个数组,每个线程访问时, 通过哈希等算法映射到其中一个数字进行计数,而最终的计数结果,则为这个数组的求和累加, 其中,热点数据value被分离成多个单元cell,每个cell独自维护内部的值,当前对象的实际值由所有的cell累计合成, 这样,热点就进行了有效的分离,提高了并行度,LongAdder正是使用了这种思想.
  • StampedLock

加锁有什么机制?

  • 表锁:开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
  • 行锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
  • 页锁:开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般
  • 悲观锁:select * from t for update;
  • 乐观锁:版本控制

ThreadLocal?应用场景?

image

最常见的ThreadLocal使用场景为 用来解决数据库连接、Session管理等

数据库水平切分,垂直切分的设计思路和切分顺序

数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上, 这种切可以称之为数据的垂直(纵向)切分;另外一种则是根据表中的数据的逻辑关系, 将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。

先垂直,后水平

数据库垂直和水平切分

Redis如何解决key冲突

链表

Redis如何解决key冲突

soa和微服务的区别?

首先SOA和微服务架构一个层面的东西,而对于ESB和微服务网关是一个层面的东西,一个谈到是架构风格和方法,一个谈的是实现工具或组件。

  • 1.SOA(Service Oriented Architecture)“面向服务的架构”:他是一种设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程中。各个服务之间 通过网络调用。
  • 2.微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”, 原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。

微服务架构 = 80%的SOA服务架构思想 + 100%的组件化架构思想 + 80%的领域建模思想

SOA架构和微服务架构的区别

单机系统演变为分布式系统,会涉及到哪些技术的调整?请从前面负载到后端详细描述。

设计一个秒杀系统?