202302
期望;过完农历春节,
- 能把面试需要的算法和 react 框架源码/vite 源码有一点基础了解即可
- 网络相关的背书容易忘记,阔以带着看
- 两个月已过啥也没干,就是一条大大的咸鱼,我必须重塑自己的技能包和价值体系,想到自己目前的处境,实在是难堪
TIP
不能再当一条咸鱼了,危险随时靠近,要时刻准备着,cookie 中的 same-site 属性又忘记了!!!
0201
- npx 跟 npm 区别
- 骨架屏实践
- 如何做出年度报告类似支付宝/掘金/xm 这种
- react 的组件懒加载
- js 知识点:面试官:你确定多窗口之间 sessionStorage 不能共享状态吗???
0202
- Preload/Prefetch 两者区别
- web 页面加载就那几个顺序,来来回回复习,有啥好记的,理解最重要
- vite 相关的开始搞起来,不喜欢拖
- 博客引入 Algolia DocSearch实现全文搜索,不知道如何下手,全是英文,看不懂
0203
- JIT(即时编译)和 AOT 编译可以选择放在两个时机执行:
代码构建时,被称为 AOT(Ahead Of Time,提前编译或预编译),宿主环境获得的是编译后的代码 代码在宿主环境执行时,被称为 JIT(Just In Time,即时编译),代码在宿主环境编译并执行
JIT 与 AOT 的区别还包括:
1.使用 JIT 的应用在首次加载时慢于 AOT,因为其需要先编译代码,而使用 AOT 的应用已经在构建时完成编译,可以直接执行代码
2.使用 JIT 的应用代码体积普遍大于使用 AOT 的应用,因为在运行时会多出编译器代码
- 要命了,结婚要花这么多钱,完蛋,三金,项链/耳环/戒指普通人办一场婚礼要用多少钱? 三金:15000(黄金价格在高位上) 戒指:5000 婚纱照:6000 彩礼:88888 婚庆:8000 酒席和烟酒:父母出
0204-05
- 今日元宵,要给叔叔阿姨发节日祝福
- 如果不考研的话需要一起奋斗,这样生活才有意义和价值,自己一个人单枪匹马久了,也会心累。
- 如果考研的话还是全力支持你,不用操心任何经济上的问题
- 解决了生活中的一个小问题,早上睡眠慢慢恢复正常,沟通还是比较重要的
0206
- TS 5.0 版发布新版 ES 装饰器、泛型参数的常量修饰、枚举增强等
- ROI return on investment 书面解释是投资回报率,通俗来讲就是你投入 100 块钱能收回多少钱,收回 150,ROI 就是 150/100=1.5,这就是 ROI,ROI 也可以简称为投产
- LTV(life time value) 生命周期总价值,意为客户终生价值,是公司从用户所有的互动中所得到的全部经济收益的总和。通常被应用于市场营销领域,用于衡量企业客户对企业所产生的价值,被定为企业是否能够取得高利润的重要参考指标
- CPM 按展示付费的广告,例如朋友圈、信息流,这些广告的 CPM 价格不低,在 100 至 150 元左右,即广告曝光 1000 次收费 100 到 150 元不等。
0207
TDD 和 DDD
TDD: Test drive development 测试驱动开发吗,涉及场景:修复 bug/写纯函数/UI 设计
DDD: domain driven design 领域驱动设计 参考React 语境下前端 DDD 的长年探索经验
border-box 跟 content-box
标准盒子模型 W3C:浏览器默认为标准盒模型,box-sizing: content-box,即盒子的宽高=content 宽高+padding+border
怪异盒子模型,一般根据实际项目需要自行设置。即:box-sizing:border-box,会把 padding 和 border 算在 content 里
0208
- 华为鸿蒙 隐私协议弹框,不懂安卓开发,捣鼓了好久。涉及到 js 侧调用 java 侧方法,主要还是因为鸿蒙端支持的版本太低了,low,而且本身华为鸿蒙对前端支持力度就不够,很多普适性的 api 都没有提供,举例比如说打开一个空白页面都没有,还有 text 标签不能嵌套 text 标签,只能抱一层 span 标签
<text class="desc">
<span>xxx</span>
<span onclick="openLink" style="color: #0b75c7;">
《用户服务协议》
</span>
<span>和</span>
<span onclick="openLink2" style="color: #0b75c7;">
《隐私政策》
</span>
</text>
0209
0210
- Eslint 的实现原理
- eslint 如何实现静态检查的
- 0214 马上要来了,你懂的
0211
- 社保突然取消了,暗自伤感,老人家养老还没有着落,后续希望能有好政策
- 前几天没睡好,昨日休息为主
0212
- 今天提前过情人节,带对象去逛街和看电影
- 积累下 DOM 相关的知识点,重温下,记录下下周需要解决的问题
0213
- 未来不可期,能做的就是把握现在
- logic 相关,慢慢积累信心吧,就差最后一口气
- 个人页面报错,找了半天,应该是资源没有加载到,资源没有加载到估计是 cdn 缓存没有更新
ailed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
- 个人博客自带的全文搜索功能 dosearch 上线,申请地址
// CSS
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3"/></li>
// js
<script src="https://cdn.jsdelivr.net/npm/@docsearch/js@3"></script>
<script type="text/javascript">
docsearch({
appId: UTFWSZD8OF,
apiKey: 2c5c49f778c42feb4c597213bacf4dc9,
indexName: bythewayer,
container: '### REPLACE ME WITH A CONTAINER (e.g. div) ###'
debug: false // Set debug to true if you want to inspect the modal
});
</script>
WARNING
收到官方回复,需要等待2-3天
0214
- 自动化测试入门
- 查看 vitepress 源码,启动之后,找不到端口号,尴尬了!!
- run-s 看不懂?
Before: npm run clean && npm run build:css && npm run build:js
After: npm-run-all clean build:\*
并行处理:npm-run-all —parallel 的简略是 run-p
序列化处理:npm-run-all —sequential 的简略是 run-s
- [AbortController().abort() 测试文档]./domTest
- markdown 语法很强大,看看下列效果
/**
* @type {import('vitepress').UserConfig}
*/
const config = {
// ...
};
export default config;
import type { UserConfig } from "vitepress";
const config: UserConfig = {
// ...
};
export default config;
0215
FCP: First contentful paint 首次内容绘制 这个指标用于记录页面首次绘制文本、图片、非空白 Canvas 或 SVG 的时间。
LCP: largest contentful Paint 最大内容绘制,用于记录视窗内最大的元素绘制的时间,该时间会随着页面渲染变化而变化,因为页面中的最大元素在渲染过程中可能会发生改变
FID: first input delay 首次输入延迟,记录在 FCP 和 TTI 之间用户首次与页面交互时响应的延迟
TTI: time to interactive 首次可交互时间,测量页面所有资源加载成功并能够可靠地快速响应用户输入的时间
TBT: total block time 阻塞总时间,记录在 FCP 到 TTI 之间所有长任务的阻塞时间总和
CLS: cumulative layout shift 累计布局偏移,记录了页面上非预期的位移波动
Time To First Byte (TTFB) :发出页面请求到接收到应答数据第一个字节所花费的时间;
First Paint (FP) :第一个像素对用户可见的时间。
First Contentful Paint (FCP): 第一条内容可见所需的时间。
Largest Contentful Paint (LCP) :加载页面主要内容所需的时间。
Time To Interactive (TTI): 页面变为交互并可靠响应用户事件的时间。
关键指标:
- LCP 代表了页面的速度指标,虽然还存在其他的一些体现速度的指标,但是上文也说过 LCP 能体现的东西更多一些。一是指标实时更新,数据更精确,二是代表着页面最大元素的渲染时间,通常来说页面中最大元素的快速载入能让用户感觉性能还挺好。
- FID 代表了页面的交互体验指标,毕竟没有一个用户希望触发交互以后页面的反馈很迟缓,交互响应的快会让用户觉得网页挺流畅。
- CLS 代表了页面的稳定指标,尤其在手机上这个指标更为重要。因为手机屏幕挺小,CLS 值一大的话会让用户觉得页面体验做的很差。
本周需要搞定的 eslint 插件,动态监测代码 => 监控工具
lint 通过静态分析源码,对 AST 进行检查,发现其中的一些代码结构的错误,或者代码格式的错误。 babel lint
后面有的忙了,vite 或者 vitepress 源码都不知道怎么跑,搞不懂具体流程
Mac 常用命令行回顾
// 文件属性:用户组、读、写、执行权限: ls -l
ls -l
total 8
drwxr-xr-x 6 xmly staff 192 12 10 2021 PortalModal
-rwxr--r--@ 1 xmly staff 17 2 15 10:39 hello
- 修改访问权限
语法:chmod 用户 操作 权限 文件
用户:u 表示用户(user)、g 表示群组(group)、o 表示其他用户(other)、a 表示全部用户。缺失的情况下默认为所有用户;
操作:+表示增加权限、-表示取消权限、=表示赋值权限;
权限:r 表示可读(read)、w 表示可写(write)、x 表示可执行(execute);
文件:不指定文件名时,操作对象为当前目录下的所有文件。
给 hello 文件增加执行权限
xmly@cpp My % ./hello
zsh: permission denied: ./hello
xmly@cpp My % chmod u+x hello
Hashbang(也称为 Shebang)是一个由井号和叹号构成的字符序列 #!,通常出现在文件开头,例如 #!/usr/bin/env bash
#!/usr/bin/env node
import("../dist/node/cli.js");
从今天开始,开始探索 vitePress 高级功能,先从成员页面开始
0216
版本格式:主版本号.次版本号.修订号,版本号递增规则如下:
主版本号 major:当你做了不兼容的 API 修改, 次版本号 minor:当你做了向下兼容的功能性新增, 修订号 patch:当你做了向下兼容的问题修正。 先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
0217
- 函数式编程
- 评论显示 IP 地址
- TS 写法基本都快忘记了,要命!
//@ts-ignore
interface ob {
[key: string]: string;
}
let obj: ob = {};
lint-staged:只检查本次修改更新的代码,并在出现错误的时候自动修复并推送
git 规范
Git 有很多的 hooks, 让我们在不同的阶段,对代码进行不同的操作,控制提交到仓库的代码的规范性,和准确性, 以下只是几个常用的钩子
pre-commit: 判断提交的代码是否符合规范
commit-msg: 判断 commit 信息是否符合规范
pre-push: 执行测试,避免对以前的内容造成影响
husky:操作 git 钩子的工具, 给我们的项目添加 git hook 的工具
git hook 是进行 git 操作会触发的脚本,
lint-staged: 本地暂存代码检查工具, 只检测git 暂存区的 lint 工具
commitlint: commit 信息校验工具
commitizen: 辅助 commit 信息 ,就像这样,通过选择输入,规范提交信息
npm 包自动发布总算搞定了changeset 自动发包
0218
- Nodejs 异步 IO 模型是什么
- libuv
- Nodejs 的日志和负载均衡怎么做的
0219
- 做一个短期规划,每天一道手写题一道算法题,记住是每天,坚持到五月底!第二天开始手写前一天写过的手写和算法题
function debounce(fn, delay) {
var timer = null;
return (...arg) => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, arg);
}, delay);
};
}
function throttle(fn, delay) {
var t1 = 0;
return (...arg) => {
var t2 = new Date();
if (t2 - t1 > delay) {
fn.apply(this, arg);
t1 = t2;
}
};
}
function throttle2(fn, delay) {
var timer = null;
return (...arg) => {
if (timer) return;
timer = setTimeout(() => {
fn.call(this, ...arg);
timer = null;
}, delay);
};
}
请求并发限制
async function asyncPool(limit, arr, fn) {}
Promise.all/Promise.race/Promise.settled
0220
- tailwind.css 后续卷起来,目前手上先把 vitepress-wmh 主题包搞出来再说
Promise.allSettled
返回一个合成的 Promise,需要等到所有的 Promise 实例都返回结果时才尘埃落定
Promise.myAllSettled = function (arr) {
return Promise.all(
arr.map((e) => {
return Promise.resolve(e).then(
(res) => {
return {
status: "fulfilled",
value: res,
};
},
(err) => {
return {
status: "rejected",
reason: err,
};
}
);
})
);
};
0221
- 函数重载?如何大白话解释下
- 如何设置二级域名,比如 doc.bythewayer.com 这种?
0222
- 手动实现一个 vue 模版字符串 render
每次都记不住 要命了,为啥会这么难!!!
输入: render(`how to input{{msg}}-{{name}}`, {msg: 'chendap', name: 'wmh'})
输出:'<h1>how to inputchendap-wmh</h1>'
function render(str, data) {
var reg = /\{\{(\w+)\}\}/;
if (reg.test(str)) {
const name = reg.exec(str)[1]; // ok
// const name = RegExp.$1.trim() ok
str = str.replace(reg, data[name])
return render(str, data)
}
return str
}
render(`<h1>how to input{{msg}}-{{name}}</h1>`, {msg: 'chendap', name: 'wmh'})
RegExp.$1 是 RegExp 的一个属性,指的是与正则表达式匹配的第一个 子匹配(以括号为标志)字符串,以此类推,RegExp.$2,RegExp.$3,..RegExp.$99 总共可以有 99 个匹配
0223
- 微信搜索 SEO 如何做的?小程序搜索优化指南
0224
vscode 设置 Typescript 中文错误提示需要打开设置页面,搜索“typescript local”,然后设置中文就行了
利用 js 实现函数重载
function addMethod(obj, name, fn) {
var old = obj[name];
console.log(old, 'BEFORE)
obj[name] = function () {
let arg = Array.from(arguments); // 转换成array
if (fn.length === arg.length) {
fn.apply(this, arg);
} else if (typeof fn === 'function') {
old.apply(this, arg);
}
};
}
// test
var person = { userName: 'bear鲍的小小熊' };
addMethod(person, 'show', function () {
console.log(this.userName + '---->' + 'show1');
});
addMethod(person, 'show', function (str) {
console.log(this.userName + '---->' + str);
});
addMethod(person, 'show', function (a, b) {
console.log(this.userName + '---->' + (a + b));
});
person.show(); // bear鲍的小小熊---->show1
person.show('bkl'); // bear鲍的小小熊---->bkl
person.show(10, 20); // bear鲍的小小熊---->30
0225
- 👍 浅谈 TS 标称类型介绍及社区实现
- unique symbol: TS 里每个 unique symbol 声明都是完全独立的唯一标识,互相不兼容。作为属性加到类型中需要用readonly修饰。
export type CNY = number & {
readonly brand: unique symbol;
};
export type USD = number & {
readonly brand: unique symbol;
};
// 用例
const yuan = 12 as CNY;
const dollar = 5 as USD;
function buyPekingDuck(money: CNY) {} // 只能用 CNY 买北京烤鸭
function buyCocaCola(money: USD) {} // 只能用 USD 买可口可乐
// 类型安全
buyPekingDuck(dollar); // Argument of type 'USD' is not assignable to parameter of type 'CNY'.
buyCocaCola(yuan); // Argument of type 'CNY' is not assignable to parameter of type 'USD'.
0226
- 如何理解 react 中的 副作用应该尽可能放到事件回调中执行?只有很少一部分副作用(比如 setTimeout 这样的计时器)需要放到 useEffect 中?
- 组件卸载时取消异步请求React 中常见的 8 个错误,如何避免?
const Component = () => {
const [data, setData] = useState(null);
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal }).then((data) => setData(data));
return () => {
controller.abort();
};
}, []);
// ...
};
- Ts 中的枚举类型?
0227
- 实现 instanceof 运算符?
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car("Honda", "Accord", 1998);
console.log(auto instanceof Car);
// Expected output: true
console.log(auto instanceof Object);
// Expected output: true
如何实现 instanceof?
// first
function mockInstanceof(left, right) {
var pro = right.__proto__;
while (true) {
if (pro === null) return false;
if (pro == right.prototype) {
return true;
}
pro = pro.__proto__;
}
return false;
}
// second
function mockInstanceof2(left, right) {
let link = left.__proto__; // Object.getPrototypeOf(left)
while (link !== null) {
if (link === right.prototype) return true;
link = link.__proto__; // Object.getPrototypeOf(link)
}
return false;
}
// Third
function mockInstanceof2(left, right) {
return right.prototype.isPrototypeOf(left);
}
0228
- 好像又回到了最开始的地方,在公司的第 1/2/3/4 次搬家,这次位置还是比较满意,终于不用再听到其他额外的声音,也可能为时稍早
- 三四月份是一年除了年末最大的变动,这次不知道经历啥,拥抱变化,坚持输入输出
- 昨天去理发,从 20 涨到 25,茶叶蛋从 1.5 涨到 2 元,唯一不变的只有工资没涨
- 这周完成主题换肤的基本配置,提交版本,乞丐版的发一版也行
- ts 中 interface 设置任意属性
interface CommunityProps {
[propName: string]: any;
}
- 接口类型 graphql?
GraphQL 是一种用于 API 的查询语言,它提供了一种更加高效、强大和灵活的方式来获取数据。使用 GraphQL,我们可以按需获取数据,而不需要在服务器上定义每个 API 端点。这使得开发人员可以更加轻松地定义、更新和扩展 API。
GraphQL 还提供了一些有用的工具和库,例如 GraphiQL,它是一个交互式的 GraphQL IDE,可以帮助我们更好地理解和测试 API。
TIP
如何理解 graphql? 我项目阔以不用,但要知道这是个什么技术