logo头像
ICQL

tmp

本文于 2058 天之前发表,文中内容可能已经过时。

临时文档

单链表反转
链表中环的检测
两个有序的链表合并
删除链表倒数第 n 个结点
求链表的中间结点

https://blog.csdn.net/qfikh/article/details/103624074

lru
二分查找
堆排序
冒泡
快排排序

系统设计:
https://blog.csdn.net/u013007900/article/details/79008993

https://www.v2ex.com/t/623704#reply86

分布式理论

微服务框架 Spring Cloud 服务发现、熔断、通信。。。

ConcurrentHashMap size方法,1.7 1.8区别

List、Set源码
spring源码
springboot自动装配原理
mybatis源码(备选)

数据结构
算法

kafka

计算机网络
操作系统
计算机系统原理

jvm

es搜索引擎

小打野刀、红宝石/蓝宝石、进化水晶、抵抗鞋、中打野刀、小血书、大血书、时之预言、法穿鞋、辉月/冰心、法穿鞋->虚无法杖

13a2a3a3
13aa23a3

a2a313a3

````

Asciidoc 2 pdf

下载工具:

使用步骤

  • 利用AsciidocFX打开仓库目录
  • 双击打开book.asciidoc
  • 点击右上角转换为html
  • 将生成的”html文件”和”images文件夹”复制到 wkhtmltopdf 软件的 bin 目录下
  • 执行命令 wkhtmltopdf book.html book.pdf 即可转换

架构演变

  • 单机–分布式

  • 集群和分布式:集群是部署同一业务到多台机器,分布式是拆分业务部署到多台服务器

  • tps:Transactions Per Second(每秒传输的事物处理个数)

  • qps:

  • OSI分层模型(已过时):

    • 物理层
    • 链路层
    • 网络层ip
    • 传输层tcp,udp
    • 会话层
    • 表示层
    • 应用层http/https/ftp/pop3等
  • TCP/IP分层模型

    • 物理层
    • 链路层
    • 网络层
    • 传输层
    • 应用层
  • TCP

    • 3次握手协议
    • 4次挥手协议
    • 滑动窗口协议
  • UDP

  • http/https原理

  • 全双工、半双工

  • bio/nio/aio

  • 序列化和反序列化

    • serialVersionUID
    • 默认是java二进制序列化,需要实现Serialize接口
    • json
    • xml
    • transient
    • 浅度克隆/深度克隆:引用类型字段的区别
  • 1.文本文件(ASCII码文件)和二进制文件

    • 存储在磁盘上都是二进制文件
    • 文本文件是某种特殊的二进制文件,只是打开程序用的解码方式不同
    • 常用文本文件编码(基于字符)
      • ASCII 码表:用1个字节表示,2^7=128种符号,最高位是符号位,只有英文字母,英文符号,阿拉伯数字等
      • GB2312 码表:兼容ASCII码表;英文1个字节,中文2个字节,判断符号位为+则是英文字节,第1个字节符号位为-第2个字节符号位为-则这2个字节加起来是中文字符;(2^7-1)*(2^7-1)=16129种符号
      • GBK 码表:兼容GB2312码表,英文1个字节,中文2个字节;判断符号位为+则是英文字节,第1个字节符号位为-第2个字节符号位不限则这2个字节加起来是中文字符;(2^7-1)*(2^8)=32512种符号
      • Big5 码表:台湾
      • Unicode 国际码表;中英文全2个字节
      • UTF8 国际码表;英文1个,中文3个字节

chapter01 计算机系统

  • 信息(数据) = 位(bit) + 上下文
  • C语言的编译过程
  • 指针变量和普通变量区别:指针变量的值是内存地址,普通变量的值是数据值
  • 系统的硬件组成
    • 总线
    • IO设备
    • 主存
    • 处理器

原码、反码、补码

https://zhuanlan.zhihu.com/p/91967268?utm_source=wechat_session

  1. 原码

原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。比如:如果是8位二进制:

[+1]原= 0000 0001

[-1]原= 1000 0001

第一位是符号位,因为第一位是符号位,所以8位二进制数的取值范围就是:(即第一位不表示值,只表示正负。)

