• 面试题汇总


    1、JPA  Hibernate 与mybatis关系

      JPA: 是什么:

      JPA(java persistence api)是sun制定的orm规范,不是具体的框架。我们知道JPA的作用就是通过对象操作数据库的,不用编写sql语句

      市场上的主流的JPA框架(实现者)有: 

      Hibernate   springdata-jpa是基于hibernate进行封装的。

      mybatis是一个不完整的orm框架,灵活性较高。

    2、Mysql 数据类型,常用函数。

      mysql常用的数据类型

    • 文本  ,包含char()   varchar()   TINYTEXT() MIDEUMNTEXT(), longTEXT,BLOB,LONGBLOB,ENUMSET等文本型,包含二进制数据。
    • 数字型:TINYINT(size) SMALLINT(size) MEDIUMINT(size) INT(size) BIGINT(size) FLOAT(size,d) DOUBLE(size,d) DECIMAL(size,d)(decimal采用字符串存贮,小数位固定),这些整数类型拥有额外的选项 UNSIGNED。通常,整数可以是负数或正数。如果添加 UNSIGNED 属性,那么范围将从 0 开始,而不是某个负数
    • 日期时间类型:DATE() DATETIME() TIMESTAMP() TIME() YEAR()  datetime 9999   timestamp 2038,存储的是从1970年起的ms数

      常用函数分为标量函数和聚合函数

      AVG() 求平均值   ;Count()计算行数;   First(column) 返回字段中第一个值,可以使用order by排序。  Last()最后一个。 Max()最大值  MIN()最小值。MIN()MAX()用于文本序列时,可以获得按字母顺序排列的最高值或最低值。SUM()返回总值。

      UCASE() LCASE()大小写转换。 MID()用于提取字符串                 LEN() ROUND() NOW()  

    DATE_FORMAT(date,format) 日期格式化
    SELECT MID(City,1,3) as SmallCity FROM Persons

      我们也可以对一个以上的列应用 GROUP BY 语句,就像这样:

      SELECT Customer,OrderDate,SUM(OrderPrice) FROM Orders GROUP BY Customer,OrderDate
    where 无法和group by一起使用。
    SELECT Customer,SUM(OrderPrice) FROM Orders
    WHERE Customer='Bush' OR Customer='Adams'
    GROUP BY Customer
    HAVING SUM(OrderPrice)>1500

      count(1) count(*) count(column),count(distinct column)区别: 

        

           Myisam中存储了表的总行数,count(*) 会很快返回,innodb没有存贮,但有优化。

    3、mysql 索引,数据结构,索引失效条件,索引命中

      https://blog.csdn.net/qq_36381855/article/details/80011876

      MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。

    目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构,在本文的下一节会结合存储器原理及计算机存取原理讨论为什么B-Tree和B+Tree在被如此广泛用于索引,这一节先单纯从数据结构角度描述它们

    为了描述B-Tree,首先定义一条数据记录为一个二元组[key, data],key为记录的键值,对于不同数据记录,key是互不相同的;data为数据记录除key外的数据。那么B-Tree是满足下列条件的数据结构:

      1. d为大于1的一个正整数,称为B-Tree的度。
      2. h为一个正整数,称为B-Tree的高度。
      3. 每个非叶子节点由n-1个key和n个指针组成,其中d<=n<=2d。
      4. 每个叶子节点最少包含一个key和两个指针,最多包含2d-1个key和2d个指针,叶节点的指针均为null 。
      5. 所有叶节点具有相同的深度,等于树高h。
      6. key和指针互相间隔,节点两端是指针。
      7. 一个节点中的key从左到右非递减排列。
      8. 所有节点组成树结构。
      9. 每个指针要么为null,要么指向另外一个节点。
      10. 如果某个指针在节点node最左边且不为null,则其指向节点的所有key小于v(key1),其中v(key1)为node的第一个key的值。
      11. 如果某个指针在节点node最右边且不为null,则其指向节点的所有key大于v(keym),其中v(keym)为node的最后一个key的值。
      12. 如果某个指针在节点node的左右相邻key分别是keyi和keyi+1且不为null,则其指向节点的所有key小于v(keyi+1)且大于v(keyi)。

      

    B-Tree有许多变种,其中最常见的是B+Tree,例如MySQL就普遍使用B+Tree实现其索引结构。

            与B-Tree相比,B+Tree有以下不同点:

                    1、每个节点的指针上限为2d而不是2d+1。

                    2、内节点不存储data,只存储key;叶子节点不存储指针。

     B-/+Tree索引的性能分析

            到这里终于可以分析B-/+Tree索引的性能了。(主要有两方面:渐进复杂度、局部性访问)

            上文说过一般使用磁盘I/O次数评价索引结构的优劣。先从B-Tree分析,根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:

                    1、每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。

                    2、B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。

            综上所述,用B-Tree作为索引结构效率是非常高的。

            而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。

            上文还说过,B+Tree更适合外存索引,原因和内节点出度d有关。从上面分析可以看到,d越大索引的性能越好,而出度的上限取决于节点内key和data的大小:

            dmax = floor(pagesize / (keysize + datasize + pointsize)) (pagesize – dmax >= pointsize)

            或

            dmax = floor(pagesize / (keysize + datasize + pointsize)) - 1 (pagesize – dmax < pointsize)

            floor表示向下取整。由于B+Tree内节点去掉了data域,因此可以拥有更大的出度,拥有更好的性能。

            这一章从理论角度讨论了与索引相关的数据结构与算法问题,下一章将讨论B+Tree是如何具体实现为MySQL中索引,同时将结合MyISAM和InnDB存储引擎介绍非聚集索引和聚集索引两种不同的索引实现形式。

    在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。

    第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引.叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。 第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录

     MySQL的优化主要分为结构优化(Scheme optimization)和查询优化(Query optimization)。本章讨论的高性能索引策略主要属于结构优化范畴

    最左前缀原理与相关优化

      很明显,当按照索引中所有列进行精确匹配(这里精确匹配指“=”或“IN”匹配)时,索引可以被用到。这里有一点需要注意,理论上索引对顺序是敏感的,但是由于MySQL的查询优化器会自动调整where子句的条件顺序以使用适合的索引

    当查询条件精确匹配索引的左边连续一个或几个列时,如<emp_no>或<emp_no, title>,索引可以被用到,但是只能用到一部分,即条件所组成的最左前缀。上面的查询从分析结果看用到了PRIMARY索引,但是key_len为4,说明只用到了索引的第一列前缀

    此时索引使用情况和情况二相同,因为title未提供,所以查询只用到了索引的第一列,而后面的from_date虽然也在索引中,但是由于title不存在而无法和左前缀连接

    可以考虑用“IN”来填补这个“坑”从而形成最左前缀:

            EXPLAIN SELECT * FROM employees.titles
            WHERE emp_no='10001'
            AND title IN ('Senior Engineer', 'Staff', 'Engineer', 'Senior Staff', 'Assistant Engineer', 'Technique Leader', 'Manager')
            AND from_date='1986-06-26';

    范围列可以用到索引(必须是最左前缀),但是范围列后面的列无法用到索引。同时,索引最多用于一个范围列,因此如果查询条件中有两个范围列则无法全用到索引。

    很不幸,如果查询条件中含有函数或表达式,则MySQL不会为这列使用索引(虽然某些在数学意义上可以使用)。例如:

            EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10001' ANDleft(title, 6)='Senior'

    索引选择性与前缀索引

            既然索引可以加快查询速度,那么是不是只要是查询语句需要,就建上索引?答案是否定的。因为索引虽然加快了查询速度,但索引也是有代价的:索引文件本身要 消耗存储空间 ,同时索引会 加重插入、删除和修改记录时的负担 ,另外,MySQL在运行时也要 消耗资源维护索引 ,因此索引并不是越多越好。一般两种情况下不建议建索引

    第一种情况是表记录比较少,例如一两千条甚至只有几百条记录的表,没必要建索引,让查询做全表扫描就好了。至于多少条记录才算多,这个个人有个人的看法,我个人的经验是以2000作为分界线,记录数不超过 2000可以考虑不建索引,超过2000条可以酌情考虑索引

    索引的选择性是指,不重复的索引值和数据表的记录总数(T)的比值,范围从1/T 到 1 之间。

      索引的选择性越高则查询效率越高,因为选择性高的索引可以让 MySQL 在查询时过滤掉更多的行。

      唯一索引的选择性是 1,这是最好的索引选择性,性能也是最好的。

      索引的选择性较低时不建议建立索引。

    一种与索引选择性有关的索引优化策略叫做前缀索引,就是用列的前缀代替整个列作为索引key,当前缀长度合适时,可以做到既使得前缀索引的选择性接近全列索引,同时因为索引key变短而减少了索引文件的大小和维护开销。即使用某一个字段的前几个字符建立索引,可以减小索引大小,同时索引选择性不会太低,对联合索引时比较好用。

    mysql索引类型

    MySQL目前主要有以下几种索引类型:(B-tree索引、hash索引、全文索引)
    1.普通索引
    2.唯一索引
    3.主键索引
    4.组合索引
    5.全文索引

    CREATE TABLE table_name[col_name data type]
    [unique|fulltext][index|key][index_name](col_name[length])[asc|desc]

    1.unique|fulltext为可选参数,分别表示唯一索引、全文索引

    1.普通索引
    是最基本的索引,它没有任何限制

    2.唯一索引
    与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

    3.主键索引
    是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引

    4.组合索引
    指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合

    5.全文索引
    主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like。它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。

    使用索引时,有以下一些技巧和注意事项:
    1.索引不会包含有null值的列
    只要列中包含有null值都将不会被包含在索引中,复合索引中只要有一列含有null值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为null。
    2.使用短索引
    对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
    3.索引列排序
    查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
    4.like语句操作
    一般情况下不推荐使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
    5.不要在列上进行运算
    这将导致索引失效而进行全表扫描,例如

    SELECT * FROM table_name WHERE YEAR(column_name)<2017;

    6.不使用not in和<>操作

    https://www.cnblogs.com/luyucheng/p/6289714.html

    mysql优化:https://www.cnblogs.com/luyucheng/p/6323477.html

    mysql锁并发:

    由于MyISAM存储引擎使用的锁定机制完全是由MySQL提供的表级锁定实现,所以下面我们将以MyISAM存储引擎作为示例存储引擎。
    1.MySQL表级锁的锁模式
    MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。锁模式的兼容性:
    对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;
    对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作;
    MyISAM表的读操作与写操作之间,以及写操作之间是串行的。当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作。其他线程的读、写操作都会等待,直到锁被释放为止。
    2.如何加表锁
    MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。

    对于MyISAM存储引擎,虽然使用表级锁定在锁定实现的过程中比实现行级锁定或者页级锁所带来的附加成本都要小,锁定本身所消耗的资源也是最少。但是由于锁定的颗粒度比较到,所以造成锁定资源的争用情况也会比其他的锁定级别都要多,从而在较大程度上会降低并发处理能力。所以,在优化MyISAM存储引擎锁定问题的时候,最关键的就是如何让其提高并发度。由于锁定级别是不可能改变的了,所以我们首先需要尽可能让锁定的时间变短,然后就是让可能并发进行的操作尽可能的并发。

    InnoDB的主键选择与插入优化

            在使用InnoDB存储引擎时,如果没有特别的需要,请永远使用一个与业务无关的自增字段作为主键。

     这样就会形成一个紧凑的索引结构,近似 顺序填满 。由于每次插入时也 不需要移动已有数据 ,因此效率很高,也不会增加很多开销在维护索引上。

            如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置:

    此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了 大量的碎片 ,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面

    4、MySQL myisam、innodb引擎区别

      1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;

      2. InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;

      3. InnoDB是聚集索引,使用B+Tree作为索引结构,必须要有主键,通过主键索引效率很高  MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的

      4. InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快。因为InnoDB的事务特性,在同一时刻表中的行数对于不同的事务而言是不一样的,因此count统计会计算对于当前事务而言可以统计到的行数,而不是将总行数储存起来方便快速查询

      5. Innodb不支持全文索引,而MyISAM支持全文索引,在涉及全文索引领域的查询效率上MyISAM速度更快高;PS:5.7以后的InnoDB支持全文索引了 ngram

      6. MyISAM表格可以被压缩后进行查询操作

      7. InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁  InnoDB的行锁是实现在索引上的,而不是锁在物理行记录上。潜台词是,如果访问没有命中索引,也无法使用行锁,将要退化为表锁。

    例如:
        t_user(uid, uname, age, sex) innodb;
        uid PK
        无其他索引
        update t_user set age=10 where uid=1;             命中索引,行锁。
        update t_user set age=10 where uid != 1;           未命中索引,表锁。
        update t_user set age=10 where name='chackca';    无索引,表锁。

      8、InnoDB表必须有唯一索引(如主键)(用户没有指定的话会自己找/生产一个隐藏列Row_id来充当默认主键),而Myisam可以没有

      9、Innodb存储文件有frm、ibd,而Myisam是frm、MYD、MYI

              Innodb:frm是表定义文件,ibd是数据文件

              Myisam:frm是表定义文件,myd是数据文件,myi是索引文件

    5、mysql 优化,limit优化。

    6、mysql建表规范。三范式

       目前关系型数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。一般来说,数据库只需要满足第三范式就行了。

    第一范式:保证每列的原子性

    第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库满足了第一范式。

    第一范式需要根据系统的实际需求来定,比如有一张用户信息表:

    一般来说"住址"设计成一个字段就行,但是如果经常访问"住址"中城市的部分,那么就非要将"住址"这个属性重新拆分为"省份"、"城市"、"地址"等多个部分进行存储,这样在对"住址"中某一部分进行操作的时候将非常方便。这么设计才算满足了数据库的第一范式,修改之后的表结构如图:

    第二范式:保证一张表只描述一件事情

    这是通俗的说法,用第二范式的定义描述第二范式,说的是在满足第一范式的基础上,数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖,也即所有非关键字段都完全依赖于任一组候选关键字

    第三范式(3NF)属性不依赖于其它非主属性    属性直接依赖于主键

    https://blog.csdn.net/wenco1/article/details/88077279

    7、微服务与分布式有什么区别。微服务5大组件。

    8、spring 常用的设计模式,23种设计模式。

    9、docker使用、基本原理

    10、springdata 产品

    11、redis双删,读写一致性。

     修改前删除,修改后等待一段时间再次删除。保证写入过程中有线程读取在写入缓存后可以将这个脏数据删除。

    12、表单重复提交,接口幂等性。

     防止重复提交:1 js提交后隐藏按钮;2、数据库设置列为唯一;3、使用session判断提交的数据是否重复。

    第三种情况:表单提交成功以后,直接点击浏览器上回退按钮,不刷新页面,然后点击提交按钮再次提交表单。

    -根本原因:因为服务器在处理请求时,不会检查是否为重复提交的请求。

    -解决方案:
    使用一个token的机制
    - token就是令牌的意思
    - 服务器在处理请求之前先来检查浏览器的token
    - token由服务器来创建,并交给浏览器,浏览器在向服务器发送请求时需要带着这个token
    - 服务器处理请求前检查token是否正确,如果正确,则正常处理,否则返回一个错误页面
    - 服务器所创建的token只能使用一次
    - token一般使用一个唯一的标识

    -在jsp页面,获取uuid作为token

    - UUID:32位字符串,通常作为对象或者表的唯一标识,根据机器码和时间戳(从1970年1月1日开始到现在)生成。

    接口幂等性:

    接口的幂等性 - fy_qxl - 博客园 (cnblogs.com)

    13、数据库优化方式。

     结构优化,查询优化。

    14、innoDB必须有主键吗。

     必须有,没有会创建一个。

    15、mybatis 的执行器,拦截器,缓存,批处理,foreach,懒加载,嵌套select查询。

    16、分布式事务,transactional失效条件。

      什么是事务,一组操作要么同时成功,要么同时失败。为了防止出现脏数据。特性:ACID  .

      spring事务:

    要保证事务的ACID特性,spring给事务定义了6个属性,对应于声明式事务注解(org.springframework.transaction.annotation.Transactional)@Transactional(key1=*,key2=*...)

    • 事务名称:用户可手动指定事务的名称,当多个事务的时候,可区分使用哪个事务。对应注解中的属性value、transactionManager
    • 隔离级别:  为了解决数据库容易出现的问题,分级加锁处理策略。 对应注解中的属性isolation
    • 超时时间:  定义一个事务执行过程多久算超时,以便超时后回滚。可以防止长期运行的事务占用资源.对应注解中的属性timeout
    • 是否只读:表示这个事务只读取数据但不更新数据, 这样可以帮助数据库引擎优化事务.对应注解中的属性readOnly
    • 传播机制:  对事务的传播特性进行定义,共有7种类型。对应注解中的属性propagation
    • 回滚机制:定义遇到异常时回滚策略。对应注解中的属性rollbackFor、noRollbackFor、rollbackForClassName、noRollbackForClassName

      传播行为:7种

      隔离行为:读未提交,读已提交,可重复读,序列化。

    https://www.cnblogs.com/dennyzhangdd/p/9549535.html   !!!!

    17、使用session及Token的区别,

    session的状态保持及弊端

    当用户第一次通过浏览器使用用户名和密码访问服务器时,服务器会验证用户数据,验证成功后在服务器端写入session数据,向客户端浏览器返回sessionid,浏览器将sessionid保存在cookie中,当用户再次访问服务器时,会携带sessionid,服务器会拿着sessionid从数据库获取session数据,然后进行用户信息查询,查询到,就会将查询到的用户信息返回,从而实现状态保持。

    结合shiro使用之后,shiro会自动将用户信息存储在shiro的Session中,取出Session中信息则可以通过

    User user = (User) SecurityUtils.getSubject().getPrincipal()获取!

    弊端:

    1、服务器压力增大

    通常session是存储在内存中的,每个用户通过认证之后都会将session数据保存在服务器的内存中,而当用户量增大时,服务器的压力增大。

    2、CSRF跨站伪造请求攻击

    session是基于cookie进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

    3、扩展性不强

    如果将来搭建了多个服务器,虽然每个服务器都执行的是同样的业务逻辑,但是session数据是保存在内存中的(不是共享的),用户第一次访问的是服务器1,当用户再次请求时可能访问的是另外一台服务器2,服务器2获取不到session信息,就判定用户没有登陆过。

    3.2 token认证机制

    token与session的不同主要在①认证成功后,会对当前用户数据进行加密,生成一个加密字符串token,返还给客户端(服务器端并不进行保存)

    ②浏览器会将接收到的token值存储在Local Storage中,(通过js代码写入Local Storage,通过js获取,并不会像cookie一样自动携带)

    ③再次访问时服务器端对token值的处理:服务器对浏览器传来的token值进行解密,解密完成后进行用户数据的查询,如果查询成功,则通过认证,实现状态保持,所以,即时有了多台服务器,服务器也只是做了token的解密和用户数据的查询,它不需要在服务端去保留用户的认证信息或者会话信息,这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利,解决了session扩展性的弊端。

    认证原理

    1.用户登陆之后,使用密码对账号进行签名生成并返回token并设置过期时间;

    2.将token保存到本地,并且每次发送请求时都在header上携带token。

    3.shiro过滤器拦截到请求并获取header中的token,并提交到自定义realm的doGetAuthenticationInfo方法。

    4.通过jwt解码获取token中的用户名,从数据库中查询到密码之后根据密码生成jwt效验器并对token进行验证。

    Shiro的关注点

      • SecurityManager,可以理解成控制中心,所有请求最终基本上都通过它来代理转发,一般我们程序中不需要直接跟他打交道。
      • Subject ,请求主体。比如登录用户,比如一个被授权的app。在程序中任何地方都可以通过SecurityUtils.getSubject()获取到当前的subject。subject中可以获取到Principal,这个是subject的标识,比如登陆用户的用户名或者id等,shiro不对值做限制。但是在登录和授权过程中,程序需要通过principal来识别唯一的用户。
      • Realm,这个实在不知道怎么翻译合适。通俗一点理解就是realm可以访问安全相关数据,提供统一的数据封装来给上层做数据校验。shiro的建议是每种数据源定义一个realm,比如用户数据存在数据库可以使用JdbcRealm;存在属性配置文件可以使用PropertiesRealm。一般我们使用shiro都使用自定义的realm。
        当有多个realm存在的时候,shiro在做用户校验的时候会按照定义的策略来决定认证是否通过,shiro提供的可选策略有一个成功或者所有都成功等。
        一个realm对应了一个CredentialsMatcher,用来做用户提交认证信息和realm获取得用户信息做比对,shiro已经提供了常用的比如用户密码和存储的Hash后的密码的对比。

    https://blog.csdn.net/weixin_43495390/article/details/86533482

    mysql主键插入问题

    为什么 MySQL 的自增主键不单调也不连续 - 51CTO.COM

    自增主键插入后删除再重启,可能主键会与之前删除的一致。

    myisam与innodb8.0不会出现,其余版本容易出现。

    Mysql enum类型

    mysql中enum类型理解 - 那啥快看 - 博客园 (cnblogs.com)

    mysql可以定义enum类型。

    还可以定义set类型。

    MySQL中数据类型介绍 - myxlp - 博客园 (cnblogs.com)

  • 相关阅读:
    Activity的singleTask启动模式
    蓝图Tips
    UE4 C++ Tips
    UE4的抛物线
    透明材质
    在UE4 C++构造函数里的常规操作
    UE4的反射关键词
    UE4字符串的各种转换
    UE4Launch遇到的问题
    在UE4C++中的宏
  • 原文地址:https://www.cnblogs.com/baldprogrammer/p/13975254.html
Copyright © 2020-2023  润新知