关闭mac合盖休眠
1 | sudo pmset -a disablesleep 1 # 禁用系统休眠 |
1 | sudo pmset -a disablesleep 1 # 禁用系统休眠 |
linux系统是否允许 ping是由好几个因素决定的,如内核参数和防火墙, 几个因素同时允许时才能ping通:
内核参数
1
2
3
4
5# 如果是1则从内核层面忽略所有ICMP ECHO请求
# 也就是Ping这台服务器收不到任何回应
cat /proc/sys/net/ipv4/icmp_echo_ignore_all
# 执行下面这个命令修改这项配置
echo "0" >/proc/sys/net/ipv4/icmp_echo_ignore_all
防火墙:iptables
云防火墙
云厂商一般会给ECS提供云防火墙,这时候需要检查一下安全组规则有没有拒绝ICMP请求
发现一起听歌的后台监控不能正常运行了,吓得我赶紧打开了阿里云看了一眼服务器状态,好家伙磁盘直接100%了。
清理工作启动!
查找大文件实用命令 1
2sudo du -ah --max-depth=1 | sort -h # 按文件(夹)大小排序显示列表
df -h # 用人类可读的方式展示磁盘剩余空间
实用清理命令
清理系统日志 1
2sudo journalctl --vacuum-time=2d # 仅保留最近两天的系统日志,多余的都自动删掉
sudo journalctl --vacuum-size=50M # 仅保留50M大小的系统日志,多余的都自动删掉
清理 PM2 日志 1
pm2 flush app_name
清理 nginx 日志 1
rm /www/wwwlogs/*
恢复故障应用
MongoDB 在磁盘满的情况下,拒绝执行,并且自动停止服务。可以通过以下命令重启:
1
2
3sudo service mongod start # 启动 mongod
sudo service mongod status # 查看 mongod 的状态
pm2 restart app_name # 重启应用以便冲洗连接数据库
时间先后关系:
DOMContentLoaded
——通过 document.addEventListener('DOMContentLoaded', handler)
监听。当浏览器已完全加载 HTML,并构建了 DOM 树时触发,但像 <img />
和 css 样式表这些外部资源可能还未加载完成。 注意:当文档中遇到 <script />
标签时,DOMContentLoaded
事件会等待脚本完全执行结束后再触发。除非带有是 async/defer 属性的脚本或者通过 document.createElement('script')
创建的脚本(这些脚本会异步加载并执行,不会阻塞 DOMContentLoaded
事件)。load
——通过 window.onload
监听。当浏览器不仅完全加载 HTML,图片样式表这些外部资源也加载完成后触发。beforeunload
——通过 window.onbeforeunload
监听。表示用户正在离开,我们可以检查用户是否保存了更改,并询问他是否真的要离开。unload
——通过 window.onunload
监听。表示用户已经离开,我们可以做一些善后工作。防抖和节流都可以用来控制函数执行的频率。
1 | const debounce = require('lodash/debounce'); |
因为这里设置防抖的间隔是 2000ms,而调用 sayHello 是每隔一秒调用一次,所以每当延时一秒的时候,函数又被调用,重新设置了一个新的 2000ms 延时,直到第 10 次调用结束后,这次延时 2000 ms 的间隔内不再有新的函数调用,等延时结束后才真正执行我们所需要防抖的函数:
1 | () => { |
举个极端点的例子,如果在程序运行时,始终保持 1000 ms 的间隔调用函数,而防抖的间隔设置为 2000 ms,那么被防抖的函数永远也不会被执行,因为永远满足不了延时 2000 ms 的时间间隔内这个函数没有被调用的条件。我们把上面那个例子改写一下:
1 | const debounce = require('lodash/debounce'); |
1 | const debounce = (fn, interval) => { |
毫无疑问,debounce 是一个高阶函数,调用它的返回结果是一个函数。在 debounce 中我们还需要一个闭包变量来 timer 来记录定时器,返回的函数是对被防抖函数的封装,主要思想是每次调用函数时,清除之前的定时器(如果有的话),重新设置一个新的定时器,这样就实现了一个简单的防抖函数。
改写一下上面那个例子
1 | const throttle = require('lodash/throttle'); |
这里我们设置了节流的间隔为 5000ms ,函数调用的间隔仍然是 1000ms。注意到在 18:46:864 ~ 18:51:864 这段时间间隔内函数被调用了5次,但实际只被执行了1次,这就是节流的作用。在一个节流间隔内,无论调用函数多少次,在这个间隔内只真正执行函数一次。
节流函数的实现有很多种,这里用时间戳的方式实现。
1 | const throttle = (fn, interval) => { |
即每次成功执行一次函数后,接下来 5000ms 之内的调用都会被忽略,这就是节流的作用。
首先来看一下 Math.random 吧,它随机生成一个 0 (包含) ~ 1 (不包含) 之间的浮点数。
基于此,我们可以实现一个函数来生成指定范围内的随机整数(MDN上的例子):
1 | // 用于理解版 |
技巧是 range 多加个1,然后再用 Math.floor 给向下取整。unit * range + offset 随机生成的是一个包含最小值但不包含最大值+1的浮点数,再向下取整就是一个既包含最小值又包含最大值的整数了,可谓是非常巧妙了。
这样生成的随机整数各整数被生成到的概率也是相等的,我们做个测试:
1 | const probabilities = Array(11).fill(0); |
每个整数被生成到的概率都是10万左右,所以通过这种方式生成的随机整数也是等概率随机生成。
为什么需要前端路由?
以前传统的前端都是一个URL对应一个页面,所以不存在这个问题。随着SPA(single-page application)即单页应用的发展,组件的变化和更新不再对应着URL变化了。但是我们又需要这种对应关系(比如通过一个URL直接访问一个 SPA 应用的子视图),我们急需一个工具专门负责维护组件状态与页面URL之间的对应关系,这就是前端路由的作用所在,如 react 的 react-router 和 vue 的 vue-router。
实现原理?
#hash
这个模式主要关注 location.hash
值,可以通过事件 hashchange
监听 URL 的变化,从而去跳转到对应子页面。
这个模式主要关注 location.pathname
的值,可以通过事件 popstate
监听 URL,但是它有很多局限性,只有做出浏览器动作如用户点击了回退按钮或在JavaScript中调用了history.back()/history.forwad()才会触发事件,下面这些情况不会触发 popstate
事件:
解决思路:
遍历 DOM 中所有的 a 标签,监听 click 事件,手动 pushState 改变浏览器地址,并手动调用 popState 中的回调函数。
在 rust 中没有类似于 typeof
的操作符来判断一个变量的类型,但是我们可以自己写一个函数来打印变量的类型。
1 | use std::any::type_name; |
用法实例如下:
1 | let tup: (i32, f64, u8, bool, &str) = (500, 3.2, 1, false, "Hello World"); |
ReactDOM.render 是 legacy 模式,ReactDOM.createRoot 是 concurrent 模式(不同的更新有不同的优先级,并且更新也是可以被打断的),目前还在实验阶段。this.setState 是同步还是异步的? 在 legacy 模式中,如果触发了 batchedUpdates 就是异步更新,没有触发是同步;在 concurrent 模式中总是异步更新。
可以通过异步调用 this.setState 来避免 batchedUpdates 来实现同步更新。 batchedUpdates 其实是 React 的一个性能优化的点,如果在一次 render 中同步调用了多个 this.setState,React 会将它们合并成一次操作,也就是所谓的批处理。
render 阶段计算出状态变化;commit阶段同步状态变化到视图,分为三个子阶段,beforeMutation, mutation (这也是真正执行DOM操作的) 和 layout。ComponentDidMount 是在 layout 阶段被同步调用的,而 useEffect 是在整个 commit 阶段结束后,被异步调用的。和 cDM 等价的 hook 是 useLayoutEffect。