项目架构设计领域
领域驱动模型
领域模型
贫血模型
数据模型并无逻辑代码是一种面向数据库的开发模式

        充血模型
            数据模型包含逻辑代码是一种面向对象的开发模式


    领域划分
        细分模块

    软件设计
        分层架构
            接入层
            应用层
            领域层
            基础设施层


    确定团队内部的通用语言

设计模式
    工厂模式
    抽象工厂模式
    策略模式
    享元模式
    单例模式
    代理模式

Java
数据结构
线性结构(按顺序排列)
队列
线性结构代表,先进先出,可描述数据存取,在代码中可用数组和链表实现

        栈
            线性结构代表,先进后出,可描述数据存取,在代码中可用数组和链表实现

        数组
            数组数据结构
                内存中连续的空间,定义时给定容量
                优点
                    1.查快->时间复杂度O(1)
                    2.有索引可随机查询

                缺点
                    1.增删慢->需要遍历时间复杂度O(n)
                    2.容量初始化后无法扩容



        链表
            链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的(优点:增删效率较高;但查询速度慢)
                单向链表
                双向链表



    非线性结构
        哈希表
            根据key-value访问数据结构:通过key和hash函数计算value
            优点
                查询插入快

            缺点
                删除慢
                有哈希冲突
                    根据哈希函数->不同key算出同哈希地址
                        链地址法(hashMap采用该方法解决冲突)
                            概念:
                                将开拓空间形式改为链表结构

                            优点
                                1.无堆积问题
                                2.查询快
                                3.更节省空间
                                4.删除修改节点更为方便


                        开放定址法
                            重新开辟一个新空间
                                重新计算空间算法
                                    线性探测法
                                        往后+1任然冲突再+1....

                                    二次探测法
                                        往后加1->仍然冲突->减1-->仍然冲突-->+2平方-->仍然冲突-->-2平方......

                                    伪随机探测法
                                        随机开辟空间



                            缺点
                                1.容易产生堆积问题不适合处理大量数据
                                2.可能会出现多冲突情况
                                3.冲突开辟空间方式比较浪费空间




                储存空间利用不足


        树
            树结构是一种非线性存储结构,存储的是具有“一对多”关系的数据元素的集合

        堆
            一棵完全二叉树的数组对象



