diff --git "a/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240708-Token.md" "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240708-Token.md" new file mode 100644 index 0000000000000000000000000000000000000000..fbcbc9d9d8763e8587aac38474b20c6dedee255a --- /dev/null +++ "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240708-Token.md" @@ -0,0 +1,22 @@ +### Token +``` +1.简单的token组成 +uid:用户唯一的身份标识 +time:当前时间的时间戳 +sign:签名,token 的前几位以哈希算法压缩成的一定长度的十六进制字符串 +2.Access Token +客户端使用用户名跟密码请求登录 +服务端收到请求,去验证用户名与密码 +验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端 +客户端收到 token 以后,会把它存储起来,比如放在 localStorage 里 +户端每次发起请求的时候需要把 token 放到请求的 Header 里传给服务端 +服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据 +3.Refresh Token +专用于刷新 access token 的 token。如果没有 refresh token,也可以刷新 access token,但每次刷新都要用户输入登录用户名与密码,会很麻烦。有了 refresh token,可以减少这个麻烦,客户端直接用 refresh token 去更新 access token,无需用户进行额外的操作。 +Access Token 的有效期比较短,当 Acesss Token 由于过期而失效时,使用 Refresh Token 就可以获取到新的 Token,如果 Refresh Token 也失效了,用户就只能重新登录了。 +Refresh Token 及过期时间是存储在服务器的数据库中,只有在申请新的 Acesss Token 时才会验证,不会对业务接口响应时间造成影响,也不需要向 Session 一样一直保持在内存中以应对大量的请求 +4.Toke和Session的区别 +Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息 +Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重复攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态 +如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了 +``` \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240709-\351\233\252\350\212\261\347\256\227\346\263\225.md" "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240709-\351\233\252\350\212\261\347\256\227\346\263\225.md" new file mode 100644 index 0000000000000000000000000000000000000000..39bcdfda7fc711c90fa26aa1ad1febefd9b9f460 --- /dev/null +++ "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240709-\351\233\252\350\212\261\347\256\227\346\263\225.md" @@ -0,0 +1,36 @@ +#### 雪花算法 +``` +1.背景 +分布式高并发的环境下,最常见的就是每年双十一的十二点,大量用户同时抢购同一商品,毫秒级的时间下可能生成数万个订单,此时确保生成订单ID的唯一性变得至关重要。此外,在秒杀环境下,不仅要保障ID唯一性、还得确保ID生成的优先度,先抢购到的要优先创建。 + +2.原理 +雪花算法(snowflake)最早是twitter内部使用分布式环境下的唯一ID生成算法。 + +雪花算法使用64位long类型的数据存储id + +0 - 0000000000 0000000000 0000000000 0000000000 0 - 0000000000 - 000000000000 + +符号位 时间戳 机器码 序列号 + +最高位表示符号位,其中0代表整数,1代表负数,而id一般都是正数,所以最高位为0。 + +41位存储毫秒级时间戳,这个时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截) * 得到的值),这里的的开始时间截,一般是我们的ID生成器开始使用的时间,一般为项目创建时间,就是下面实现中代码的twepoch 属性,生成器根据时间戳插值进行初次尝试创建ID。 + +10位存储机器码,最多支持1024台机器,当并发量非常高,同时有多个请求在同一毫秒到达,可以根据机器码进行第二次生成。机器码可以根据实际需求进行二次划分,比如两个机房操作可以一个机房分配5位机器码。 + +12位存储序列号,当同一毫秒有多个请求访问到了同一台机器后,此时序列号就派上了用场,为这些请求进行第三次创建,最多每毫秒每台机器产生2的12次方也就是4096个id,满足了大部分场景的需求。 + +总的来说雪花算法有以下几个优点: + +能满足高并发分布式系统环境下ID不重复 +基于时间戳,可以保证基本有序递增 +不依赖第三方的库或者中间件 +生成效率极高 +ps:在Web开发中需要跟js打交道,而js支持最大的整型范围为53位,超过这个范围就会丢失精度,53之内可以直接由js读取,超过53位就需要转换成字符串才能保证js处理正确。53位存储的话,32位存储秒级时间戳,5位存储机器码,16位存储序列化,这样每台机器每秒可以生产65536个不重复的id。 + +3.实现 +雪花算法的实现严重依赖时间,因此如果发现时间回退需要抛出异常。 + +package com.example.springbootmybatis.controller; + +``` \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240710-ABP.md" "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240710-ABP.md" new file mode 100644 index 0000000000000000000000000000000000000000..4cd534551ca09336cec08b0a742274b4b2453c3a --- /dev/null +++ "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240710-ABP.md" @@ -0,0 +1,46 @@ +####一、什么是ABP +``` +ABP(ASP .NET Boilerplate Project)是基于DDD的经典分层架构思想 +基于领域驱动的理念来构架整个架构,其中领域驱动包含的概念有: +域 +子域 +聚合 +聚合根 +领域模型 +值对象 +通用仓储接口(底层:贴近数据库) +领域模型仓储接口 +领域服务接口 +应用服务接口 +API服务接口(高层:贴近用户) +领域事件 +大脑风暴 +事件风暴 领域模型:一些不涉及其他对象(不是指其他类型,是指对象实例)的业务操作,放在领域模型(即Domain) +具体层分析 +通用仓储接口:通用的仓储接口,其实现放在基础设施层、单独的一层ORM工具层 +领域模型仓储接口:领域独有的一些业务,可以写成领域模型接口,其实现放在Domain +领域服务接口:涉及到多个领域实体的业务和操作,放在领域服务 +应用服务接口:应用服务其实就是对领域模型业务和领域服务业务进行编排的一个层,比较薄 +API服务接口:接受参数,最多做一些数据验证工作 +单元测试层Tests:提供应用层对象的模拟测试,其中测试的数据库使用的是EntityFramework的内存数据库,不影响实际数据库内容 +``` + +#### ABP框架的特点 +``` +依赖注入:这个部分使用Castle来实现依赖注入 +Repository仓储模式 +身份验证与授权管理 +数据有效性验证 +审计日志记录 +Unit Of Work工作单元模式 +异常处理 +日志记录 +多语言/本地化支持 +AutoMapping自动映射:实现领域对象和DTo对象的属性映射 +动态WebAPI层 +多租户支持 +软删除支持 +系统设置存取管理(系统级、租户级、用户级,作用范围自动管理) +领域事件 +模块以及模块的依赖关系实现插件化的模块处理 +``` \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240711-\346\265\213\350\257\225.md" "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240711-\346\265\213\350\257\225.md" new file mode 100644 index 0000000000000000000000000000000000000000..6d0025f145de4dd1988e9c789b6f4070cce64eda --- /dev/null +++ "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240711-\346\265\213\350\257\225.md" @@ -0,0 +1,22 @@ +#### 什么是测试 +``` +测试是软件生命周期中一个非常重要的阶段,在应用程序的开发过程中,为了确保它的功能与预期一致,必须对其进行测试 +帮助开发员改正系统中所存在的缺陷,提高软件的可靠性 +测试应该覆盖到软件的所有功能,全面、细致的测试会在很大程度上节省软件开发的成本 +``` +#### 二、测试的类型 +``` +根据不同的维度,可以把测试方法分为不同的类型 + +从结构的透明性方式,分为白盒测试、黑盒测试和灰盒测试 +白盒测试(结构测试):在已知程序的内部逻辑前提下,对程序内部结构进行验证 +黑盒测试(功能测试):将软件视为“黑盒”,在对程序内部实现未知的前提下,按照需求和预期结果对程序的功能进行测试 +灰盒测试:介于二者之间,在已知程序内部逻辑的前提下,对软件进行功能测试 +从测试执行方式,分为手工测试和自动化测试 +手工测试:要求测试人员与最终使用软件的用户一样,对软件功能进行实际操作并验证 +自动化测试:通过专业的测试软件、测试脚本騞自动化测试用例对软件进行测试 +从测试所涉及的层次,分为单元测试、集成测试和系统测试 +单元测试:验证代码段(如方法或函数)功能的测试,通常由开发人员编写相应的测试方法,以验证代码执行后与预期结果是否一致 +集成测试:用于验证具有依赖关系的多个模块或组件是否能够正常工作 +系统测试:对整个系统进行全面测试 +``` \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240712-antdv\344\275\277\347\224\250.md" "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240712-antdv\344\275\277\347\224\250.md" new file mode 100644 index 0000000000000000000000000000000000000000..281fc66304368e5ef5d1102901a57e43f21c33de --- /dev/null +++ "b/\347\216\213\345\256\235sen/\347\254\224\350\256\260/20240712-antdv\344\275\277\347\224\250.md" @@ -0,0 +1,55 @@ +#### 引入 ant-design-vue +``` +1.新建项目 +2.使用组件 +1. 安装 +npm i --save ant-design-vue@4.x +2. 注册 +全局完整注册 + import { createApp } from 'vue'; + import App from './App'; + // 以下完整引入antdv + import Antd from 'ant-design-vue'; + import 'ant-design-vue/dist/reset.css'; + + let app = createApp(App); + + app.use(Antd).mount('#app'); + // 样式文件需要单独引入 +全局部分注册 + import { createApp } from 'vue'; + import { Button, message } from 'ant-design-vue'; + import App from './App'; + + let app = createApp(App); + + /* 会自动注册 Button 下的子组件, 例如 Button.Group */ + app.use(Button).mount('#app'); + + app.config.globalProperties.$message = message; +局部组件 需要分别注册组件子组件,如 Button、ButtonGroup,并且注册后仅在当前组件中有效 + // 选项式写法 + + + // 组合式写法 + + + +``` \ No newline at end of file