非对称加密
非对称加密非对称加密有两个密钥:公钥和私钥。
特点:如果用公钥进行加密,只有用对应的私钥才能解密;如果用私钥进行加密,只有用对应的公钥才能解密。
最有名的非对称加密算法:RSA 算法
主要的应用场景:
加密数据
数字签名
身份认证
加密通信双方把自己的公钥发送给对方,发送方发送消息时使用自己的私钥加密,接收方使用对应的公钥解密。
真实的应用场景
服务端把公钥发送给用户,用户使用公钥加密,发送密文给服务端,服务端通过私钥解密。
HTTPS 中,只在建立安全连接阶段使用非对称 RSA 加密,用于安全的协商一个对称加密密钥,之后全程使用对称加密通信,这是由于非对称加密效率低。
数字签名用于校验身份。
由于每个人的私钥是保密且独一无二的,这就非常适合用来作为自己的身份ID。自己使用自己的私钥,别人通过公钥验签。
签名:正文 —-> hash值 —-> 使用私钥加密hash值 —-> 生成签名
验签:
签名 —-> 使用公钥解密签名 —-> hash值
正文 —-> hash值
判断两个 hash 值是否一致,一致就表示正文没有被修改,且是公钥对应 ...
Vue3 Hooks
Vue3 Hooks灵感借鉴自 React Hooks,但底层原理不同,Vue 基于自身细粒度的响应性系统。
hook:钩子
hooks 是一个函数,被称为“钩子函数”,该函数会和 Vue 组件的特定 API 配合使用,Vue 会在特定时机调用该函数。
特定的时机指:
生命周期函数执行时
某个值改变时
hooks 的优点:
便于代码复用
便于整个逻辑的封装
hooks 相当于组件级别的逻辑封装,比 Vue2 中的 mixins 更加方便好用。
自定义 hooks 函数约定:hook 文件以 use 开头。
官方示例,该函数可以很方便的给页面添加鼠标监听逻辑。
创建 mouse.js 文件
123456789101112131415161718192021// 导入Vue组件级相关APIimport { ref, onMounted, onUnmounted } from 'vue';// hook函数命名以use开头export function useMouse() { // 响应式数据 const x ...
Vue3相对于Vue2的优化
Vue3相对于Vue2的优化对于开发者影响最大的还是 Composition API,代码写法上更加灵活。
(1)项目架构优化
Monorepo
分包
(2)类型检测更严格Vue3 使用了 TypeScript,Vue2 使用的是 Flow,Vue1 没有。
(3)性能优化tree-shaking 技术
编译时静态分析出未使用的模块。减小 Vue.js 包体积。
数据劫持
Object.defineProperty():会改变原数据
Proxy:不会改变原数据,代理处理器,可以检测数组
Block tree
vnode 与动态内容的数量相关,之前是与模板规模相关。
diff算法优化
(4)语法优化新增 Composition API,之前是 Options API
便于逻辑聚合
取代 Mixins,逻辑复用
Vue源码概述
Vue源码概述Vue 2.x 的源码就是利用了 Flow 做静态类型检查。
timerFuncVue 在构建时,会初始化一个 timerFunc 函数,该函数会把 flushCallbacks 函数放入异步队列中。
flushCallbacks 函数负责清空在 Vue.nextTick 中定义的批量异步操作。
nextTick 负责收集包装异步函数,添加到 callbacks 数组中,并且触发 timerFunc 函数。
nextTick 就是把一个异步函数加入队列中,等同步方法执行完了立刻执行。
VueVue 函数接收一个 options 参数,执行 _init() 函数。
123function Vue (options) { this._init(options)}
初始化流程
12345678910111213141516171819202122mergeOptions()// 生命周期:确定实例的父实例和根实例initLifecycle(vm)// 初始化实例上定义的自定义事件initEvents(vm)// 解析组件的插槽信息,得到 vm.$sl ...
SpringBoot常用注解
SpringBoot常用注解组件相关@Controller 和 @Service 都派生于 @Component。
SpringBoot 中的组件扫描功能会识别到这些注解。
@Component该注解是万能的注解
通常加在配置类上
@Controller修饰控制器层组件
接收请求,对请求进行分发
可以跳转到模板页面。
而 @RestController 只能返回实体对象,不能跳转到模板页面。
@Service修饰业务层组件
@Repository用于修饰 dao 层组件
专注于系统数据的处理。
依赖注入@Autowired
auto wired:自动联线
根据对象的 类型 自动注入依赖对象
@Resource默认会根据对象的 名称 自动注入依赖对象
123@Autowired@Resource(name = "umsAdminServiceImpl")private UmsAdminService adminService;
@Qualifier当同一个对象有多个实例可以注入时
实例与生命周期@Bean用于修饰方法,标识该方法会创建一个 Bean 实例,并交给 ...
Node.js Buffer
Node.js BufferJavaScript 语言自身只有字符串数据类型,没有二进制数据类型。但在处理像TCP流或文件流时,必须使用到二进制数据。
因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。该缓存区对应 V8 堆内存之外的一块原始内存。
Buffer是典型的JS与C++结合的模块。
在Node启动时就会加载它,并挂载到global全局对象上。
Buffer对象Buffer对象类似于数组,存放的元素为16进制的两位数(00-FF),即0-255,占用8bit,一个字节。
可通过length获得Buffer的长度(字节数)。
Buffer内存分配在C++层面申请内存,在JS中分配内存。
slab分配机制
是一种动态内存管理机制。
slab是一块已申请的固定大小的内存区域。有3种状态:
没有分配
部分分配
完全分配。
Node以8KB为界限区分Buffer是大对象还是小对象。
8KB是每个slab的大小,在JS层面,以8KB为单位进行内存分配。
小Buffer对象分配
预先申请slab,事后分配。
一个slab可以存储多 ...
Node.js内存控制
Node.js内存控制服务器端性能敏感,内存管理的好坏很关键。
V8的垃圾回收机制V8的内存限制单个Node进程只能使用部分内存。
64位系统约1.4G,32位系统约0.7G,这导致Node不能直接操作大内存对象。
原因:
V8引擎主要是服务于浏览器端的
垃圾回收机制的限制
V8的对象分配查看内存使用量:
1process.memoryUsage();
返回值
12345{ rss: 133454, heapTotal: 71000, heapUsed: 33200}
堆内存是动态变化的,不足时会继续申请,直到超过V8限制。
V8的限制是可以放宽的,在Node启动时传递参数:
1234// 单位是MBnode --max-old-space-size=1700 test.js// 单位是KBnode --max-new-space-size=1024 test.js
V8的垃圾回收垃圾回收策略:分代式垃圾回收机制。
没有一种算法可以胜任所有场景,按对象的存活时间分代,匹配不同的回收算法。
内存分代:
新生代:存活时间短的对象,Sca ...
Node.js异步IO
Node.js异步IO异步早就存在于操作系统的底层,通过信号量、消息等方式应用。
与Node的事件驱动、异步IO设计理念比较相近的一个产品是Nginx。
为什么要异步IO原因:Node是面向网络设计的。
网络请求是一个耗时操作,同步网络请求会导致程序处于等待卡死状态,用户体验差。
计算机将组件进行了抽象,分为IO设备和计算设备。
处理一组任务的方案:
单线程串行执行:易于编写,但是性能差。
多线程并发执行:性能一般较好;但多线程开销大,且需要处理锁、状态同步等问题,编写难度大。
Node的方案是:利用单线程避免死锁、同步等问题;利用异步IO让单线程不会阻塞,更好地利用CPU。
异步IO的现状异步IO不是Node首创。
异步/同步和阻塞/非阻塞是两回事。
操作系统内核对于IO只有两种方式:阻塞与非阻塞。
阻塞IO:操作系统处理IO时,会等待IO结束,获得数据后再返回。
非阻塞IO:操作系统启动IO后,立即无数据返回。
操作系统把输入输出设备抽象为文件,在进行IO操作时,通过文件描述符进行管理,先打开文件描述符,在根据文件描述符进行数据的读写。
非阻塞IO返 ...
Node.js网络编程
Node.js网络编程在Web领域,大多数编程语言需要专门的Web服务器容器,如ASP需要IIS服务器,Java需要Tomcat服务器,PHP需要Apache服务器。Node则不需要额外的容器。
Node提供了多个模块:
net:TCP
dgram:UDP
http:HTTP
https:HTTPS
构建TCP服务TCP:传输控制协议。传输层
大多数网络应用是基于TCP搭建的。
创建会话,服务端和客户端分别提供一个套接字,实现连接。
创建TCP服务器端:
12345678910111213141516var net = require('net');var server = net.createServer(function(socket){ socket.on('data', function(data){ // 接收到数据 socket.write('接收到数据:' + data); }); socket.on('end ...
JavaScript寄生式组合继承
JavaScript寄生式组合继承“寄生式组合继承”可以算是引用类型继承的最佳模式,在“组合继承”的基础上进一步优化。
JS中,一个类即一个构造函数。
组合继承父类
12345function Father(){ // 类属性}// 类方法Father.prototype.xxx = function(){}
子类
12345678function Sub(){ // 调用父类构造函数,继承父类属性 Father.call(this);}// 调用父类构造函数,指定原型,继承父类方法Sub.prototype = new Father();// 指定子类的原型为自己,原型与构造函数双向绑定Sub.prototype.constructor = Sub;
寄生式组合继承相对于组合继承,优化的一点是 Sub.prototype = new Father();,不通过new创建原型,而是通过Object.create()创建原型。
Object.create()创建的对象没有构造函数的属性,只有原型。
1234 ...