CAS机制、索引(主索引、辅助索引)、笛卡尔积

ConcurrentHashMap

  • 在JDK1.8中的数据结构以及如何实现线程安全
    • 1.8之前ConcurrentHashMap采用的是分段(segment)锁机制
    • 1.8开始ConcurrentHashMap的数据结构与1.8中HashMap的数据结构一致,都是数组+链表+红黑树
    • 如何实现线程安全: CAS+synchronized
      • 什么是CAS机制:
        • 就是执行写操作的的时候,先获取版本号,提交的时候再次获取版本号,两次版本号一致则提交成功,否则自旋,超出时间返回失败
      • 若桶位置为空则采用CAS机制
        • 其中一条线程会先获该桶位的取版本号,插入提交的时候,(再次获取版本号)若发现版本号一致,则成功
        • 另一条线程也会获取版本号,提交的时候,(再次获取版本号)发现两次获取的版本号不一致,自旋
      • 若桶的位置不为空则
        • 多线程并发,谁先获取桶位的头节点,谁就先给头节点加锁,后获取的想进来加锁,发现有锁,进入阻塞等待
      • 这样的情况下,相比较于JDK1.7的给segment加锁,这里效率更高,因为是直接给桶位加锁,假设线程B操作2桶位,和线程A操作的1桶位,是并发执行的
      • 即:只要位置不同,完全不受影响,
        • 并且桶位相同的情况下,只有桶位不为null才会加锁
ConcurrentHashMap实现线程安全的机制:CAS+synchronized
eg:2线程并发执行添加元素操作,且2个线程添加的元素均要向同一散列桶添加
 -若桶位置为null,此时采用CAS保证线程安全.
     -线程1向下标1位置插入key-value, 此时采用CAS,
     -线程2并发向下标1位置插入key-value, 此时采用CAS,
      在插入操作时若版本号不一致,则某线程自旋,从而确保线程安全.
​
 -若桶位置不为null,则线程会给该位置的头节点加锁
     -假设线程1先访问,则给头节点加上锁,
     -此时线程2也想给头节点加锁,只能阻塞
     -线程1加上锁,则线程1先根据key进行equals比较,
        - 若true,则替换value
        - 若false,则在链表或红黑树中添加新的Node节点

索引(Index),一张表可以创建多个主键

  • 索引的定义:
    • 为该列数据进行排序,继而生成"目录".
  • 索引的作用:
    • 索引是用来提高查询效率的 -- 当数据量大时,效果显著
  • 索引提高查询效率原理:
    • 索引类似于对数据创建了目录
  • 索引是如何创建目录的?以及创建好的目录中保存的是什么?
    • Mysql的存储引擎是Innodb,会使用B+Tree(数据结构)来为索引创建目录
  • 数据结构:BTree:多叉平衡查找树(新增的时候实现了排序) B:balance
    • Degree度:BTree的度是自定义的:就是有几个分叉,如:二叉树的度就是2,一个节点可以有两个分叉
    • 它会分裂提取,如果目前度的数是5,则每个数据块保存的元素个数小于等于n-1的
      • 也就是说,一个元素块最多保存4个,如果此时再来一个元素,那么进灰进行分裂提取
      • 分裂提取的做法是:将最中间的数据提到上一层去,上一层就会出现数据块(保存提取的值),原来的数据块就会分裂成两个数据块,(左侧数据块都大于父节点的值,右侧数据块都小于父节点的值)
      • 提取出的元素前后会有两个指向
        • 即:每个元素的前后都会有前驱指针和后继指针

  • 上图的BTree 的度为5,已经添加了4个元素,此时再添加一个元素就会分裂 ,如下图:

  •  如果此时再添加元素 比如添加 7 ,跟二叉树类似,会先和父节点比大小,如果小,到左侧,左侧有数据块,再次比大小(遍历),比8小,就会添加到8的左侧,再来个6同理,如果再次添加,数据块的节点数即将超过n-1 那么就会提取中间节点,到它的父节点上再次比较
  • 如下图

  • 当添加元素8的时候,就会分裂 

  •  也就是说,当我们要查找数据的时候,查找的是对磁盘的IO操作,数据块会保存到内存里,我们在数据块里查找元素,是在内存的操作,查找目录是磁盘操作,然后将数据块保存到内存里的

