单例模式
-
目的:确保一个类只能有一个实例,并提供访问它的全局访问点。
-
为解决:一个全局使用的类频繁地创建和销毁。
-
何时使用:当你想控制实例数目,节省系统资源的时候。
-
应用实例:
- windows是多进程多线程的,在操作一个文件时,不可避免的出现多个进程或线程来同时操作一个文件,因此所有文件处理都必须通过唯一的实例。
- 一些设备管理器比如打印机,需要用到单例模式。假如一个电脑连两个打印机,就不能同时打印一个文件。
-
优点:内存只有一个实例,减少开销;避免对资源的多重占用。
-
缺点:没有接口,不能继承。
-
实现:
- 懒汉式, 线程不安全
- 懒汉式,线程安全
- 饿汉式
HashMap底层原理
HashMap
JDK8之后,如果哈希表单向链表中元素超过8个,那么单向链表这种数据结构会变成红黑树数据结构。当红黑树上的节点数量小于6个,会重新把红黑树变成单向链表数据结构。
- 解决hash 冲突:就是不同的元素通过 Hash&(lenth-1) 公式算出的位置相同,现在就启动了链表(单项链表),挂在了当前位置的下面,而链表的元素怎么关联呢,就用到了Node 的next ,next的值就是该链表下一个元素在内存中的地址。jdk1.7 就是这样处理的,而到了 1.8 以后,就引用了红黑树,1.8以后这个链表只让挂7个元素,超过七个就会转成一个红黑树进行处理(最多是64,超多64 就会重新拆分)。当红黑树下挂的节点小于等于6的时候,系统会把红黑树转成链表。 Node 在jdk1.8之前是插入l链表头部的,在jdk1.8中是插入链表的尾部的。
- hashMap 扩容:hashMap 会根据 当前的hashMap 的存储量达到 160.75=12 的时候,就是扩容 162=32 依次类推下去。2倍扩容。
SQL
- 索引:SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间
Redis
-
是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。
-
高性能:
假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在数缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可。 -
高并发:
直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。 -
Redis为什么这么快:
- 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1);
- 数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的;
- 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,
- 使用多路 I/O 复用模型,非阻塞 IO;
- 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;