- 博客(115)
- 资源 (1)
- 收藏
- 关注
原创 关于软件设计那些事---正交设计
在我们写代码的过程中,往往只考虑功能的实现,很少考虑或者不考虑代码之后的维护程度,但是随着系统愈来愈复杂,即便是智商最为发达的程序员也发现,单一过程的复杂度已经超出他的掌控极限。所以这需要人们在对于比较复杂的模块时,需要对大问题进行分解。本人之前是有看类似的设计相关的书籍,但是还是感觉在实际操作中,没有很充分的运用上去,没有养成习惯,现在重新对这些来进行一次学习低内聚的模块首先拆分为多个高内聚的模块;然后再考虑这多个模块之间的API设计,以降低这些高内聚的软件单元之间的耦合度。双方各自独自变化,互不影响。
2022-10-13 16:25:15 609 1
原创 迁移vite步骤及采坑记录
背景分析本次的目的不是直接用 vite 替换 vue-cli ,而是想同时保留 vite 和 vue-cli 。除去影响开发体验webpack 和 vite 本质上都是入口文件 + 依赖分析 + 模块转换。vite 是 使用的时候进行处理(vite针对第三方库有同样会进行预处理), webpack 则是先全部处理完毕。当浏览器天然支持 ES module 之后,实时处理变得可能。这也是 vite 启动速度快的原因。步骤1. 分析vue.config.js,安装相关依赖yarn add vite
2022-02-28 10:44:30 1995
原创 css3 实现一个loading加载动画
实现类似下面的一个loading加载动画最终实现的css样式 div { position: relative; margin: auto; width: 100px; height: 100px; border-radius: 50%; } @property --per {
2022-01-24 17:00:28 576
原创 git-cli 部署及yml介绍
通过部署根目录下的.gitlab.yml文件,控制ci流程的不同阶段每次push/merge后之后触发。每当你push/merge一次,gitlab-ci会执行.gitlab-ci.yml文件在里面编写的脚本,并完整地走一遍stages流程stages: 定义总阶段(与自定义流程中stage对应)stages: - build - codescan - bcode_check自定义流程(代码扫描JS)自动部署: <<: *uiEnvImages
2022-01-06 19:59:25 756
原创 一、docker认识及一些实现原理
一、虚拟化和容器技术虚拟化技术将计算机物理资源进行抽象,转化为虚拟的计算机资源提供程序使用。这里的计算机资源 指的是 CPU提供的运算控制资源, 硬盘提供的数据存储资源,网卡提供的物理传输资源二、相关应用及分类为了解决多平台的兼容问题将虚拟化技术应用到资源管理中(注意的是虚拟化技术只是为了提高计算机资源的使用率,而不是减少程序资源的占用率)虚拟化主要分为硬件虚拟化和应用程序虚拟化三、容器与虚拟机容器—把应用程序运行隔离在独立的运行环境中,这个运行环境就像是个容器容器与虚拟机对比少了 虚
2021-12-17 11:09:21 842
原创 基于qiankun微前端及基于monorepo工作流的lerna改造前端项目(一)
乾坤介绍(import-html-entry)将一个大型应用拆分成若干个更小、更简单,可以独立开发、测试和部署的子应用,然后由一个基座应用根据路由进行应用切换解决两个大型项目互不干扰的情况,可以独立运行应用加载切换 劫持 hashchange和popState(包括css隔离和js隔离,js隔离利用proxy和快照方式来实现,proxy劫持对象的set和get方法)import-html-entry 实现应用以html为入口,依次 解析加载css,js 隔离lerna 介绍用来优化托管在 gi
2021-12-14 21:14:16 1858
原创 babel 编写plugin(三)----原理
AST 抽象语法树抽象语法树就是通过JavaScript Parser将代码转化成为一颗抽象语法树,这棵树定义了代码的结构。然后通过操纵这棵树的增删改查实现对代码的分析,变更,优化。
2021-12-04 11:38:29 352
原创 babel 编写plugin(二)----常用的babel
babel-loader本质是一个函数,函数参数是源代码和配置参数option,函数返回转换后的代码配置参数可以通过loader配置,也可以在babel.rc文件文件传入babel-corebabel最核心的模块,是babel转译器本身,提供转译的API,例如babel.transform等,babel-loader就是调用core中的这些API完成转译的babel-preset-env告诉babel以什么规则转换,也就是preset的值,core.transform里面的参数规则下面babe
2021-11-20 16:34:20 835
原创 babel 编写plugin(一)--介绍
babel介绍babel其实就是代码转换器,就是把ES6转化成ES5,或者把jsx转换成js等plugin和presetplugin实现babel的核心功能就是plugin,如下:原始代码 ----> plugin转化器 ----> 转化后的代码业务使用一、手动执行单个文件安装相关依赖执行转换,通过–plugins声明依赖的插件,多个插件之间采用,进行分隔下列命令如下:npm bin/babel --plugins babel-plugin-transform-es201
2021-11-20 14:59:11 1493
原创 基于qiankun微前端(支持vue2,vue3)及基于monorepo工作流的lerna改造前端项目(二)
乾坤介绍(import-html-entry)将一个大型应用拆分成若干个更小、更简单,可以独立开发、测试和部署的子应用,然后由一个基座应用根据路由进行应用切换解决两个大型项目互不干扰的情况,可以独立运行应用加载切换 劫持 hashchange和popState(包括css隔离和js隔离,js隔离利用proxy和快照方式来实现,proxy劫持对象的set和get方法)import-html-entry 实现应用以html为入口,依次 解析加载css,js 隔离lerna 介绍用来优化托管在 gi
2021-10-14 15:59:15 1806
原创 vue-ts 中 @Component 解读--写一个自己的类装饰器和方法装饰器
类装饰器–应用于类构造函数,其参数是类的构造函数@Component就是个类装饰器,作用于Vue对象vue-class-component 中,入口代码是function Component(options) {if (typeof options === 'function') { return componentFactory(options);}return function (Component) { //vue对象,类装饰器返回 return compo
2021-07-21 17:37:29 2441
原创 深入学习 TCP/IP(六)---三次握手及四次挥手
三次握手三次握手的最重要的是交换彼此的 ISN(初始序列号)SYN 报文不携带数据,但是它占用一个序号,下次发送数据序列号要加一规则: 凡是消耗序列号的 TCP 报文段,一定需要对端确认。如果这个段没有收到确认,会一直重传直到达到指定的次数为止。第一次—客户端向服务端请求: 客户端发送SYN同步发送标识 1,并且产生一个客户端的初始序列号 ISN,这个时候序列号Seq 是等于初始序列号ISN第二次—服务端响应客服端:服务端产生一个ACK确认包,包的大小为Seq(client) +1, 并且产生一
2021-05-12 17:38:15 149
原创 深入学习 TCP/IP(五)---Port
前言分层结构中每一层都有一个标识,比如链路层标识 ---------- MACIP层标识 ---------- IP地址传输层标识 ----------- 端口号TCP 用两字节的整数来表示端口,一台主机最大允许 65536 个端口号的。TCP 首部中端口号如下图黄色高亮部分传输层就是用端口号来区分同一个主机上不同的应用程序的。操作系统为有需要的进程分配端口号,当目标主机收到数据包以后,会根据数据报文首部的目标端口号将数据发
2021-05-11 20:01:03 831 1
原创 深入学习 TCP/IP(四)----数据包大小
最大传输单元(Maximum Transmission Unit, MTU)数据链路层传输的帧大小是有限制的,不能把一个太大的包直接塞给链路层,这个限制被称为—MTU以太网的帧格式,以太网的帧最小的帧是 64 字节,除去 14 字节头部和 4 字节 CRC 字段,有效荷载最小为 46 字节最大的帧是 1518 字节,除去 14 字节头部和 4 字节 CRC,有效荷载最大为 1500,这个值就是以太网的 MTU因此如果传输 100KB 的数据,至少需要 (100 * 1024 / 1500) = 69
2021-05-08 17:45:20 5030
原创 深入学习 TCP/IP(三)
TCP首部字段详解源端口 目的端口序列号确认号头部长度 保留 ACK SYN FIN RST… 窗口大小校验和 紧急指针TCP报文头部没有源ip和目的ip,只有源端口和目的端口序列号TCP 是面向字节流的协议,通过 TCP 传输的字节流的每个字节都分配了序列号,序列号(
2021-05-06 21:33:12 340
原创 深入学习 TCP/IP(二)
TCP 是一个可靠的(reliable)、面向连接的(connection-oriented)、基于字节流(byte-stream)、全双工的(full-duplex)协议。面向连接面向连接就是在正式发送数据前要三次握手,断开连接的时候要四次挥手无连接的协议则不需要三次握手发送端会发送 SYN 标识给接收端接收端会发送 ACK+ SYN 给接收端标识可以接受发送端 发送ACK标识简历完毕,可以发送数据了协议是可靠的对每个包提供校验和每个 TCP 包首部中都有两字节用来表示校验和,防止
2021-05-06 21:08:46 161
原创 深入学习 TCP/IP(一)
历史背景ARPANET: Advanced Research Project Agency Network 美国国防部高级研究计划局研究的非常小的网络为1969年最小的Internet很多人会认为 TCP/IP 是 TCP、IP 这两种协议,实际上TCP/IP 协议族指的是在 IP 协议通信过程中用到的协议的统称分层模型可以用wiresharks 抓包查看网络接口层(Network Access Layer)–ETH提供了主机连接到物理网络需要的硬件和相关的协议网络互联网层(Interne
2021-05-06 20:53:01 157
原创 node框架---koa 洋葱模型
洋葱模型它能接受一个函数数组,然后返回一个新的函数,函数自外向内,然后自内向外执行,和洋葱一样例如:const fn1 = (next) => { console.log(1); next(); console.log(2);};const fn2 = (next) => { console.log(3); next(); console.log(4);};const fn3 = (next) => { conso
2021-05-06 17:55:15 299
原创 简述--websocket 实现原理代码
websocket 使用H5:<!DOCTYPE HTML><html><head><meta charset="utf-8"><script type="text/javascript">function WebSocketTest() {if ("WebSocket" in window) { alert("您的浏览器支持 WebSocket!");// 打开一个 web socketvar
2021-04-22 20:50:24 292
原创 js 组合继承----附上 new object.create 实现
组合继承组合继承就是 原型链继承 + 构造函数原型链继承:function Animal () { this.color = [];}Animal.prototype.getColor = function () { return this.color;} function Dog () {}Dog.prototype = new Animal();缺点: 1. 原型上的引用类型共享 2. 没法传参构造继承function Animal (name) { this.na
2021-04-19 21:35:48 104
原创 详解V8垃圾回收机制
为什么要垃圾回收因为c、c++ 在定义变量的时候都会手动分配和手动释放掉,但是在js中是不需要我们自己手动处理的。V8引擎会根据你当前定义对象的大小去自动申请分配内存。不需要我们去手动管理内存了,所以自然要有垃圾回收,否则的话只分配不回收,岂不是没多长时间内存就被占满了吗,导致应用崩溃。由于V8最开始就是为JavaScript在浏览器执行而打造的,不太可能遇到使用大量内存的场景,所以它可以申请的最大内存就没有设置太大,在64位系统下大约为1.4GB,在32位系统下大约为700MB。如何判断可以进行垃
2021-03-09 17:11:39 317
原创 回溯,深度遍历---单词搜索
给定一个二维网格和一个单词,找出该单词是否存在于网格中。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。board =[ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E']]给定 word = "ABCCED", 返回 true给定 word = "SEE", 返回 true给定 word = "ABCB", 返回
2021-02-22 21:04:38 108
原创 连续赋值(从堆栈角度解析)var a = {n:1}; a = b ;a.x=a={n:2};
前提:1. 首先明白的是.的优先级是高于=的优先级,且.的运算符是从左到右的,=的运算符是从右到左的对于 var a = {n:1};a = b中a 指向了堆内存中的对象{n:1}, var b=a; a赋予给b的时候传的是栈中的地址(相当于新建了一个不同名“指针”) ,而不是堆内存中的对象。对于 a.x=a={n:2};之前说了“.”的优先级大于赋值运算符的优先级,所以先来看a.x;a.x实际上是未定义的;再来看赋值运算符的从右向左解析;a = {n : 2},a被从新赋值,指向了一个新对
2021-01-16 14:38:35 426 1
原创 valueOf 、toString及隐式转换
共同点在 JavaScript 中,toString()方法和valueOf()方法,在输出对象时会自动调用不同点二者并存的情况下,在数值运算中,优先调用了valueOf,字符串运算中,优先调用了toString<script> var obj = {}; obj.valueOf = function() { return 10; } obj.toString = function() { return "return value"; } var result
2021-01-07 21:19:40 383
原创 Promise 实现并发请求限制 (一)
常用写法,不保证执行的顺序,不管成功失败用一个数组存储所有任务,判断正在请求的个数如果当前还有可执行的,递归取任务执行function createAjax (tasks, pool, callback) { class Task { constructor () { this.task = []; this.running = 0; this.result = []; } pushTask (task) { this.task.push(task);
2020-12-23 18:15:15 655
原创 最长回文子串-----二维数组
思路如果 i-j 是回文子串,那么i+1-----j-1 也是回文子串定义一个二维数组,每一项代表 是否是回文子串小tips: Array.from 可以用来拷贝数组Array.from(new Array(9),() => new Array(9).fill(0)) new Array(9).fill(new Array(9).fill(0))两者不相等function longestPalindrome (string) { let length = string.lengt
2020-12-14 19:59:47 237
原创 二分法查找---logn复杂度
数据量越多,查找的越快1. 对于一个有序的数组,找到target第一次出现和最后一次的索引值,时间复杂度为logn思路: 1. 找到左半部分第一次等于target的值2. 找到右半部分第一次大于taget的索引值 减一function search (nums, target) { let findIndex = (nums, target, isSearchLeft) => { let left = 0, right = nums.length - 1, result = num
2020-12-01 21:38:35 605
原创 LFU 缓存算法-----链表
Least Ffequently User最少使用缓存的 算法思路 O(1):利用双向链表数据结果实现新增删除利用map来读取存储数值及频率的次数首先明确,我们要对外暴露两个方法,get 和 set因为get和set的调用要更新次数以及缓存数据的存储,所以要实现一个私有方法 _updateget 函数比较简单,如果存储的数据中有值的话,直接读取,并且更新使用的次数频率,否则返回 -1;set 函数 分两种情况,如果存储的数据中有值的话,更新值,并且更新使用的次数频率。 如果没有值,
2020-11-28 16:58:15 184
原创 js 数组转成二叉树(递归)
判断终止条件。 leng === 1 return this.value = value取中间mid先定义一个root = arr[mid];root.left 递归左半部分root.right 递归右半部分返回rootfunction sortedArrayToBST (arr) { if (!arr.length) { return null; } if (arr.length === 1) { return arr[0]; } let mid = parseIn.
2020-11-19 21:20:21 2369 2
原创 深度优先遍历及广度优先遍历
深度优先遍历 Depth-First-Search(DFS)自上而下的遍历搜索 (时间比广度要长,但是空间更少)堆栈的形式, 即先进后出广度优先遍历 Breadth-First-Search (BFS)广度优先逐层遍历 (时间比深度要短,但是花费的空间更大)队列的形式, 即先进先出两者差别深度优先不需要记住所有的节点, 所以占用空间小, 而广度优先需要先记录所有的节点占用空间大深度优先有回溯的操作(没有路走了需要回头)所以相对而言时间会长一点代码实现const data = [
2020-11-17 21:17:35 400 1
原创 十大排序(一)冒泡、选择、快排和插入
冒泡排序让数组的当前项与后一项作比较,如果当前项大于后一项,则交换位置最多比较length - 1轮,每一轮最多比较 length - 1 - i 次, 每次比较一轮的时候都能得到最大的放到后面function bubbleSort (arr) { for (let i =0; i< arr.length -1) { for (let j = i; j++; j < arr.length -1 - i) { if (arr[j] > arr[j+1]) {
2020-11-16 22:12:52 70
原创 RSA算法(二)
号称世界上最重要的加密算法生成步骤甲要向乙进行通信,要生成私钥和公钥一. 甲方随机生成两个质数a (61), b(53),实际上质数越大,就越难破解二. 计算 a和b的乘积 nn的长度就是秘钥的长度,n = 61×53 = 3233, 写成二进制是110010100001,一共有12位,所以这个密钥就是12位,实际应用中,RSA密钥一般是1024位,重要场合则为2048位三、计算n的欧拉函数φ(n) —φ(n) = (p-1)(q-1)φ(3233)等于60×52,即3120四、随机
2020-11-13 11:01:40 153
原创 RSA算法(一)
对称加密算法加密和解密都是使用同一种规则这样存在的问题: 甲方必须把加密的规则告诉乙方,否则无法解密,这样保存和传递秘钥就很可能存在安全问题非对称加密算法乙方生成两把秘钥(公钥和私钥),公钥是公开的,任何人都可以获得,私钥是保密的甲方获取乙方的公钥,对它进行加密乙方得到加密的信息后,用私钥解密RSA算法就是著名的非对称加密算法,密码长度越长越容易被破解互斥欧拉函数模反...
2020-11-12 21:29:52 183
原创 下一个全排列
比当前的大(大的幅度要尽可能小),如果当前是降序排列(最大),要转换成升序排列(大的幅度要尽可能小)eg: 【1,2,3】=> [1, 3, 2]eg: 从最后一项 [1, 2, 3, 4, 6, 5] => [1,2,3,5,4,6]思路: 1. 从最后一项开始找升序, 如果找到当前值 i2. 从最后一项寻求第一个比他大的数,并且与它交换3. i后面的所有值按照降序排列let getNextList = (nums) => { let i = nums.length -
2020-11-12 10:36:51 101
原创 几种跨域的实现
跨域就是协议,域名和端口号有一个不同jsonp不安全,可能导致xss攻击import { JSONP } from './JSONP'// 调用JSONP({ url: 'url', data: { key1: 'key1' }, callback (data) { // data 是服务端返回的数据 } })JSONP({url: 'url', data: { key1: 'key1' }}).then((d
2020-11-11 10:28:58 113 1
原创 CSS--BFC
块级格式化上下文BFC的布局规则内部的box会在垂直方向一个一个的放置box的垂直方向的距离由margin决定,属于同一个BFC的相邻BFC margin会发生重叠BFC的区域不会与float box重叠计算BFC的高度时,浮动元素也参与计算如何创建BFCoverflow: 不为visible( hidden)float的值不是nonedisplay的值是inline-block、table-cell、flex、table-caption或者inline-flexposition的
2020-11-09 16:45:31 124
原创 weakMap、weakSet、Reflect 在vue3的应用
weakMap只接受对象作为键名键名所引用的对象是弱引用,不可遍历(可能在任何时刻被垃圾回收器回收)利用这一特征,在对数据量很大的时候就可做一部分的优化例子: Vue3在 检测到哪些数据发生了变化时候用了weakMap。所以当我们需要关联对象和数据,比如在不修改原有对象的情况下储存某些属性或者根据对象储存一些计算的值等,但是又不想管理这些数据的死活时可以考虑使用 WeakMapconst targetMap = new WeakMap<any, KeyToDepMap>()expo
2020-11-09 15:55:29 513
原创 贪心算法---解决整数转换成罗马数字
定义总是对局部做出最优解,而不是整体考虑最优解思路1.建立数学模型2.把每个问题分成若干个子问题3.对子问题进行求解4.把子问题局部最优解合成原来问题的一个解特性有一个候选的集合,比如硬币, 罗马数字集合随着算法的进行,将积累起其他两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优例子罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
2020-11-07 15:35:27 163
原创 MVVM的一些思考与实现(Vue为例)
MVVM 定义响应式,双向绑定数据层–视图层–视图数据层修改视图层(View),数据直接更新修改数据层,不需要更新dom,就可以直接更新视图实现步骤实现一个模板解析器 class Compile实现一个观察者 class Observer实现一个class Watcher 来连接 Compiler 和 Observerclass MVVM 整合以上三个初始化new Vue({el: ‘#app’ || document.getElemenrById(‘app’),data
2020-11-06 17:29:57 124
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人