B+Tree是BTree的变种

  • B+Tree与BTree的区别:
    • 1、叶子节点数据块之间有指针指向,目的是为了提高查找某区间范围数据的效率
      • 例如:查找11-15之间的所有数字,此时只需找到11,则可以根据指向找到后续的内
    • 2、分裂提取时,被提取的数依然存在子数据块中,而且往上提的元素保存在偏大的子块里

Mysql中索引的实现:使用B+Tree数据结构,并 在B+Tree基础上进行了优化

  • 索引是干什么的
    • 索引会给某一列(字段)添加,目的要为该列的所有数据进行排序,并生成目录,便于查找。
    • id是主键,唯一的(并且是整数,且自增的,根据主键生成索引是有顺序的),根据主键生成索引是最优的选择
    • 如果主键不是自增的,且不是整数是随机生成的,那么每次新增的时候都得重新排序,效率大大降低

聚集索引:

  • mysql的Innodb 会自动的 为每张表的主键添加索引,所以若数据库的存储引擎是Innodb,则每张表必须要有主键
    • 默认给主键添加的索引,叫做聚集索引/主索引
  • 若创建的表没有主键
    • 此时先找到unique约束的自动给该列添加索引.
  • 若创建的表中没有unique约束的字段
    • 此时会为表添加隐式的主键,长度为6,类型为long

叶子节点为 key+data,下图是简略图

  •  key:表示的是添加索引那列的数据
    • 如果添加索引的列是id 那么该列的数据值就是id,如果索引列是name,那么该列的数据值就是name 的值
  • data:在Innodb引擎里,保存的是真正的数据

非叶子节点为:key

  • 即:只有索引的值,而没有保存真实的

聚集索引:对主键添加的索引,叶子节点保存的是key+data,而且data保存的是真实数据,又叫主索引

        如果添加条件这一列,根据where条件 查询条件时非常高的

        比如说读2,第一次io操作,比12小 去左侧,找到左侧后,在找到你要去哪一块去找

        找到区域之后,找到数据块,数据块里找的是谁,一下就找到了,而且直接找到的是数据

非聚集索引/辅助索引

  • 给非主键列添加的索引,即为非聚集索引
    • 聚集索引与非聚集索引的叶子节点中保存的数据不同
  • 聚集索引叶子节点中保存的为
    • key(索引)-data(真实的数据)
  • 非聚集索引叶子节点中保存的为
    • key(索引)-data(主键),之后再根据找到的主键调用聚集索引查到最终的数据 
  • 我们创建索引(对name添加索引),
    • 比如说当我们要对name进行查询的时候,给name添加索引
    • 1、数据库会对所有的数据进行排序生成目录结构 
    • 2、生成目录结构后,key保存的就是索引(name的值),data保存的就是主键id
  • 它查找的方式是,根据索引的名字 找到 主键id,然后根据主键id去聚集索引里去找data
  • data为真是数据,就找到了

  •  创建索引的sql:
    • create index 索引名字 on 表(表字段);
  • 删除索引的sql
    • drop index 索引名字;
create index index_name on table(col);
​
删除索引:
drop index index_name;
  • 什么时候使用索引,什么时候不要使用索引:
    • 若表中的数据量不大,不建议使用索引,因为添加索引tree会排序,也会占用时间和内存
    • 若某列的数据值会被频繁改动,不要给这一列添加索引(如金额等)因为值修改之后,对应的索引会更新(添加索引是需要排序的)
    • 通常会为where后的某个常用的查询条件的字段添加索引
  • 索引失效的情形:
    • 若添加索引的字段涉及到运算,此时索引会失效.
      • eg:
      • age添加索引 where age+1>x,age上的索引失效
    • 添加索引的字段使用函数也是失效
    • 若使用左侧模糊查询 (like '%a'),索引会失效,肯定会失效的那就挨个找了
      • 右侧模糊查询正常使用
  • 在查询条件部分对添加索引的字段使用not in,索引会失效
    • 而in 相当于 指定索引了,而使用not in 相当于范围查找了
  • 当数据量大的时候,查询如何优化
    • 添加索引,避免使用索引失效的情形
