zoukankan      html  css  js  c++  java
  • 笔记

    1:服务器阻塞时,什么也做不了,不能处理其他客户端的连接,资源浪费。

    2:什么时候发生阻塞:获取连接时;处理数据时;


    3:数据库的索引为B+数。
    最左前缀原则:如果对column1,column2,column3建立了联合索引,那么在使用该索引时只有三种组合,它们分别是:column1 、column1 and column2、column1 and column2 and column3,概括起来就是想要使用右边的索引,必须用上左边的所有索引。如果只使用column2作为where的查询条件,将不会用到所建好的索引。

    总结

    1、InnoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。

    2、由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。 
    3、当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。 
    4、即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。 
    5、检索值的数据类型与索引字段不同,虽然MySQL能够进行数据类型转换,但却不会使用索引,从而导致InnoDB使用表锁。通过用explain检查两条SQL的执行计划,我们可以清楚地看到了这一点。

    4:悲观锁和乐观锁

    定义:

    悲观锁(Pessimistic Lock): 
    每次获取数据的时候,都会担心数据被修改,所以每次获取数据的时候都会进行加锁,确保在自己使用的过程中数据不会被别人修改,使用完成后进行数据解锁。由于数据进行加锁,期间对该数据进行读写的其他线程都会进行等待。

    比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

    乐观锁(Optimistic Lock): 
    每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作。

     乐观锁不能解决脏读的问题。

    1.      使用自增长的整数表示数据版本号。更新时检查版本号是否一致,比如数据库中数据版本为6,更新提交时version=6+1,使用该version值(=7)与数据库version+1(=7)作比较,如果相等,则可以更新,如果不等则有可能其他程序已更新该记录,所以返回错误。

    2.      使用时间戳来实现.

    3.      CAS操作方式:即compare and swap 或者 compare and set,涉及到三个操作数,数据所在的内存值,预期值,新值。当需要更新时,判断当前内存值与之前取到的值是否相等,若相等,则用新值更新,若失败则重试,一般情况下是一个自旋操作,即不断的重试。

    最后提交前作一次select for update检查,然后再提交update也是一种乐观锁的做法。

    适用场景:

    悲观锁:比较适合写入操作比较频繁的场景,如果出现大量的读取操作,每次读取的时候都会进行加锁,这样会增加大量的锁的开销,降低了系统的吞吐量。

    乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。

    总结:两种所各有优缺点,读取频繁使用乐观锁,写入频繁使用悲观锁。

    5:为何HashMap的数组长度一定是2的次幂?

    hashMap的数组长度一定保持2的次幂,比如16的二进制表示为 10000,那么length-1就是15,二进制为01111,同理扩容后的数组长度为32,二进制表示为100000,length-1为31,二进制表示为011111。从下图可以我们也能看到这样会保证低位全为1,而扩容后只有一位差异,也就是多出了最左位的1,这样在通过 h&(length-1)的时候,只要h对应的最左边的那一个差异位为0,就能保证得到的新的数组索引和老数组索引一致(大大减少了之前已经散列良好的老数组的数据位置重新调换),个人理解。

    数组长度保持2的次幂,length-1的低位都为1,会使得获得的数组索引index更加均匀。
    均匀分布table数据和充分利用空间

    because we are using power-of-two expansion, the elements from each bin must either stay at same index, or move with a power of two offset in the new table.

    扩容后,原来table中的数据的索引要么保持不变,要么移动2的幂次方【如果扩容前数组大小为16,则移动16+index】。

    因为我们使用2的幂定义数组大小,数据要么待在原来的下标, 或者移动到新数组的高位下标。 (举例: 初始数组是16个,假如有2个数据存储在下标为1的位置, 扩容后这2个数据可以存在下标为1或者16+1的位置)


    如果没有哈希碰撞, HashMap就是个数组,我说的是如果吐舌头。 数组的查询时间复杂度是O(1),所以HashMap理想时间复杂度是O(1);如果所有数据都在同一个下标位置, 即N个数据组成链表,时间复杂度为O(n), 所以HashMap的最差时间复杂度为O(n)。如果链表达到8个元素时重构为红黑树,而红黑树的查询时间复杂度为O(logN), 所以这时HashMap的时间复杂度为O(logN)。


    HashMap本来就是为了提供高效率的查询,1.7以及之前的版本,使用单链表存储冲突节点,最坏的情况是存入n个节点全部冲突,当然由于resize扩容,那么HashMap的查询复杂

    6、SpringMVC的工作流程

    1. 用户发送请求至前端控制器DispatcherServlet

    2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。

    3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

    4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器

    5. 执行处理器(Controller,也叫后端控制器)。

    6. Controller执行完成返回ModelAndView

    7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet

    8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器

    9. ViewReslover解析后返回具体View

    10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。

    11. DispatcherServlet响应用户

     

  • 相关阅读:
    cf------(round)#1 C. Ancient Berland Circus(几何)
    cf------(round)#1 B. Spreadsheets(模拟)
    grep 精确匹配
    解决 service iptables save 报错 please try to use systemctl
    kubernetes 亲和性调度详解
    免费好用的SSH手机客户端
    axios和drf结合的增删改查
    CDH 部署 Hadoop:5.开始安装
    OpenNebula概述
    Python 3.x 引入了函数注释
  • 原文地址:https://www.cnblogs.com/esther-qing/p/8716146.html
Copyright © 2011-2022 走看看