日问周刊 | 全栈面试汇总 | 第二期

勤学如春起之苗,不见其增,日有所长;辍学如磨刀之石,不见其损,日有所亏。

我在 github 上新建了一个仓库 日问,每天至少一个问题。有关全栈,graphql,devops,微服务以及软技能,促进职业成长,欢迎交流。

以诸葛武侯的诫子书与君共勉

夫君子之行,静以修身,俭以养德。非澹泊无以明志,非宁静无以致远。夫学须静也,才须学也,非学无以广才,非志无以成学。淫慢则不能励精,险躁则不能治性。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及!

【Q037】linux 有哪些发行版,你最喜欢哪一个

原文链接,欢迎讨论: 【Q037】linux 有哪些发行版,你最喜欢哪一个

开放问题,不过你至少得知道一个发行版...

【Q036】http 状态码中 301,302和307有什么区别

原文链接,欢迎讨论: 【Q036】http 状态码中 301,302和307有什么区别

  • 301,Moved Permanently。永久重定向,该操作比较危险,需要谨慎操作:如果设置了301,但是一段时间后又想取消,但是浏览器中已经有了缓存,还是会重定向。
  • 302,Fount。临时重定向,但是会在重定向的时候改变 method: 把 POST 改成 GET,于是有了 307
  • 307,Temporary Redirect。临时重定向,在重定向时不会改变 method

【Q035】http 常见的状态码有哪些

原文链接,欢迎讨论: 【Q035】http 常见的状态码有哪些

【Q034】如何实现一个 loading 动画

原文链接,欢迎讨论:【Q034】如何实现一个 loading 动画

【Q033】如何对接口进行限流]

原文链接,欢迎讨论: 【Q033】如何对接口进行限流

一般采用漏桶算法:

  1. 漏桶初始为空
  2. API 调用是在往漏桶里注水
  3. 漏桶会以一定速率出水
  4. 水满时 API 拒绝调用
漏桶算法

可以使用 redis 的计数器实现

  1. 计数器初始为空
  2. API 调用计数器增加
  3. 给计数器设置过期时间,隔段时间清零,视为一定速率出水
  4. 计数器达到上限时,拒绝调用

当然,这只是大致思路,这时会有两个问题要注意

  1. 最坏情况下的限流是额定限流速率的2倍
  2. 条件竞争问题

不过实际实现时注意以下就好了(话说一般也是调用现成的三方库做限流...),可以参考我以前的文章 https://shanyue.tech/post/rate-limit/

【Q032】js 中什么是 softbind,如何实现

原文链接,欢迎讨论:【Q032】js 中什么是 softbind,如何实现

【Q031】js 中如何实现 bind

原文链接,欢迎讨论: 【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 中如何打印所有网络接口

原文链接,欢迎讨论: 【Q030】linux 中如何打印所有网络接口

ifconfig

ifconfig 是最简单最常用,但是打印信息太多了

$ ifconfig

netstat

netstatip 也挺好用,特别是它们还可以打印路由表

$ netstat -i

ip

$ ip link

$ ip addr

【Q029】websocket 如何向特定的用户组推送消息

redis 处维护一个对象,记录每个 group 所对应的 connections/sockets

{
  'Class:201901': [student1Socket, student2Socket]
}

当 client 刚连入 server 时,便加入某个特定的组,或者叫 room,比如 student01,刚开始连入 server,可能要加入 room:Student:01Class:201901Group:10086

【Q028】在linux中如何获取登录的用户 <img src="https://img.shields.io/badge/linux-fabd14">

【Q028】在linux中如何获取登录的用户 <img src="https://img.shields.io/badge/linux-fabd14">

$ who

$ last

【Q027】在前端开发中,如何获取浏览器的唯一标识 <img src="https://img.shields.io/badge/js-f1da50">

fingerprintjs2

【Q026】如何对接口进行压力测试 <img src="https://img.shields.io/badge/server-blueviolet">

【Q025】简述 socket 建立的过程 <img src="https://img.shields.io/badge/network-blue">

一图胜千言

image

【Q024】在 postgres 中,查询时如何对 jsonb 数据格式化 <img src="https://img.shields.io/badge/db-red">

使用 jsonb_pretty 函数,示例如下

> select jsonb_pretty('{"a": {"b": 4}}'::jsonb)
+----------------+
| jsonb_pretty   |
|----------------|
| {              |
|     "a": {     |
|         "b": 4 |
|     }          |
| }              |
+----------------+
SELECT 1
Time: 0.018s

【Q023】websocket 服务多节点部署时会有什么问题,怎么解决 <img src="https://img.shields.io/badge/server-blueviolet">

借用 redis

【Q022】如何实现一个简单的 Promise <img src="https://img.shields.io/badge/js-f1da50">

一个简单的 Promise 的粗糙实现,关键点在于

  1. pending 时, thenable 函数由一个队列维护
  2. 当状态变为 resolved(fulfilled) 时,队列中所有 thenable 函数执行
  3. 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)
})

【Q021】React 中,cloneElement 与 createElement 各是什么,有什么区别 <img src="https://img.shields.io/badge/react-61dafb">

首参不一样,直接上 API

React.cloneElement(
  element,
  [props],
  [...children]
)

React.createElement(
  type,
  [props],
  [...children]
)

【Q020】如何实现一个分布式锁 <img src="https://img.shields.io/badge/redis-0d4e99"> <img src="https://img.shields.io/badge/server-blueviolet">

【Q019】如何实现选中复制的功能 <img src="https://img.shields.io/badge/html-ea4628">

它一般可以使用第三方库 clipboard.js 来实现,源码很简单,可以读一读

主要有两个要点

  1. 选中
  2. 复制

选中

选中主要利用了 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')


我是山月,一个喜欢跑步与爬山的程序员,我会定期分享全栈文章在个人公众号中。如果你对全栈面试,前端工程化,graphql,devops,个人服务器运维以及微服务感兴趣的话,可以关注我

如果你对全栈面试,前端工程化,graphql,devops,个人服务器运维以及微服务感兴趣的话,可以关注我
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,511评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,495评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,595评论 0 225
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,558评论 0 190
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,715评论 3 270
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,672评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,112评论 2 291
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,837评论 0 181
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,417评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,928评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,316评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,773评论 2 234
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,253评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,827评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,440评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,523评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,583评论 2 249

推荐阅读更多精彩内容

  • # 测试服务器情况和技术能力 17-11-26 www.worldhm.cn http://sso.worldhm...
    时间清单阅读 272评论 0 0
  • 1.Linux基础和分布式集群技术 学完此阶段可掌握的核心能力: 熟练使用Linux,熟练安装Linux上的软件,...
    大数据05阅读 375评论 0 0
  • 子夏问曰:巧笑倩兮,美目盼兮,素以为绚兮。何谓也。子曰:绘事后素。曰:礼后乎。子曰:起予者,商也。始可与言诗已矣。...
    梁光宇阅读 945评论 9 10
  • 现在的项目越来越多,很多人时间都浪费在选择项目上了,当你选好项目后,你会发现那些在同起跑线上的人早已经赚到了第一桶...
    崔帝谋阅读 328评论 0 1
  • 从我自己的经历而言,我不相信命运,我信仰方法论。凡事皆有规律。任何一个人,通过学习,掌握规律,不断努力,都可能拥有...
    一采阅读 114评论 0 1