并查集 Python3 模板
并查集模板
1 | class UnionFind: |
1 | class UnionFind: |
bitcon 是一个基于交易的账本
bitcoin 会维护一个 UTXO 数据结构
UTXO:upspent trasction output,用来防止 double spending
每笔交易都要指明,从哪几个交易记录到哪几个地址,
备注: 以太坊是 account-based ledger
比特币每 21万个区块会使挖矿奖励减半,比特币通过控制挖矿难度来控制平均每 10 分钟出一个区块,而 21万个区块差不多等于 4年。
21万 * 10分钟 / (60分钟 * 24小时 * 365天) = 约4年
比特币挖矿的每一次尝试 nonce 都是一次 Bernoulli trial
Bernoulli trial: a random experiment with binary outcome
Bernoulli process: a sequence of independent Bernoulli trials
memoryless: 前面的结果不会影响后面的概
比特币是 memoryless and progress free 的: 这提供了挖矿公平性的保证,每一次尝试都是一样的概率。
The BitCoin Network
appliction layer: BitCoin Block Chain
network layer: P2P Overlay Network
simple robust but not efficient
挖矿目标,使得 H(block header) <= target,其中 Header 中的 nonce 可以修改,使得结果小于 target(target 是前缀一连串 0 的二进制数)
bitcoin 挖矿的本质就是尝试出 nonce 使得结果小于 target,从而获得记账权。
SHA-256 即 Secure hash Algorithm 2^256,产出 256 位二进制数。
出块时间太短会有什么问题?
同一时间会有很多分叉,算力会被分散,有恶意的算力可以集中扩展一个分叉。
好人的算力被分散了,这样坏人就不需要 51%的算力进行攻击了。
以太坊将出块时间降低到了15s,这样的话就需要新的共识机制,ghost,(扩展,orphan node, uncle reward)
调整方式?
1 | target = target * (actural time / expected time) |
其中 actual time = time spent mining the last 2016 blocks
expected time = 2016 * 10 * 60 (秒)
1 | next_dificulty = previous_diffulty * (2 weeks / time to mine last 2016 blocks) |
target 和 expect_difficulty 成反比
每次调整最大4倍,最小1/4
如何让大家都进行调整?
在 block header 中有一个字段 nBits 4个字节,nBits 是 target 的压缩版本(target 有 256位)
如果有坏矿工不进行调整,那么他产生的区块将不被其他矿工承认。
从速度上来说:
CPU -> GPU -> ASIC 即 Appliction Specific Integrated Circuit
mining puzzle -> Alternative mining puzzle (目的: ASIC resistance)
有些区块链会使用可变的 mining puzzle,这样可以有效抑制 ASIC 的发展。
矿池:pool manager has many miner,pool manager 也就是全节点,有很多职责,而 miner 只负责计算 hash。
矿池如何分配奖励:使用 almost valid block,矿工只需要挖到矿池规定的具有一定数量前导 0 的 nonce,就可以得到一个 share,最终的奖励根据 share 分配。
矿池的弊病:让 51% Attack 更容易
51%算力的矿池可以干的坏事:
bloom filter 是块头的一个域
bloom filter 快速过滤掉不符合条件的区块
以太坊:transaction-driven state machine
(比特币的状态机是 utxo)
Proof of stake
virtual mining
AltCoin Infanticide
Proof of Deposit
nothing of stake
Casper the Friendly Finality Gadget (FFG)
Validator 2/3
100 epoch -> 50 epoch,连续两个 epoch 有 2/3 通过
EOS
DPOS: Delegated Proof of Stake
拆分配置为 webpack.common.js、webpack.dev.js、webpack.prod.js
webpack.dev.js、webpack.prod.js 通过 webpack-merge 的 smart 继承 webpack.common.js
1 | import { smart } from 'webpack-merge' |
在 webpack5 中,更改为
1 | import merge from 'webpack-merge' |
dev、prod 区别
mode、plugin: webpack.DefinePlugin、devServer
安装 webpack-dev-server,通过 –config 指定 config 文件
proxy 端口代理
对 js 文件处理,使用 babel-loader
使用 babelrc 文件进行配置 preset & plugin
css:
Loader: [‘style-loader’, ‘css-loader’, ‘postcss-loader’]
postcss-loader: 配置文件 postcss.config.js 其内容 plugins: [require(‘autoprefix’)]
less:
Loader: [‘style-loader’, ‘css-loader’, ‘less-loader’]
loader 执行顺序从后往前
url-loader: 小于指定 limit 大小的图片使用 base64,可以通过指定 output 把文件统一放在某个目录下
url-loader file-loader 区别
它们都可以用于载入静态资源文件,url-loader 比 file-loader 的优势在于可以将文件转为 base64
they are both deprecated in webpack v5,使用 asset module 代替
url-loader file-loader 原理:
loader 本质上是一个函数,它们遇到需要解析的文件,会使用 webpack loader 的 api emitFile 将文件移动到指定的路径,并将文件改写为以下内容
1 | export default '/absolute/path' |
or
1 | export default 'data:imgae/jpeg:base64....' |
这样的内容。
1 | output: { |
使用 currentHash 的好处:当内容不变时,hash 值不变,浏览器可以使用缓存。
TODO: 为什么可以使用 import output 的语法?
需要配置多个 entry
1 | // webpack.common.js |
对应的 output 需要需改
1 | // webpack.prod.js |
使用 currentHash 的好处:当内容不变时,hash 值不变,浏览器可以使用缓存。
HtmlWebpackPlugin 需要多个
1 | // webpack.common.js |
其他
CleanWebpackPlugin: 会清空 output.path 指定的路径
使用 MiniCssExtractPlugin
1 | rules: [ |
公用代码和第三方代码不会经常变,如果不抽离,每次都需要被重新打包,因为每次的hash值都发生变化,所以不能使用缓存,浏览量每次都会加载很慢。
1 | plugins: [ |
使用方式:
1 | setTimeout(() => { |
react 使用 @babel/preset-react
1 | // .babelrc |
vue 使用 vue-loader
1 | module: { |
1 | { |
避免引用无用模块
例子:
1 | // webpack.prod.js |
使用的地方
1 | import moment from 'moment' // 235.4K (gzipped: 66.3K) |
1 | module: { |
JS 是单线程的,要开启多进程打包
提高构建速度,特别是对于多核 CPU
1 | // webpack.prod.js |
1 | // webpack.prod.js |
使用多进程压缩代码
1 | // webpack.prod.js |
1 | // webpack.prod.js |
PS:
自动刷新 vs. 热更新
wepack 有自带的配置字段 watch 配置自动刷新
1 | module.exports = { |
使用的地方
1 | import { sum } from './math' |
动态链接库插件
webpack 已经内置 DllPlugin 支持
步骤:
通过 DllPlugin 打包出 dll 文件
通过 DllReferencePlugin 引用 dll 文件
好处:
使用 url-loader 配置 limit
可以使用缓存
1 | import('./dynamic-data.js').then() |
optimization.splitChunks
IgnorePlugin 直接不引于,代码中没有无用的代码
1 | output: { |
Tree-Shaking 举例
1 | // math.js |
在实际使用的地方只有使用到 add,那么 multi 就不会被打包
打包出来的代码中,每个文件一个函数会合并成一个函数
好处:
1 | const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin') |
babel 只对语法进行转换,对于新的 api 不进行转换,例如 Promise 或者 [].includes
新的语法需要使用 babel-polyfill 进行转换
babel 也不管模块化,所以需要配合 webpack 使用
.babelrc
1 | { |
使用 babel 转换 js 文件
1 | npx babel index.js |
polyfill 即布丁,babel-polyfill = core-js + regenerator,在 babel 7.4 之后弃用,推荐直接使用 core-js & regenerator
core-js 是一系列 polyfill 的合集
regenerator 对 generator 语法进行补充支持
.babelrc
1 | { |
babel-polyfill 会污染全局环境,
使用 babel-runtime 不会去污染全局环境
如果开发第三方库,必须使用 babel-runtime
主要是内部效率优化
chunk 是偏抽象的一个概念,bundle 是 chunk 的输出实体
loader: 模块转换器 如:less => css
plugin: 扩展插件,如 HtmlWebpackPlugin
略
配置 output.library
略
import()
如 class 可以用 function 模拟
如 Promise 可以用 callback 模拟
但是 proxy 的功能无法用 Object.defineProperty 模拟
略
代码
1 | // 定义三种状态 |
测试用例 1
1 | // 测试用例 |
测试用例 2
1 | const p2 = new MyPromise((resolve, reject) => { |
代码
1 | Promise.myAll = function (promises) { |
测试 case
1 | const p1 = new Promise((resolve) => { |
Promise.allSettled 和 Promise.race 原理类似
1 | npm install -g yo generator-eslint |
目录结构如下:
1 | . |
接着执行
1 | yo eslint:rule |
此时目录结构如下:
1 | . |
在 eslint-plugin-demo 目录下执行
1 | npm link |
控制台会输出
1 | /usr/local/lib/node_modules/eslint-plugin-demo -> /Users/your-name/workspace/eslint/eslint-plugin-demo |
然后在需要使用该 npm 包的项目中执行
1 | npm link eslint-plugin-demo |
控制台会输出
1 | /Users/your-name/workspace/eslint/eslint-example/node_modules/eslint-plugin-demo -> /usr/local/lib/node_modules/eslint-plugin-demo -> /Users/daomeng.pan/workspace/eslint/eslint-plugin-demo |
如果需要解除 link ,则直接删除项目中 node_modules 下的软链接即可
1 | rm /Users/your-name/workspace/eslint/eslint-example/node_modules/eslint-plugin-demo |
yo eslint:rule 生成的模板文件如下
1 | /** |
meta
--fix
的时候是否自动修复create: (function) 返回一个对象,其中包含了 ESLint 在遍历 JavaScript 代码的抽象语法树 AST (ESTree 定义的 AST) 时,用来访问节点的方法。
我们可以借助 ast语法树分析网站,在里面得到我们的语法树
1 | module.exports = { |
使用 eslint-module-utils 提供的方法可以提高开发效率
例
1 | const { default: moduleVisitor } = require('eslint-module-utils/moduleVisitor'); |
参考源码 https://github.com/benmosher/eslint-plugin-import/blob/master/utils/moduleVisitor.js
create 函数接收一个 context 对象
提供了很多常用的方法和属性,包括 getSourceCode() 获取源码、getFileName() 获取文件名、context.options 获取配置的参数(schema 中约定好的结构) 等
一直觉得自己的下巴比别人的要长,对自己的长相也一直挺自卑的。直到上大学的时候才真正知道,自己的这种症状是因为牙齿咬合不正畸形导致的,我属于比较严重的地包天加偏颌。看了很多网上牙友的看牙经历,知道了正畸正颌这一神奇的治疗方法,也看到了很多治疗成功的案例,我决定等毕业攒够钱一定要去做这个治疗。
2019.06.17 我来到了上海的一家公司,这家公司距离上海九院 5公里。(上海九院是全国正畸正颌做得最好的几家医院之一),但是因为经济的原因,一直没开始我的治疗。2020 年 11 月初,我在网上挂了个九院 ”正畸正颌“ 普通初诊号。
到了初诊的这一天,我 9:00 来到九院,先是尝试在自助挂号机上挂号,但是”正畸正颌“是无法使用医保卡的,自然是挂号失败了。然后只能去窗口排队取就诊卡。九院窗口挂号的队伍很长,排了半小时才排到。挂完号之后就直接去四楼的正畸正颌科等着了。等了不是很久就到我了,面诊我的是8诊台的丁医生,她看了看我的情况,就跟我说了我这种情况是需要做正畸正颌联合治疗的,并且跟我说了治疗时长可能要两三年,费用需要十几万。因为我事先做好调研了,所以我表示都没有问题,接着丁医生就给我开了张单子,开始拍片了。在六楼交完 2800元的拍片费用之后,我当天拍完了牙片、全景、CT,核磁共震约在了下周六 11.21。还做了一项抽血,抽血是为了验是否有乙肝。把 CT 的牙片给了丁医生后,约了下次来取牙模的时间。差不多到中午的时候就全部结束回家了。
进展比我预想的要快很多,本来预期只是来稍微了解下情况,没想到就直接交完钱拍好片了。
今天是专门来拍核磁共振(MRI)的,顺便取了下之前做的 CT胶片和验血单子。进入核磁共振巨大的铅门,医生让我躺在 MRI 的仪器上,带上耳罩,开始 MRI。其中一段过程要求我咬住一个塑料块。整个过程在头部周围一直有各种频率刺耳的声音。差不多几分钟后就结束了。中午之前就结束回家了。
今天来口扫了,首先是一个医生拿着扫描器对着你的口腔一顿扫描,估计是为了出 3D 打印模型。然后去拍照,照相师把我的嘴撑开,对着牙的各个角度都拍了照片。最后就是去了一个牙模室,一个护士拿石膏一样的东西盖在你的上牙齿2分钟,等凝固后去下,然后是下牙。接着就跟丁医生约了会诊的时间。差不多也是中午前就结束了。
会诊就是正畸医生和动手术的正颌医生一起讨论出一个正畸方案,我从早上 8:30 等到了 11点,终于轮到我的会诊了,全程就是丁医生在讲大概的正畸方案,然后正颌医生点了点头,全程两分钟左右就结束了。最后定下来的拔牙方案是,把上颌的两颗4号牙外加3颗智齿,因为有一颗智齿之前拔掉了。智齿不影响正畸带牙套,只要拔掉两个四号牙就可以开始正畸了。本来想的拔牙怎么说也要一个月时间吧,就和丁医生约了 12.31 号上牙套。
下午的时候在颅颌面科挂了个号,排到之后进入诊室,医生开了一张单子让我去一楼拿消炎药和两针麻醉剂。拔牙的过程很快,5分钟不到,两颗4号牙就都拔完了。拔牙比预想的快了很多,就在微信上跟丁医生提前了带牙套的时间,约在了 12.17 号。拔完牙咬了纱布 45 分钟后吐掉了,嘴里还有一点点血,不过过了两小时左右,喝了点水,基本就没有血了。
回家的时候带了个石膏牙模回去。
今天预约的是早上 10点钟,随意我比平时多睡了会儿。到九院 4楼正畸科的时候刚好 9.50,看到叫号机上写着我的名字,我就直接进去了。丁医生在专家四诊台等着我,我到了以后,丁医生去取了下工具,我躺下来就开始粘牙套的托槽了。正畸医生先往我的牙齿上喷了一些酸酸的东西,酸蚀牙齿,然后一个个托槽往上粘,粘完托槽以后,医生用铁丝将所有托槽连在一起。过程粘了两个小时。
中午回家的时候在白玉兰吃了碗牛肉粒手擀面,右下颌最里面的托槽直接就崩掉了,联系了丁医生,下午又回到九院重新粘上。
晚上和公司同事聚餐,感觉到牙上下牙咬合的时候很疼,不能咬东西,将就吃了点东西。
每顿饭后牙套里都塞满了食物,都需要认真刷牙。买了一款漱口水,刷完牙含漱一会儿。
配置 http 代理监听 127.0.0.1:1087
1 | vim ~/.ssh/config |
添加文件内容如下:
1 | Host github.com |
即可走 http 代理,效果如下
配置 socks5 代理监听 127.0.0.1:1086
在命令行中执行以下命令
1 | git config --global http.proxy "socks5h://localhost:1086" |
即可。