JVM内核
    java虚拟机,虚构出来的计算机,内部具有计算功能,可以划平台运行java代码(与操作系统无关),即一次编写到处运行
        优点
            1.跨平台,一次编写到处运行
            2.自动管理内存,垃圾回收机制
            3.数组下标越界检查机制
            4.多态

        JVM结构
            线程私有
                1.寄存器
                    记录下一条指令地址
                    特点
                        不会发生内存溢出


                2.虚拟栈
                    1.局部变量
                    2.方法返回地址
                    3.操作数栈
                    4.动态链接
                    5.可通过-Xss 进行调优

                3.本地方法栈
                    执行native 方法


            线程共享
                4.堆
                    1.存放java new 对象
                    2.线程共享数据,存在数据安全问题
                    3.字符串常量池
                        ""为字符串特殊字符,即String a="1" 在常量池中保存并且值相等的情况下会复用。
                            1.String a="abc";String b ="abc" a和b指向字符串常量池同一地址 a==b /   String c="a"+"b"+"c" --> a==c
                            2.String f ="c"; String d = "ab"+c  --> a!=c  -->Java 语言提供对字符串串联符号(”+”)和其他对象到字符串的转换的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的,字符串转换是通过 toString 方法实现的。所以它不会在常量池中开辟空间而在堆中开辟新空间


                    4.可通过-Xms -Xmx限定其最小、最大值进行调优
                    5.发生垃圾回收的地方
                    6.数据结构
                        年轻代
                        年老代

                    7.存放字面量、静态对象

                5.方法区(元空间/jdk1.8前"永久代")
                    特点:存放在系统内存,不存放在jvm内存,不存在垃圾回收情况
                    1.运行时常量池
                    2.类信息
                    3.类加载器



        JVM运行过程
            1.加载.class文件
            2.分配内存
            3.执行垃圾回收

        JVM调优过程
            出现jvm调优原因
                老年代full gc 频繁导致SWT(stop the world即应用停顿进入卡死状态)导致CPU飙升

            调优方法
                增加年轻代 minor gc回收效率,尽量在年轻代中回收,减少老年代full gc频率
                1.使用压测工具小并发量发送数据
                2.使用top查看cpu跑高的线程记录线程id
                3.jstack(jvm自带)根据id定位到具体代码位置
                4.如果不是代码问题,分析下吞吐量和gc情况,并重新分配年轻代老年代空间
                5.主要通过堆栈默认值 -xms 和 -xss 进行调整

            垃圾回收器
                新生代收集器:
                    Serial
                        是一款用于新生代的单线程收集器,采用复制算法进行垃圾收集

                    ParNew
                        一个 Serial 的多线程版本,其它与Serial并无区别。ParNew 在单核 CPU 环境并不会比 Serial 收集器达到更好的效果,它默认开启的收集线程数和 CPU 数量一致,可以通过 -XX:ParallelGCThreads 来设置垃圾收集的线程数

                    Parallel Scavenge
                        新生代的多线程收集器,与 ParNew 的不同之处是ParNew 的目标是尽可能缩短垃圾收集时用户线程的停顿时间,Parallel Scavenge 的目标是达到一个可控制的吞吐量


                老年代收集器:
                    Serial Old
                         Serial 的老年代版本,同样是一个单线程收集器,采用标记-整理算法

                    CMS
                        以最短回收停顿时间为目标的收集器,以 “ 最短用户线程停顿时间 ” 著称
                             1.初始标记:标记一下 GC Roots 能直接关联到的对象,速度较快。
                            2.并发标记:进行 GC Roots Tracing,标记出全部的垃圾对象,耗时较长。
                            3.重新标记:修正并发标记阶段引用户程序继续运行而导致变化的对象的标记记录,耗时较短。
                            4.并发清除:用标记-清除算法清除垃圾对象,耗时较长。


                    Parallel Old
                         Parallel Scavenge 的老年代版本,是一个多线程收集器,采用标记-整理算法


                堆内存垃圾收集器:G1
                    采用 “ 化整为零 ” 的思路,把整个堆内存划分为多个大小相等的独立区域(Region),在 G1 收集器中还保留着新生代和老年代的概念,它们分别都是一部分 Region



        JVM参数
            标准
                - 开头

            非标准
                -x 开头

            不稳定
                -xx 开头


        垃圾回收
            垃圾回收期发生在堆区
                1.如何确定对象需要被回收
                        1.可达性分析法
                            以GcRoot为根节点进行引用链寻找,当对象无引用链关系则为不可达可回收

                        2.引用计数法
                            每个地方有引用,计数+1,当计数为0可回收



                2.引用类型
                    强
                    软
                    弱
                    虚

                3.垃圾回收算法
                    1.标记-清除算法
                        通过可达性分析,清除可回收对象
                            优点
                                优于复制算法空间利用率上

                            缺点
                                1.效率比复制算法慢,而且会导致swt(程序中止运行)
                                2.空间利用不足,有空间碎片



                    2.标记-整理算法(压缩)
                        (适用于年老代)通过可达性分析,将存活对象向边界移动,清除边界外的内存
                            优点
                                1.不会产生空间碎片
                                2.充分利用内存空间

                            缺点
                                1.效率比复制算法慢,而且会导致swt(程序中止运行)



                    3.标记-复制算法
                        (使用于年轻代)将内存分为两半,通过可达性分析,将存活内存复制到另外一半,原先一半进行清除
                            优点
                                清楚速度快

                            缺点
                                空间利用低下,用空间换时间



                    4.分代清除算法
                        1.年轻代(采用复制算法) 1
                            JVM 参数-Xmn
                                伊甸园
                                    8

                                fromSurvivor
                                    1

                                toSurvivor
                                    1



                        2.年老代(采用标记压缩算法) 3






