勤学如春起之苗,不见其增,日有所长;辍学如磨刀之石,不见其损,日有所亏。javascript
我在 github 上新建了一个仓库 日问,天天至少一个问题。有关全栈,graphql,devops,微服务以及软技能,促进职业成长,欢迎交流。html
以诸葛武侯的诫子书与君共勉前端
夫君子之行,静以修身,俭以养德。非澹泊无以明志,非宁静无以至远。夫学须静也,才须学也,非学无以广才,非志无以成学。淫慢则不能励精,险躁则不能治性。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及!java
原文连接,欢迎讨论: 【Q037】linux 有哪些发行版,你最喜欢哪个react
开放问题,不过你至少得知道一个发行版...linux
原文连接,欢迎讨论: 【Q036】http 状态码中 301,302和307有什么区别git
原文连接,欢迎讨论: 【Q035】http 常见的状态码有哪些github
原文连接,欢迎讨论:【Q034】如何实现一个 loading 动画web
原文连接,欢迎讨论: 【Q033】如何对接口进行限流面试
通常采用漏桶算法:
可使用 redis
的计数器实现
固然,这只是大体思路,这时会有两个问题要注意
不过实际实现时注意如下就行了(话说通常也是调用现成的三方库作限流...),能够参考我之前的文章 https://shanyue.tech/post/rate-limit/
原文连接,欢迎讨论:【Q032】js 中什么是 softbind,如何实现
原文连接,欢迎讨论: 【Q031】js 中如何实现 bind
最简单的 bind
一行就能够实现,而在实际面试过程当中也不会考察你太多的边界条件
Function.prototype.fakeBind = function(obj) { return (...args) => this.apply(obj, args) }
测试一下
function f (arg) { console.log(this.a, arg) } // output: 3, 4 f.bind({ a: 3 })(4) // output: 3, 4 f.fakeBind({ a: 3 })(4)
原文连接,欢迎讨论: 【Q030】linux 中如何打印全部网络接口
ifconfig
是最简单最经常使用,可是打印信息太多了
$ ifconfig
netstat
与 ip
也挺好用,特别是它们还能够打印路由表
$ netstat -i
$ ip link $ ip addr
在 redis
处维护一个对象,记录每一个 group 所对应的 connections
/sockets
{ 'Class:201901': [student1Socket, student2Socket] }
当 client 刚连入 server 时,便加入某个特定的组,或者叫 room,好比 student01,刚开始连入 server,可能要加入 room:Student:01
,Class:201901
,Group:10086
$ who $ last
一图胜千言
使用 jsonb_pretty
函数,示例以下
> select jsonb_pretty('{"a": {"b": 4}}'::jsonb) +----------------+ | jsonb_pretty | |----------------| | { | | "a": { | | "b": 4 | | } | | } | +----------------+ SELECT 1 Time: 0.018s
一个简单的 Promise
的粗糙实现,关键点在于
pending
时, thenable
函数由一个队列维护resolved(fulfilled)
时,队列中全部 thenable
函数执行resolved
时, thenable
函数直接执行rejected
状态同理
class Prom { static resolve (value) { if (value && value.then) { return value } return new Prom(resolve => resolve(value)) } constructor (fn) { this.value = undefined this.reason = undefined this.status = 'PENDING' // 维护一个 resolve/pending 的函数队列 this.resolveFns = [] this.rejectFns = [] const resolve = (value) => { // 注意此处的 setTimeout setTimeout(() => { this.status = 'RESOLVED' this.value = value this.resolveFns.forEach(({ fn, resolve: res, reject: rej }) => res(fn(value))) }) } const reject = (e) => { setTimeout(() => { this.status = 'REJECTED' this.reason = e this.rejectFns.forEach(({ fn, resolve: res, reject: rej }) => rej(fn(e))) }) } fn(resolve, reject) } then (fn) { if (this.status === 'RESOLVED') { const result = fn(this.value) // 须要返回一个 Promise // 若是状态为 resolved,直接执行 return Prom.resolve(result) } if (this.status === 'PENDING') { // 也是返回一个 Promise return new Prom((resolve, reject) => { // 推动队列中,resolved 后统一执行 this.resolveFns.push({ fn, resolve, reject }) }) } } catch (fn) { if (this.status === 'REJECTED') { const result = fn(this.value) return Prom.resolve(result) } if (this.status === 'PENDING') { return new Prom((resolve, reject) => { this.rejectFns.push({ fn, resolve, reject }) }) } } } Prom.resolve(10).then(o => o * 10).then(o => o + 10).then(o => { console.log(o) }) return new Prom((resolve, reject) => reject('Error')).catch(e => { console.log('Error', e) })
首参不同,直接上 API
React.cloneElement( element, [props], [...children] ) React.createElement( type, [props], [...children] )
它通常可使用第三方库 clipboard.js 来实现,源码很简单,能够读一读
主要有两个要点
选中主要利用了 Selection API
选中的代码以下
const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range); selectedText = selection.toString();
取消选中的代码以下
window.getSelection().removeAllRanges();
它有现成的第三方库可使用: select.js
复制就比较简单了,execCommand
document.exec('copy')