[1111 1111 , 0111 1111]

[-127 , 127]

原码是人脑最容易理解和计算的表示方式。

  1. 反码

反码的表示方法是:

正数的反码是其本身;

负数的反码是在其原码的基础上,符号位不变,其余各个位取反。

[+1] = [0000 0001]原= [0000 0001]反

[-1] = [1000 0001]原= [1111 1110]反

可见如果一个反码表示的是负数,人脑无法直观的看出来它的数值。通常要将其转换成原码再计算。

  1. 补码

补码的表示方法是:

正数的补码就是其本身;

负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1。(也即在反码的基础上+1)

[+1] = [0000 0001]原= [0000 0001]反= [0000 0001]补

[-1] = [1000 0001]原= [1111 1110]反= [1111 1111]补

对于负数,补码表示方式也是人脑无法直观看出其数值的。通常也需要转换成原码再计算其数值

密码加密

  • 密码不能以明文存储,应该保存加密后的
    • 常见的加密方法有 SHA 或 MD5,用这两种加密算法 + salt(盐),即原密码 + 一段自定义字符串进行SHA或MD5加密
    • BCrypt:使用的是布鲁斯·施内尔在1993年发布的 Blowfish 加密算法
  • Bcrypt:内部自己实现了随机加盐处理,MD5加密每次加密后的密文其实都是一样的,而Bcrypt每次加密后得到的不一样
    • java使用示例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      //pom依赖
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring‐boot-starter-security</artifactId>
      </dependency>

      //添加spring security依赖后,所有的地址都被spring security所控制
      //只是需要用到BCrypt密码加密的部分
      //所以我们要添加一个配置类,配置为所有地址匿名访问
      @Configuration
      @EnableWebSecurity
      public class SecurityConfig extends WebSecurityConfigurerAdapter{
      @Override
      protected void configure(HttpSecurity http) throws Exception {
      http
      .authorizeRequests()
      .antMatchers("/**").permitAll()
      .anyRequest().authenticated()
      .and().csrf().disable();
      }

      //注入BCryptPasswordEncoder bean
      @Bean
      public BCryptPasswordEncoder bcryptPasswordEncoder(){
      return new BCryptPasswordEncoder();
      }
      }

      //密码加密/校验
      @Autowired
      BCryptPasswordEncoder encoder;
      public void test() {
      String password = "test";
      //密码加密
      String newpassword = encoder.encode(password);

      //密码校验
      boolean isMath = encoder.matches(password,newpassword);
      }

常见的认证机制

  • 1)HTTP Basic Auth:每次请求API时都提供用户的username和password
  • 2)Cookie Auth
    • Cookie认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie对象;通过客户端带上来Cookie对象来与服务器端的session对象匹配来实现状态管理的。默认的,当我们关闭浏览器的时候,cookie会删除。但可以通过修改cookie 的expire time使cookie在一定时间内有效
  • 3)OAuth(比较复杂)
    • OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在某一web服务上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用
  • 4)Token Auth:使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录
    • 相比cookie优势:
      • 支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输
      • 无状态:Token机制在服务端不需要存储session信息
      • 更适用于移动应用:原生 ios和安卓 不支持cookie,必须使用cookie容器
      • CSRF:不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范
      • 性能:token验证快
      • 标准化:如jwt协议

jwt(json web token)

  • JSON Web Token(JWT)是一个非常轻巧的规范,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息
  • JWT组成:一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名
    • 1)头部(Header)
      • 用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等
        1
        2
        3
        4
        5
        //头部指明了签名算法是HS256算法
        {"typ":"JWT","alg":"HS256"}

        //使用 BASE64 编码后得到
        eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
    • 2)载荷(playload)
      • 载荷就是存放有效信息的地方,不建议存储私密信息
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        //1、标准中注册的声明(建议但不强制使用)
        iss: jwt签发者
        sub: jwt所面向的用户
        aud: 接收jwt的一方
        exp: jwt的过期时间,这个过期时间必须要大于签发时间
        nbf: 定义在什么时间之前,该jwt都是不可用的.
        iat: jwt的签发时间
        jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
        //2、公共声明
        //3、私有声明:自定义存储的信息

        {"sub":"1234567890","name":"John Doe","admin":true}
        //使用 BASE64 编码后得到
        eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
    • 3)签名(signature)
      • 签名信息由 header (base64后的),payload (base64后的),secret(盐)组成
        1
        2
        3
        4
        5
        6
        7
        8
        //原理:
        //需要base64加密后的header 和 base64加密后的payload
        //使用.连接组成的字符串
        //然后通过header中声明的 加密方式 进行加盐 secret 组合加密得到 签名
        TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

        //最后 头部.载荷.签名 组成token
        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7Hg
  • java基于jjwt的实现