jre
    java内部运行环境包含JVM

jdk
    java开发包,包括JAVA开发核心

集合类
    Collection
        List
            ArrayList
                内部使用的动态数组来存储元素,使用于列表,增删慢,查询快,线程非安全
                扩容机制
                    ArrayList扩容的本质就是计算出新的扩容数组的size后实例化,并将原有数组内容复制到新数组中去。1.5倍 关键方法 Arrays.copyof


            linkedlist
                内部使用的双向链表来存储元素,可用于列表也可用于队列,查询慢(因为空间不连续需遍历),增删快,线程非安全

            vector
                因用synchronized性能低线程安全,类似ArrayList,现在很少使用


        set(无序不可重复)
            HashSet
                底层实际上是用HashMap存:数组+链表
                作为Set接口的主要实现类;线程不安全的;可以存储null值
                  transient是Java语言的关键字,用来表示一个成员变量不是该对象序列化的一部分

            TreeSet
                TreeSet中添加的数据,要求是相同类的对象

            LinkedHashSet


    Map
            HashMap
                作为Map的主要实现类;线程不安全的,效率高;存储null的key和value
                LinkedHashMap
                    保证在遍历map元素时,可以按照添加的顺序实现遍历

                HashMap中数组的默认大小是16,而且一定是2的指数,增加为原来的2倍

            HashTable
                使用synchronized锁住整个类确保线程安全的,效率低;不能存储null的key和value
                put 和 get 等方法都用synchronized方法锁住
                Hashtable中数组默认大小11,扩容方式是 old*2+1
                Proerties类
                    读取文件


            TreeMap
                保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序, 底层使用红黑树




