开篇
在反复折腾了这么几年以后,回头看来2017年那时学习外加文章输出的时间是让自己感到最舒服的日子。最近在看了阮一峰(以下简称阮博)的周刊以后,觉得写作能让自己能从每天的看似平淡的日常中获取有所收获。虽然自己可能做不到持续输出,也许本次以后就遥遥无期,仅仅作为自己任性的行为。
技术方向
关于工程版本号
项目第版本号存在最佳实践第约定:语义化版本 / 语义化版本中文
概括来说,版本通常按照以下规范:
major.minor.patch-pre
例如:1.0.0-1
major: 主版本号,用于不兼容的API修改
minor: 次版本号,功能新增
patch: 修订号,问题修复
pre: 各种先行版,预览版,etc
通过语义化版本方式,版本版本本身具有可读性。平时业务开发过程中,没有思考过版本迭代规范(由于toB内部项目,也缺少了理应存在的changelog)。之前在微信小程序提交第时候,官方的版本号也是采用这种语义化的版本号定义规则,现在才了解到这大概是一种最佳实践。
前端项目可以考虑npm提供的命令行:npm version
,来进行版本迭代。npm version
也是遵照了语义化的规则,通过常用的参数,帮助我们更新package.json
中的版本信息,并自动执行add
和commit
。
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]
取消自动打tag功能,可以追加参数 --no-git-tag-version
详细内容可以参见:npm version
对于一个项目的,初始版本号通常是:0.1.0
,当对外开放标注版本的时候可以使用1.0.0
算法
最近继续在弥补不足的算法知识,本周的几个排序算法都是基于分组的概念,算法复杂度理想情况下都是O(n)
1.桶排序
将大的数组对象,根据范围划分成多个小的数组(多个桶),桶内排序(使用快排)后合并。桶排序比较适合外部排序,例如:内存无法一次性加载所有数据的时候,将数据划分成不同的范围并用桶排序,最后再组合写出到文件,就能实现无法一次性全量排序的数据,这个解决大量数据的思路(分而治之),不过从排序规则来说,需要制定范围,所以可能更适合数字/或能转换为数字比较的数据排序(计算机世界其实都可以转换为数字,至少是二进制)。
以下例子中前提是数组元素均为自然数,如果需要包含负数或者非数字元素,则算法需要进行调整
function bucket_sort(arr) {
// 将数据分成3个桶
return bucket_sort_unit(arr, 3);
}
function bucket_sort_unit(arr, n) {
// 找到桶内最大值
let max = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
// 单位桶的范围
let unit = Math.ceil(max / n);
let buckets = [];
for(let i = 0; i < n; i++) {
buckets.push([]);
}
// 将元素放到每一个桶中
for(let i = 0; i < arr.length; i++) {
buckets[Math.ceil(arr[i]/unit) - 1].push(arr[i]);
}
// 桶内自排序,并组合到一起
let res = [];
for(let i = 0; i < n; i++) {
quick_sort(buckets[i]);
res.push(...buckets[i]);
}
return res;
}
console.log(bucket_sort([1,3,20,9,5,6,10,83,29]));
2.计数排序
在桶排序的基础上,极端化到每个桶只有一个元素。根据王争老师的实现,最关键的点在巧妙利用数组元素值和其出现次数的关系,来构建所需要的数组。
function countSort(arr) {
// 获取数组中元素最大值
let max = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
// 直接获取累加数组
let plusBuckets = [];
for (let i = 0; i < max + 1; i++) {
plusBuckets[i] = 0;
}
for(let i = 0; i < arr.length; i++) {
plusBuckets[arr[i]]++;
}
for (let i = 1; i < max + 1; i++) {
plusBuckets[i] = plusBuckets[i - 1] + plusBuckets[i];
}
// 利用累加累加后数组的特性,计算数据
let res = [];
for (let i = 0; i < arr.length; i++) {
// 获取到某个元素累加后到最大index
// 这里的关键是要理解plusBuckets[arr[i]]代表什么
// arr[i]是数组数据的值,相对于plusBuckets来说是其中的数组序号
// plusBuckets是数组数据值出现次数得加后的结果
let index = plusBuckets[arr[i]] - 1;
// 最大到index就是某个元素应该到值
res[index] = arr[i];
// 元素占位以后,累加数需要-1
plusBuckets[arr[i]]--;
}
// 为什么不用,因为解构本身应该可能用到循环,所以就变成了两层循环,计算复杂度就不一定是O(n)
// let buckets = [];
// for(let i = 0; i < max + 1; i++) {
// buckets[i] = [];
// }
// for(let i = 0; i < arr.length; i++) {
// buckets[arr[i]].push(arr[i]);
// }
// let res = [];
// for(let i = 0; i < buckets.length ; i++) {
// res.push(...buckets[i]);
// }
return res;
}
因此总结规则其实就是:
1. 利用累加求和的方式获取到每个元素的最大序号
2. 通过原数组中元素出现次数和最大序号的关系,原数组中某个数出现一次,则将该元素填充在最大序号处
3. 最大序号-1后继续排序
3.基数排序
基数排序的分类思路是将一个数据(从思路上看对字符串排序似乎更合适),利用稳定排序算法,将的每一位分别排序,最后得到整体的排序结果。这里的前提是所有数据位数一致,如果不一致可以考虑使用0
进行补位(字符串比较通常是通过ASCII码进行的比较)
Makefile
makefile
的目的是配合make
生成所需要的文件,且自带文件变化检测功能,标准格式:
<target> : <prerequisites>
[tab] <commands>
target
和prerequisites
最后其实都是落到文件上,因为make
会对prerequisites
文件进行比较,如果有变化才执行相关command
过程,例如:
source: file1.txt file2.txt
file1.txt:
echo file1 > file1.txt
file2.txt:
echo file2 > file2.txt
所以command
都会输出target
,makefile
归根到底是为了创建一系列文件而生,这些创建的文件,可能会由其他的命令继续负责执行过程。
makefile
的教程推荐阮博的(看了一些文章,阮博写的算是最简单明了的了):Make 命令教程 和 GUN Make
一句话知识点
-
React
中<Fragment> | <></>
一定程度等同于Vue
中的<template>
,可以用作代码片段组合 -
无障碍
a11y
的能力可以用<label style="display:none">, aria-label, aria-labeledbody, title, alt
等方式屏幕读取器可读 -
HTML现在有哪些可以使用的Element:HTML Elements
-
Chrome devtools中的lighthouse功能,可以简单分析出网站某页面的性能,并给出部分建议,例如B站首页:
-
Chrome87 devtools中开启实验的CSS overview功能,可以拉出全站的配色,字体,边框,背景色,依赖CSS加载,可以用作视觉参考
开启方式:devtools小齿轮 -> Experiment -> CSS Overview
非技术方向
《进击的巨人》完结
本周巨人完结,漫画自己没跟,不过基本上被剧透完了,个人对结局不置可否,因为后续篇章没有看,所以没有发言权,不过从目前来看,结局不太符合大部分人理想中的结局。每个人心中都有自己认为的一个标准,如果不能达到自己所预期的结果,这个作品就是失败么?多从各个角度看一下这个作品,可能这些不同的看法和原作本身一样值得品味:
比特币UTXO模型
两种交易模型:UTXO和账户交易模型
比特币使用UTXO交易模型,每次交易都会产生UTXO,可以类比的纸币交付,例如:
我有2块钱
,我要买1块钱
的零食,我需要给2块钱
给商家,商家再找给我1块钱
,而不是我直接支付宝/微信转账1块钱
(账户扣款)给商家,存在一个找零的过程。
每张纸币就是一个UTXO,但是和纸币交易也有区别,毕竟纸币交易的UTXO对应的价值是一定的,但是每个UTXO对应比特币价值基本上是不同的。
四月新番
新一季的新番又来了,但是因为近期过审的原因,似乎题材上可能卡控更加严格了,且看且珍惜,目前本周还没补番,从目前了解到的情况,大概率会追《伊甸星园》(真岛浩老师新作),别的应该还包括上一季度的蜘蛛子和《勇者斗恶龙达伊的大冒险了》。
最后一提,上周补掉的《Re0》,确实是特别不错的佳作,虽然我不懂运镜,但是在人物刻画上的运镜,我只能说《Re0》真的细节,算是近今年特别推荐且续集保持高水准的作品了。
其他
阮博写的未来世界幸存者,虽然谈不上帮自己解决了多大困惑,但是总归是给到了一种解题思路。
每周其实新的输入比想象到多很多,只是很多被自己忽略了,碎片化的学习是需要更多时间的整理,才能体现其价值。
以上就是本周内容,大部分内容均为个人再加工观点,可能存在部分漏洞,欢迎大家指正。