2.29TODO

  1. 基础(√)
  2. 集合(√)
  3. 多线程(√)
  4. JVM(√)
  5. Redis(√)
  6. Mysql(√)
  7. MongoDB
  8. 计网+操作系统
  9. Spring

1. Redis

  1. 什么是Redis:非关系型的键值对数据库,数据存在内存中,读写速度快,一般用于缓存数据
  1. 项目为什么使用mongoDB:(https://blog.csdn.net/dog_flying/article/details/100052831)(https://zhuanlan.zhihu.com/p/670763653
    1. 为什么不使用Redis缓存+Mysql存数据的方式

      1. 要维护Redis缓存跟Mysql数据的一致性问题
      2. 业务开发时要维护Mysql的表结构,比如有新业务要新增表字段,开发起来很麻烦
    2. 为什么选择mongoDB

      1. MongoDB自身有一个缓存层,这样就可以用一个MongoDB就能实现缓存+存储数据的功能
      2. MongoDB的是文档型,玩家的某个系统的数据是以文档形式保存在mongoDB中,读取数据时,从库中读取,放到内存中,更新数据时,先更新内存的数据,然后定义一定的时间间隔,再把内存的数据写回数据库(项目一般是5分钟执行一次,也可以手动调用update()方法更新,一般在玩家下线或者停服的时候update()玩家数据和全服玩家的数据
      3. MongoDB最大的特点就是表结构灵活,像游戏这种经常有新需求需要新增字段的,使用mongoDB直接在表里加字段就行了,不需要考虑表的结构
      4. 对数据的操作一般都是在业务代码中进行,不需要在SQL层面进行复杂的查询操作和事务操作
  1. Redis优缺点
    1. 优点:

      1. 基于内存,读写速度快
      2. 单线程,避免了线程切换的开销和多线程的竞争。执行命令是由单线程执行
      3. 支持持久化,RDB和AOF两种持久化方式,可以将数据保存到磁盘,避免数据丢失
      4. 支持事务
      5. 支持主从复制,主节点自动将数据同步到从节点
    2. 缺点:

      1. 因为是将数据放在内存,因此会受到服务器内存大小的限制,不支持大量数据的存放
  1. 为什么快
    1. 基于内存,数据读写在内存进行,速度快
    2. 单线程执行命令,避免了线程切换的开销和多线程竞争
    3. io多路复用
    4. 数据结构简单,kv键值对形式
  1. Redis是单线程还是多线程
    1. redis6.0之前是单线程的,redis6.0之后引入多线程技术,只是用来解决网路IO读写的问题,执行命令还是单线程的
  1. Redis数据类型
    1. String:键值对,key和value都是字符串

      1. 指令
        1. 设置kv,可设置存活时间:set key value [ex second][millseconds]
        2. 获取key:get key
        3. 自增:incr key
        4. 自减:decr key
      2. 应用
        1. 缓存
        2. 计数器:粉丝数
    2. Hash:key-field,常用于存储对象

    3. Set:存储无序不重复单独字符串,最多MAX_VALUE个,支持并集、交集。可用于存储共同关注

    4. List:存储有序可重复的字符串,最多MAX_VALUE个,可以两端弹出插入

      1. 指令:lpop、lpush、rpop、rpush
    5. ZSet:存储有序不重复的字符串,zrange指令可做排行榜

  1. Redis事务
    1. multi开启事务、exec执行事务、discard取消事务
    2. redis事务无法保证原子性,单条命令是原子性的,但是整个事务不是原子性,如果事务中某条命令出错,不影响其他命令的执行,事务也不会回滚
    3. redis事务没有隔离级别,multi开启事务后,exec执行事务前,输入的命令会先进入队列,先不执行。也就不存在事务内的某条查询命令会看到其他事务的更新,其他事务的查询也无法看到本事务内的更新
  1. 持久化机制
    1. RDB:redis默认的持久化机制,将数据库快照保存到dump.rdb文件中

      1. 触发
        1. save命令:是同步命令,阻塞客户端请求,直到保存成功
        2. bgsave命令:异步命令,fork一个子进程来进行数据保存,不会阻塞客户端请求
        3. 通过配置文件,自动保存:save 60 1000:指的是当60秒内有1000个key被改动时,触发自动保存
      2. 优点:数据恢复快
      3. 缺点:如果是用主动输入命令进行保存,耗时、耗性能。
        如果是自动保存,又不一定能触发保存机制
    2. AOF:

      1. 需要在配置文件中开启:appendonly yes
      2. 原理:开启AOF后,当redis执行一个命令后,这个命令就会被追加到AOF文件的末尾
      3. 策略
        1. always:每次有新命令追加到AOF文件时就执行一次fsync,非常慢,但非常安全。
        2. everySec:每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
        3. no:由操作系统执行,不安全
  1. Redis集群
    1. 为什么要部署集群:

      1. 单机情况下,一旦服务器宕机,数据不可用
      2. 单机的内存容量有限,可缓存的数据有限
    2. 主从复制:主节点负责读写,从节点只负责读,主节点修改后的数据会同步到从节点

      1. 配置主从模式
        1. 从服务器节点的配置文件,将slaveOf的port端口改成主服务器的port,然后进入主服务器,通过info replication命令查看是否配置成功
        2. 在从服务器节点使用slaveOf 主服务器port
      2. 优点:
        1. 高可用,当主节点宕机后,从节点接替主节点的工作
        2. 读写分离,主节点负责读写,从节点只负责读
      3. 缺点:主节点宕机后无法恢复,只能由从节点全权接替工作
    3. 哨兵模式:为了解决主从复制模式下主节点宕机后只剩下从节点的问题,引入了哨兵模式,在哨兵模式下,当主节点宕机后,从节点会通过竞争,选取一个从节点升级为主节点

      1. 配置哨兵模式:
        1. 配置sentinel.conf配置文件,sentinel monitor 主机名 主机ip 主机port 触发切换的哨兵数量
        2. 使用redis-sentinel命令启动哨兵服务
      2. 哨兵的作用
        1. 监视和提醒,当服务器节点出现问题时,报告
        2. 自动故障迁移,当主节点宕机后,哨兵之间会选取一个从节点升级为主节点,原来的主节点重连后,只能作为从节点
      3. 优点:解决了主从复制模式的主节点缺失问题
    4. 集群:配置多个主从复制+哨兵模式

  1. 过期策略:惰性删除、定期删除、定时删除
    expire设置key存活时间、set key value []
    1. 定期删除:每隔一段时间对一些key进行检查,删除已经过期的key
    2. 定时删除:为每个设置过期时间的key开一个定时器进行清理
    3. 惰性删除:访问这个key的时候才检查是否已过期,过期就清除
  1. 缓存击穿
    1. 原因:一个被大量访问的key突然过期了,导致大量的查询请求要去到数据库查询
    2. 解决:热点key不设置过期时间
  1. 缓存穿透
    1. 原因:大量的恶意请求查询一个不存在的key,因为缓存里找不到,要去到数据库中查询,导致数据库压力增大
    2. 解决:使用布隆过滤器,其原理相当于在缓存跟数据库之间再加了一层缓存,在初始化时,从数据库中把已有的key拿出来,放到布隆过滤器中,如果key在布隆过滤器中找不到,则说明在数据库中也没有,可以拦截恶意请求打到数据库
  1. 缓存雪崩
    1. 原因:同一时间有大量的key同时失效,导致大量请求打到数据库上
    2. 解决:设置key过期时间时,用随机数,避免大量的key同时过期

2. Mysql

  1. mysql是关系型数据库,redis和mongoDB是非关系型数据库,什么时候用
    1. 数据量小的时候用关系型数据库,因为是将数据存放在磁盘,读写数据要进行磁盘IO,速度慢
    2. 数据量大的时候用非关系型数据库,将数据读取到内存,内存读写速度快
    3. 用非关系型数据库做缓存,用关系型数据库存数据
  1. 事务四大特性:ACID
    1. 原子性:事务包括的操作要么全部成功,要么失败回滚
    2. 一致性:事务执行前后保持一致。比如a和b账户共有1000块,两人之间的转账无论是成功还是失败,总数都是1000
    3. 隔离性:事务进行的修改在最终提交之前,其他事务不能见其修改结果
    4. 持久性:事务对数据的修改一旦提交,就会保存到数据库中
  1. 脏读、不可重复读、幻读
    1. 脏读:一个事务处理过程中读取了另一个未提交事务的数据
    2. 不可重复读:同一个事务内,多次查询同一个记录,返回了不同的数据,这是因为在两个查询间隔,另一个事务修改了数据并提交了结果
    3. 幻读:事务在读取某个范围内的记录时(记录的范围区间),有另一个事务在该范围区间插入或删除了一条记录,导致读取到的记录条数不一致
  1. 事务隔离级别
    1. 串行化:加锁处理,强制事务按照顺序执行。可解决上面三个问题
    2. 可重复读:同一个事务中多次读取的数据是一致的,是mysql的默认隔离级别。可解决不可重复读和脏读问题。
    3. 读已提交:事务只能看到已经提交事务的修改结果,可解决脏读问题。
    4. 读未提交:所有事务都可以看到其他未提交事务的执行结果
  1. 隔离级别如何实现
    1. 读已提交和可重复读通过MVCC实现,串行化通过锁实现
  1. MVCC机制
    1. 当前读:读取的是数据库的最新版本的数据,并且在读取时要求其他事务不会修改当前的记录,所以是对读取的记录进行了加锁处理
    2. 快照读:不加锁,通过MVCC版本号读取UNDO LOG快照日志读取中的数据
  1. 什么是索引:索引是加快数据表的访问速度的一种数据结构
  1. 为什么索引可以加快检索速度
    1. 索引的作用就像一本书的目录,可以快速定位数据在表中的位置。如果没有索引就要遍历全部数据逐个查找

    2. 索引的底层是B+树,在B+树中,节点的key按值的大小从左到右升序排序,数据存在叶子节点。在进行查找时,首先在根节点进行二分查找,找到key所在的指针,然后在指针指向的节点区域进行查找,找到叶子节点,得到key对应的数据

3. B+树的索引又可以分为聚簇索引和非聚簇索引
    1. 主索引为聚簇索引,辅助索引为非聚簇索引。

    2. 聚簇索引是以主键作为键值,聚簇索引的叶子节点存放着完整的数据。非聚簇索引是以非主键作为键值,叶子节点存放着主键值,所以非聚簇索引在查找时,要先找到主键,然后根据聚簇索引找到主键对应的数据(回表操作)

    3. 聚簇索引使用场景:
    select id from test where id = 10;      //搜索id索引树

    4. 非聚簇索引使用场景
    select * from test where name = "123";      //非主键查询,先搜索name字段,得到name="123"对应的主键id值,再搜索聚簇索引,找到对应id值的数据
    select name from test where name = "123";   //如果非聚簇索引上有name的值等于123,那么它就不用回表

4. 为什么B+树比B树更适合
    1. B树每个节点都要存key和data,而B+树的data都存在叶子节点,非叶子节点存key。这样就使得B+树的一个节点可以存放更多的索引,树的高度更低,磁盘IO次数更少,数据检索速度更快
    2. B+树的叶子节点是按照key的值升序相连的,范围查找更快
    3. B+树的数据都在叶子节点,查询更稳定,每次查询都是从根节点到叶子节点
  1. 什么时候要建索引,什么时候不用建索引
    1. 用索引:经常查询的字段、主键必须加索引、排序字段使用索引可以加快检索速度、联表查询
    2. 不用索引:经常增删数据的字段、有大量重复数据的字段、表数据太少时没必要用索引
  1. 索引有哪些类型
    1. 主键索引:数据不能重复,不能为null,一张表只能有一个主键索引
    2. 唯一索引:数据不能重复,可以为null
    3. 普通索引
    4. 组合索引:由多个数据列组成的索引
    5. 全文索引:对文本内容进行搜索
  1. 创建索引和删除索引
    1. CREATE INDEX在已创建的指定的表和列上创建一个普通索引:CREATE INDEX (INDEX_NAME) ON (TABLE_NAME)(COLUNM_LIST)
    2. 建表时指定数据列
    3. ALTER TABLE创建索引
    4. ALTER TABLE DROP删除索引
  1. 组合索引
    1. 为什么使用组合索引

      1. 一个索引能够覆盖多个索引字段可以减少空间的开销。
      2. 减少回表次数,比如有1000W的数据,搜索3个字段,不使用联合索引执行select操作,每次都要进行回表操作。而使用联合索引时,如果3个字段能够全部覆盖,则不进行回表(覆盖索引情况)
      如:select col1,col2,col3 from table where col1 = 1 and col2 = 2 and col3 = 3;    //每个条件可以筛选出10%的数据
      不使用联合索引:先查询col1的10%,即1000W*10%=100W,然后回表从100W条数据中再查询符合col2数据,100W*10%,再回表查询符号col3的数据,10W*10%。
      使用联合索引,直接搜索:1000W*10%*10%*10%=1W
      
    2. 最左匹配原则:从SQL语句的左边开始,当遇到范围查询(>、<、between、like>)等就会停止匹配,后面的字段不会使用索引
      比如:对abc三个列建立联合索引

      1. 当查询a/ab/abc时会走索引,查询bc时不会走索引
      2. 当查询a=1 and b>2 and c=3时,c就不会走索引
    3. 什么情况下索引会失效

      1. 组合索引,在不符合最左匹配原则时,索引失效
      2. 以%或者like开头的查询
      3. 查询条件以or连接
      4. 在索引上进行计算
  1. mysql的数据结构:数值、日期、字符串
    1. 数值:整数int、浮点型float、double
    2. 日期:date
    3. 字符串:varchar、char
  1. mysql的锁
    1. 并发事务时,保证数据访问顺序的机制叫锁

    2. 锁跟隔离级别的关系

      1. 串行化:锁住整个事务范围,直到事务结束
      2. 可重复读:读取数据时加共享锁,事务结束后才释放共享锁
      3. 读已提交:读取数据时加共享锁,读取完之后释放锁
      4. 读未提交:不加锁
    3. 锁的类型:表锁、页锁、行锁。innodb默认采用表锁

    4. 共享锁:读锁,一个事务对一个数据加了共享锁,只能进行读取操作,不能更新该数据,其他事务也不能对该数据加排他锁

    5. 排他锁:写锁,一个事务对一个数据加了排他锁,可以对该数据进行读取和更新,期间其他事务不能对该数据加共享锁和排他锁

3. mongoDB

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容

  • 1. MySQL 基础考点 事务原理,事务特性,事务并发控制常用字段、含义区别常用数据库引擎直接区别 2. 什么是...
    焰火青春阅读 418评论 0 0
  • 1、面向对象: 面向对象相对应的就是面向过程,而面向过程就是注重事情的一个步骤和顺序,而面向对象注重的是参与者,而...
    墨宇暗黑阅读 1,436评论 0 1
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,865评论 2 89
  • JVM-Class类文件结构 常量池:字面量(字符串和final常量)和符号引用(类和接口的全限定名、字段的名称和...
    小丑的果实阅读 1,808评论 0 0
  • JavaOOP Java的数据结构有哪些? 线性表(ArrayList) 链表(LinkedList) 栈(Sta...
    h2coder阅读 816评论 0 14