多线程并发
    多线程实现的四种方式
        1.继承Thread
        2.实现runnable
        3.使用callable
        4.线程池方式

    java通过Executors提供四种线程池
        1.缓存
        2.定长
        3.定时(周期)
        4.单线程

    线程相关方法
        线程状态图
            start()   启动线程,调用run方法
            run()   Thread线程里的方法,需重写,
            yield  主动释放当前线程主动权
            join    在线程中加入另一个线程,直到插入线程执行完毕
            sleep  线程休眠一段时间
            isAlive 判断线程是否存活

        wait/notify依赖于锁资源,所以只能在synchronized中来进行使用
        park/unpark是LockSupport类下的方法,park用来暂停特定线程,unpark用来将暂停的特定线程恢复

    共享变量可见性实现(原子性、有序性、可见性)
        synchronized
        reenTrantLock
        reenTrantWriteReadLock
        volatile
            1.可见性
                将共享变量各线程可见

            2.有序性
                防止指令重排序
                    意思:编译器和处理器为了优化程序性能而对指令序列进行重排序,也就是你编写的代码顺序和最终执行的指令顺序是不一致的
                    影响:重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性


            3.原子性

        ThreadLocal
            每个线程都具有自己的ThreadLocalMap对其他下线程进行隔离
                维护了ThreadLocalMap(ThreadLocal,value)



    aqs(抽象队列同步机制)
        state 
            由volitile修饰,cas修改

        clh等待队列
        condition阻塞队列
        衍生的并发工具
            reentrantLock
                ReentrantLock是Java并发包中提供的可重入互斥锁,它与synchronized相比具有更多的功能,例如可以指定公平性、支持多个条件变量、可中断和超时等特性,可以替代synchronized关键字。
                    和synchronized区别
                        1.synchronized是JVM层次的锁实现,ReentrantLock是JDK层次的锁实现;
                        2.锁状态判断:1 ReentrantLock可通过ReentrantLock#isLocked判断,synchronized无法判断
                        3.synchronized是非公平锁,ReentrantLock是可以是公平也可以是非公平的;
                        4.synchronized是不可以被中断的,而ReentrantLock#lockInterruptibly方法是可以 被中断的;
                        5.在发生异常时synchronized会自动释放锁,而ReentrantLock需要开发者在finally 块中显示释放锁;
                        6.ReentrantLock获取锁的形式有多种:如立即返回是否成功的tryLock(),以及等待指 定时长的获取,更加灵活;
                        7.synchronized在特定的情况下对于已经在等待的线程是后来的线程先获得锁(sychronized的唤醒策略),而ReentrantLock对于已经在等待的线程是先来的线程 先获得锁;

                    synchronized锁升级
                        先拟定一条线程跑,有其他线程来,就升级为轻量级锁,自旋,同个同步块两个线程争抢时,就阻塞
                            偏向锁:只在一个线程中进行,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会消除它身上的偏向锁,将锁恢复到标准的轻量级锁
                            轻量级锁:偏向锁运行在一个线程进入同步块的情况下,当第二个线程加入锁争用的时候,偏向锁就会升级为轻量级锁
                            重量级锁:轻量级锁自旋到达阈值后,没有获取到锁,就会升级为重量级锁



                1.默认是非公平锁(锁资源竞争获取)
                2.互斥锁

            countDownLatch
                和cyclicBarrier区别
                    countdownLatch是aqs和cas实现,它是一个线程等待多线程机制
                    cyclicBarrier是条件判断的,而且它是可循环的多线程互相等待机制


            Semaphore
                Semaphore是Java并发编程中的一种同步设施,它可以通过许可(permits)来控制访问共享资源的线程数量,从而达到对共享资源的访问控制。它与计数信号量有着相同的功能,但是它允许一个线程同时获取多个许可,而不是一次只能获取一个许可。



    线程池运行原理
        参数
            核心线程数
            最大线程数
            最大空闲时间
            阻塞队列
                arrayBlockingQueue
                    数组阻塞队列(线程满返回标识)
                        队列里元素储存
                        队列线程间如何阻塞和唤醒
                            reentrantLock
                            Condition



                delayqueue
                delayedWrokQueue
                linkedBlockingDeque

            线程工厂
            时间单位
            拒绝策略
                abortpolicy(默认拒绝策略)
                    直接抛异常

                discardPolicy(抛弃策略)
                    抛弃当前线程

                discardOldPolicy(抛弃策略)
                    抛弃最早线程

                callerRunPolicy(运行当前线程)
                    谁调用谁运行




    异步的几种方式
        开启线程池
            java自带线程池(阿里禁止使用,会造成oom,因为Excutor采用无界队列LinkedBlockingQueuesize,最大为Intmax值)
                newFixed
                newCached
                newsingle
                newSchdule

            自定义,最好不要使用executors创建,用ThreadPoolExecutor创建

        springboot提供的@Async
        消息队列实现

数据库
关系型数据库
mysql
索引类型
1、普通索引,基本的索引,没有任何限制,用于加速查询,数据可以重复
2、组合索引(联合索引),指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用
3、全文索引,用来查找文本中的关键字
4、唯一索引,索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
5、主键索引,特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引。也就是在唯一索引的基础上相应的列必须为主键

        索引结构
            b+tree索引
                mysql的默认索引
                data储存在叶子节点上,索引储存在非叶子节点上,叶子节点之间有双向链接,可用于范围和模糊查询

            btree索引
                orcale默认的索引
                平衡二叉树:每个节点阶段不超过一,左边节点少于根结点,右边节点大于根节点,为了实现平衡效果用自旋实现
                每个节点都储存数据

            哈希索引
                Memory引擎的默认索引
                基于hash算法计算具体槽位,用于等值查询时间复杂度时(log(1)),查询速度快,但不可用于范围模糊和分页查询,也存在哈希冲突的可能性


        sql优化
            1.识别度高字段建立索引
            2.非必要不要进行函数计算
            3.不要将类型转换作为对比条件,如字符串对比不用双引号
            4.避开索引失效情况,如%通配符,采用全匹配或者向右匹配
            5.关联查询时,尽量使用小结果集驱动大结果集

        事务隔离级别
            读未提交
            重复读(mvcc)
                同个事务读取不同数据,解决脏读(同个事务可能读到被撤回的数据)

            不可重复读(mvcc)
                同个事务读取相同数据,解决不可重复读,解决不了幻读(某个范围数据不可重复读取)

            串行化
            mvcc(多版本并发控制)
                1.快照读,一数据多版本根据readview读取undolog
                2.当前读(行锁读,悲观锁)


        慢sql查询
        储存引擎类型
            innoDb
                索引策略
                    索引覆盖
                        查询数据都在一颗索引树即可寻找所有数据,无需回表查询

                    索引下推
                        索引遍历时去除掉字段中不符条件的,减少回表,和索引效率

                    最左匹配原则
                        联合索引(a,b,c)相当于创建索引(a)(a,b)(a,b,c)



            myIsam
            memory


    orcale