类似cas的sso实现

  • 实现类似cas的sso单点登录(具体查看https://github.com/icql/Projects 或者 https://git.icql.work/icql-work/Projects ) ,具体路径 /JavaProjects/icql/icql-sample/icql-sample-ssm/ 项目下sso相关内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    /**
    * sso-client
    * login:
    * ----登录检查(session或者redis等其他方式)
    * --------已登录:return
    * --------未登录:请求参数中验证 ticket 是否存在
    * ------------是:请求sso-server(/validate,参数ticket),验证 令牌ticket 是否有效
    * ----------------有效:sso登录通过
    * ----------------无效:删除url ticket参数后的字符串,重定向sso-server(/login,参数service),return
    * ------------否:重定向sso-server(/login,参数service),return
    * logout:
    * ----删除自身登录校验,重定向到sso-server(/logout,参数service),return
    * *****************************************************************************
    * *****************************************************************************
    * sso-server
    * login:(参数service)
    * ----验证全局票据 cookie[ICQLTGC] 是否存在
    * --------是:已经登录过,检查缓存是否存在此TGC
    * ------------是
    * ----------------根据参数service生成唯一令牌ST(ticket)
    * ----------------根据TGC(cookie[ICQLTGC]的值)从缓存中查询 用户信息
    * ----------------缓存[key:唯一令牌ST(ticket),用户信息],设置默认生效时间5分钟
    * ----------------更新 TGC 生效时间
    * ----------------service为空,重定向到/success,不为空重定向到 [service + "?ticket=" + 令牌ST(ticket)] ,return
    * ------------否:未登录,显示sso-server登录页面,传递参数service到页面
    * --------否:未登录,显示sso-server登录页面,传递参数service到页面
    * ----------------发送登录请求login4form(参数:service,username,password),验证用户密码是否正确
    * --------------------成功:将会返回令牌ST(ticket),重定向到 [service + "?ticket=" + 令牌ST(ticket)]
    * --------------------失败:停留在sso-server登录页面
    * login4form:(参数:service,username,password)
    * ----验证参数
    * --------未通过:
    * --------通过
    * ----数据库查询 用户信息user
    * --------未找到:return
    * --------找到
    * ----根据参数service,生成sso-client的唯一令牌ST(ticket)
    * ----根据参数sso-server的域名,生成sso-server的唯一票据TGC
    * ----缓存[key:唯一令牌ST(ticket),用户信息],设置默认生效时间5分钟
    * ----缓存[key:TGC,用户信息],保存登录用户的信息,设置默认生效时间60分钟
    * ----设置sso-server的浏览器cookie(key:ICQLTGC,value:TGC)
    * ----return 唯一令牌ST(ticket)
    * validate:(参数ticket)
    * ----根据ticket从缓存中查询 用户信息
    * --------找到:200,返回用户信息,从缓存中清除 ticket 相关信息(ST令牌只能使用一次)
    * --------未找到:204
    * logout:(参数service)
    * ----验证全局票据 cookie[ICQLTGC] 是否存在
    * --------存在:删除 缓存TGC,删除cookie[ICQLTGC]
    * --------不存在
    * --------service为空,重定向到/logout,不为空重定向到 service ,return
    * register4form:(参数)
    * ----注册页面未实现
    * register4check:(参数)
    * ----
    */
微信打赏

赞赏是不耍流氓的鼓励