select..from table where id in(1,3,5)-索引有效
select..from..where age not in(10,11)-索引失效

sql语句中各部分的执行顺序

  • 一旦on出现,前边的就会出现一次联查,
  • 如果再出现on 那么就会拿之前的那张虚拟表和后边的表再进行一次联查,这种情况下,一种执行了2次IO读取操作
  • 也就是说一次on就会产生一次联查

笛卡尔积:

  • 左表中的每条数据均与右表中的每条数据进行匹配并生成结果
  • 最终生成的结果数为:m*n
    • m:A标的数据量
    • n:B表中的数据量
  • from后这时候会产生表的笛卡尔积效果
    • 1、from t1 join t2,此时会先产生t1,和t2的笛卡尔积,结果集是一张表是虚拟表(所有数据的拼接,能拼接起来的)V1
    • 2、on 确定连接条件,是从刚才的笛卡尔积里面筛出的一些数据 V2(如下图的笛卡尔积筛选),然后可以把它当做一个新的虚拟表
    • where 继续筛选得到V3
    • group by 得到 v4
    • having

多表查询的时候,这种效率最高,因为只出现了一次on 说明只执行了一次
IO操作
select * from t1 join t1 join t3 join t4...on t1.xx = t2.xx and t2.xx=t3.xx and..


这种情况是:出现了两次on,说明执行了两次IO操作
// 应用的场景:要求t1,t2先出结果集,拿此结果集与t3再次联查
select * from t1 join t2 
on // 出现一次IO查询,
t1.xx = t2.xx 
join t3 
on // 拿t1 与 t2的结果集与t3再次进行IO查询
...
select distinct col1,col2..from t1 join t2 on t1.xx=t2.xx 
where ...group by ...having....order by...limit...
​
select * from emp e right join dept d on e.id = d.id

多表执行顺序:
    1. from  产生笛卡尔积虚拟表v1 无论什么连接,先执行交叉连接
    2. on    确定连接条件,则可以从上述的v1中筛出数据
             -虚拟表v2
    3. left/right join  
        -在v2基础上将主表中独有的数据添加到v2中,
        另一个表因为无匹配数据,以null填充.产生v3
    4. where - 在v3基础上再次筛选条件,得到虚拟表v4
    5. group by - 在v4基础上进行分组产生虚拟表v5
    6. having  - 在v5的基础上再次进行数据筛选得出v6
    7. select - 在v6的基础上查询结果得出虚拟表v7
    8. distinct - 去重得出虚拟表v8
    9. order by - 基础v8进行排序得到虚拟表v9
    10. limit - 基于v9是筛选出想要的部分数据
        limit m,n
        limit x;   筛选出前x条数据
​
注意点:
select ..from t1 join t2 on t1.xx=t2.xx join t3 on..  --- 应用的场景:要求t1,t2先出结果集,拿此结果集与t3再次联查.

面试题:

1.请描述servlet的生命周期 - 涉及到的方法

servlet的作用是用来接收和响应请求

1. 默认情况下,当请求第一次到达servlet时,该servlet进行实例化
2. 紧接着会调用init()方法进行初始化
3. 客户端每次向该servlet发起请求,均调用service()来进行处理
4. 在实例销毁前调用destroy()方法,通常用于做最后的资源释放.
​
serlvet内部的方法:
构造方法
init()
service() -- 用来处理请求
   doGet()/doPost() -- 内部都调用了service()
destroy()  -- servlet实例在销毁前会调用的方法

Navicat使用

连库、创建数据库、创建表 

  • 连库
    • 连接名随便起,自己定义的名字

  •  创建一个数据库  
    • 字符集用utf8mb4     是4个自己,包含的更多
      • utf8 默认是utf8mb3 即 3个字节,我们不用
    • 排序规则用ci这个

  • 创建字段,可以添加主键
    • 添加自增等操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值