非关系型数据库
    mogoDb
    redis
        常用场景
            1.热点数据缓存
            2.全局ID
                1.redis的原子性

            3.计数器
                1.incr方法
                2.同步数据库允许时间延迟

            4.分布式中数据共享,如session
                1.redis是分布式独立服务
                2.可在多个应用间共享数据

            5.分布式锁
                1.setnx方法
                2.不存在才能添加
                缺点
                    过期时效会导致锁失败
                    解决方案:守护线程看门狗机制


            6.限流
                1.incr方式
                2.以用户ID或者其他业务唯一ID作为key,每访问一次+1
                3.超过次数返回false


        高可用
            哨兵模式(一主多从)(焦点:高可用)
                单哨兵
                    集群监控
                    故障通知
                    master重新选举
                    通知客户端新得mater主机地址

                多哨兵
                    半数哨兵同意机制
                    哨兵集群不受影响单台哨兵宕机
                    比较复杂需要测试环境和生产环境充分验证才能通过


            redis cluster (redis 3.0后推出的方案)(服务端分片)(焦点:水平扩展)
                数据分片
                    slot槽位16384个
                    实现在线扩容
                    通过CRC()%16384 算法任意分配槽点,对应槽点对应任意主机
                    数据同步:先主后从(主从同步)
                        主从复制过程
                        主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

                    扩容和压缩的方式
                        扩容:将旧节点数据迁移部分到新节点
                        压缩:将新节点数据迁移到各个节点中


                hash tag :CRC(key)%16384 将批次数据统一存储在一个节点上,形式key {tag} 利用tag计算出固定的槽位值,和一致性哈希不同的是类似分盘策略,是种自定义分盘。
                Redis Cluster方案不需要额外部署Sentinel(哨兵)集群,而是通过集群内部通信实现集群监控,故障时主从切换;同时,支持内部基于哈希实现数据分片,支持动态水平扩容


        redis数据结构
            String
            List
            set
            zset
            HashMap

        IO多路复用

        redis事务
            概念:一串 以multi开头 EXEC结束的redis命令串
            常用方法
                multi:开始redis事务标识
                EXEC:开始执行命令串
                disCard:取消命令串
                WATCH:监听一个或多个键,当键值发生改变,则中止修改命令
                    监听实现图

                UNWATACH:取消监听

            事务执行流程
                1.MULTI开启事务
                2.事务进入队列QUEUED
                3.EXC执行命令队列

开发框架
spring
spring是IOC.AOP框架,简化配置开发
AOP
切面编程
1.通过反射机制
jdk动态代理(有接口)
1.InvocationHandler接口(调用处理接口)
invoke()方法,反射目标类

                    2.Proxy类(代理类)
                        根据1实例创建代理类对象


                cglib动态代理(无接口)
                    当没有InvocationHandler接口就会使用cglib
                    代码生成的类库,可以在运行时动态的生成指定类的一个子类对象



        IOC
            指创建对象的控制权的转移到spring容器中
                1.set注入
                2.构造注入
                3.注解注入



    配置方式
        XML
        注解配置
        java配置
        配置之间区别
            yml(key-value形式,缩进代表层级,具层级可表达多对多,大小写敏感)、properties(key=value的格式但只能单对单)、xml(可延展的标记语言,语言约束DTD或Schema,需要用DOM或SAX解析)

        配置注释
            @ConfigrationProperties和@Value


    创建bean方式方式
        基于注解@configration 和 @Bean
        基于XML,配合
            方法注入
            构造器注入


    bean的生命周期
        1.beanDefinition获取配置文件信息生成原始类
        2.实例化
            通过beanName找到Type通过反射返回obj回来

        3.属性复制
            populateBean
                @Autowired
                    只会byType
                    若无法分辨可以使用@Qualifier或者@Primary

                @Resource
                    默认byName
                    type有值采用type,name有值采用name
                    jdk的注释

                三级缓存问题
                    一级缓存:成熟态
                    二级缓存:无属性注入的对象
                    三级缓存:代理工厂



        4..初始化
            aware
                BeanNameAware
                BeanFacroryAware
                ApplicationContextAware
                    获取ApplicationContext容器


            Init-Method
                BeanPostProcessor(AOP借助它构建代理对象)
                    PostProcessorBeforeInitialization

                InitializingBean类
                    afterPropertiesSet方法

                BeanPostProcessor
                    PostProcessorAfterInitialization(顺序)



        5.销毁
            disposableBean接口
            destroy-method方法



springMvc
    springmvc请求过程
        1.用户发出请求,请求被web容器拦截
        2.web容器将请求发送给DispatcherServlet,DispatcherServlet作为整个SpringMVC的入口
        3.DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,根据用户的请求的URL地址,找到具体的处理器
        4.HandlerMapping处理器映射器找到具体的处理器,将请求传递给处理器
        5.处理器执行完操作后,将结果返回给DispatcherServlet;
        6.DispatcherServlet再把处理结果返回给web容器;
        7.web容器将处理结果返回给用户。


springBoot
    springboot自动装配原理
        自动将第三方的bean装载到IOC容器中(约定大于配置的理念)
        1.springbootApplication复合注解
            @EnableAutoConfiguration


    配置文件加载过程
        外部config目录 > 外部同级目录 > jar包内部config目录 > jar包内部同级目录
        只要把配置文件放在jar包的同级目录下,或者放在同级下的config文件夹中,SpringBoot都会去此处读取配置文件
        加载顺序详细
            先加载 JAR 包外的配置文件,再加载 JAR 包内的配置文件(jar包外优先);
            先加载 config 目录内的配置文件,再加载 config 目录外的配置文件;(config目录内优先)
            先加载 config 子目录下的配置文件,再加载 config 目录下的配置文件;
            先加载 appliction-{profile}.properties/yml,再加载application.properties/yml;(后缀application优先)
            先加载 .properties 文件,再加载 .yml 文件。(properties优先)



springCloud
    五大组件
        Zuul网关
        ferign服务调用
        Eureka服务注册与发现
        ribbon负载均衡
        Hystrix——服务熔断


kafka
    消息不丢失
        1.生产端
            1.retry机制
            2.失败回调函数
            3.异步提交信息改为同步提交

        2.borker端
            1.ack=-1机制
            2.cp模型确保


    不重复消费
        消费端
            1.业务消费5分钟触发rebalance机制,增强业务处理能力
            2.偏移量提交超过5秒,触发重新拉取消费偏移量,关闭自动提交改为手动提交


    顺序一致性
        生产端
            1.retry机制下会导致partition数据不一致,所以生产端采用同步接受信息,max.in.flight.requests.per.connection=1

        消费端


Dubbon
    工作原理
        1.生产者和消费者根据 配置信息向注册中心发起注册
        2.生产信息和消费者信息会根据注册中心的订阅关系互相保存信息,消费者会把生产者缓存到本地,同时也会根据注册中心的推送感知生产者信息的变动
        3.消费者生成代理对象根据均衡策略向生产者发起接口调用
        4.生产者通过反序列化数据,然后通过代理对象的接口实现

    负载策略
        1.随机
        2.最小活跃数
        3.一致性哈希
        4.响应时间
        5.权重轮询


ElasticSearch全文搜索引擎
    概念:每个字段都被索引并可被搜索,可以快速存储、搜索、分析海量的数据
    基本概念
        (1)index 索引:索引类似于mysql 中的数据库,Elasticesearch 中的索引是存在数据的地方,包含了一堆有相似结构的文档数据。
        (2)type 类型:类型是用来定义数据结构,可以认为是 mysql 中的一张表,type 是 index 中的一个逻辑数据分类
        (3)document 文档:类似于 MySQL 中的一行,不同之处在于 ES 中的每个文档可以有不同的字段,但是对于通用字段应该具有相同的数据类型,文档是es中的最小数据单元,可以认为一个文档就是一条记录。
        (4)Field 字段:Field是Elasticsearch的最小单位,一个document里面有多个field
        (5)shard 分片:单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。
        (6)replica 副本:任何服务器随时可能故障或宕机,此时 shard 可能会丢失,通过创建 replica 副本,可以在 shard 故障时提供备用服务,保证数据不丢失,另外 replica 还可以提升搜索操作的吞吐量。

    特点
        业务处理采用异步也会导致并行下顺序不一致,可采用同步,将业务处理串行化
        1.集群 cluster:Elasticsearch 的好处就是支持集群,一个集群是由一个或多个节点组织在一起的。共同拥有整个数据,一起提供索引和搜索功能(分片提供的)。一个集群会有一个唯一的名称标识,不配置默认集群名为elasticsearch,如需要修改则取 Elasticsearch 的配置文件修改即可。只要节点的集群名称相同,就可以加入同一个集群中。
        2.节点node:一个节点是集群中的一个服务器,作为集群的一部分。
        3.索引 Indices:就是索引库,放索引(数据)的。
        4.类型 type:在一个索引中,你可以定义一种或多种类型。其实也就是分门别类。比如冰箱、电视、洗衣机,都归为电器一类。这里面也是如此,没有强制要求。
        5.文档 document:数据载体,一个文档是一个可被索引的基础信息单元。(json格式的数据)
        6.分片和复制:一个索引可以存储超出单个节点硬件限制的大量数据。当索引(数据)过多过大时,可以通过分片将索引分成很多份,效率就能够提高。而复制也就是备份,起一个修复的作用。
        7.映射 mapping:其实也就是做限制的,拿数据库举例,数据库中数据表的字段是不是有数据类型的限制,比如 varchar、int、date类型等,elasticsearch中也就类型的限制,同样也是对字段进行限制。其不仅可以限制数据类型,而且还可以设置指定的分析器、默认值、是否被索引等等。。
        初始缺点:elasticsearch搜索中文,可能并不会有你如期的效果需要IKAnalyzer

    常用API
        1.QueryBuilders.matchAllQuery():查询全部
        2.QueryBuilders.queryStringQuery(keyword):通过关键字查询
        3.QueryBuilders.termQuery("columns","property"):根据词条查询,第一个参数也就是字段名,第二个参数其实就是要查询的 “词条”
        4.QueryBuilders.idsQuery("type").addIds("_id","_id",...,"_id"):根据_id查询,根据指定的type(表)查询符合索引id的数据,索引id在es服务图形界面上是 _id的形式
        5.QueryBuilders.wildcardQuery("columns","value*"):模糊查询:使用通配符查询,单字符通配符?,多字符通配符*,根据查询的词在对应的columns(字段)做查询。

    关键技术
        倒排索引
            倒排索引是 关键词到文档 ID 的映射

        倒排表压缩算法(FOR)
            根据差值减少字节空间

实战经验
线上错误排查
1. top找出内存高消耗进程 id
2. top hp id 找具体进程看高消耗线程
3.jstack 线程id 转文件
4.vim查看文件 通过/线程id转16进制数据 搜索到具体代码