├── 前端 ├── JD.md ├── Mobile-Interview.md ├── README.md ├── Node-Interview.md ├── Web-Interview.md ├── React-Interview.md └── JavaScript-Interview.md ├── 产品经理 ├── JD.md └── README.md ├── 测试与运维 ├── JD.md └── README.md ├── 算法与大数据 ├── JD.md ├── MachineLearning-Interview.md ├── Statistics-Interview.md └── README.md ├── 大厂面试集锦 ├── 蚂蚁金服.md ├── README.md └── 阿里巴巴.md ├── 面试基础 ├── 简历提升.md ├── 面试技巧.md ├── README.md ├── 面试流程.md └── 智力题.md ├── 服务端架构 ├── JD.md ├── MicroService-Interview.md ├── DistributedSystem-Interview.md ├── Database-Interview.md ├── Linux-Interview.md ├── HA-Interview.md ├── Architecture-Interview.md ├── Go-Interview.md ├── DistributedComputing-Interview.md ├── Virtualization-Interview.md ├── Java-Interview.md └── README.md ├── CS 通识 ├── AlgoDS-Interview.md ├── DesignPattern-Interview.md ├── Workflow-Interview.md ├── Network-Interview.md └── README.md ├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ ├── custom.md │ ├── feature_request.md │ └── bug_report.md ├── LICENSE └── README.md /前端/JD.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /产品经理/JD.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /测试与运维/JD.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /算法与大数据/JD.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /大厂面试集锦/蚂蚁金服.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /面试基础/简历提升.md: -------------------------------------------------------------------------------- 1 | # 简历提升 -------------------------------------------------------------------------------- /面试基础/面试技巧.md: -------------------------------------------------------------------------------- 1 | # 面试技巧 2 | -------------------------------------------------------------------------------- /产品经理/README.md: -------------------------------------------------------------------------------- 1 | # 产品经理面试题集锦 2 | -------------------------------------------------------------------------------- /服务端架构/JD.md: -------------------------------------------------------------------------------- 1 | # JD | 服务端架构的职位模型 2 | -------------------------------------------------------------------------------- /服务端架构/MicroService-Interview.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /测试与运维/README.md: -------------------------------------------------------------------------------- 1 | # 测试与运维面试题集锦 2 | -------------------------------------------------------------------------------- /服务端架构/DistributedSystem-Interview.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /算法与大数据/MachineLearning-Interview.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CS 通识/AlgoDS-Interview.md: -------------------------------------------------------------------------------- 1 | # 数据结构与算法面试题 2 | -------------------------------------------------------------------------------- /前端/Mobile-Interview.md: -------------------------------------------------------------------------------- 1 | # Mobile Interview 2 | -------------------------------------------------------------------------------- /算法与大数据/Statistics-Interview.md: -------------------------------------------------------------------------------- 1 | # 数理统计面试题 2 | -------------------------------------------------------------------------------- /CS 通识/DesignPattern-Interview.md: -------------------------------------------------------------------------------- 1 | # 编程范式与设计模式面试题 2 | -------------------------------------------------------------------------------- /服务端架构/Database-Interview.md: -------------------------------------------------------------------------------- 1 | # Database Interview 2 | -------------------------------------------------------------------------------- /大厂面试集锦/README.md: -------------------------------------------------------------------------------- 1 | # 大厂面试集锦 2 | 3 | 本章收录了很多 BAT、TMD 的面试题。 4 | -------------------------------------------------------------------------------- /CS 通识/Workflow-Interview.md: -------------------------------------------------------------------------------- 1 | # Workflow Interview 2 | 3 | # Git 4 | -------------------------------------------------------------------------------- /服务端架构/Linux-Interview.md: -------------------------------------------------------------------------------- 1 | # Linux Interview | Linux 与操作系统面试题集锦 2 | -------------------------------------------------------------------------------- /面试基础/README.md: -------------------------------------------------------------------------------- 1 | # 面试基础 2 | 3 | 本章对于面试前的简历准备与提升、面试的流程、面试中常用的技巧与一些智力题目进行盘点讨论。 4 | -------------------------------------------------------------------------------- /CS 通识/Network-Interview.md: -------------------------------------------------------------------------------- 1 | # Network Interview 2 | 3 | # HTTP 4 | 5 | - 一个 TCP 连接可以发多少个 HTTP 请求? -------------------------------------------------------------------------------- /大厂面试集锦/阿里巴巴.md: -------------------------------------------------------------------------------- 1 | # 阿里巴巴 2 | 3 | # 链接 4 | 5 | - https://mp.weixin.qq.com/s/yZSywiavq0F8wfif28nnzA -------------------------------------------------------------------------------- /服务端架构/HA-Interview.md: -------------------------------------------------------------------------------- 1 | # HA Interview | 高可用面试题 2 | 3 | ![](https://i.postimg.cc/Cx3m9mYH/image.png) 4 | -------------------------------------------------------------------------------- /面试基础/面试流程.md: -------------------------------------------------------------------------------- 1 | # 面试流程 2 | 3 | # 链接 4 | 5 | - https://www.zhihu.com/question/290543744/answer/595815243 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.xmind filter=lfs diff=lfs merge=lfs -text 2 | *.zip filter=lfs diff=lfs merge=lfs -text 3 | -------------------------------------------------------------------------------- /服务端架构/Architecture-Interview.md: -------------------------------------------------------------------------------- 1 | # Architecture Interview 2 | 3 | # DDD 4 | 5 | - 如何理解领域驱动设计?为什么需要领域驱动设计,它的优势是什么?在实际应用中如何实践领域驱动设计? 6 | -------------------------------------------------------------------------------- /服务端架构/Go-Interview.md: -------------------------------------------------------------------------------- 1 | # Go Interview 2 | 3 | ![](https://i.postimg.cc/KvBnMY5N/image.png) 4 | 5 | # 链接 6 | 7 | - https://studygolang.com/articles/17796 8 | -------------------------------------------------------------------------------- /前端/README.md: -------------------------------------------------------------------------------- 1 | # Web Interview | Web 面试题集锦 2 | 3 | [Web Interview]() 是 [Awesome Interviews]() 系列的组成,涵盖了笔者在日常积累中总结而来的可成为面试题的知识要点与场景案例。 4 | 5 | 本文所提及的问题皆可在下列文档矩阵中寻找到解答,请自行索引。 6 | -------------------------------------------------------------------------------- /CS 通识/README.md: -------------------------------------------------------------------------------- 1 | # 计算机科学与技术通识面试题 2 | 3 | # 版本控制与团队协作 4 | 5 | ## Git 6 | 7 | - Git Rebase 和 Merge 有什么区别? 8 | 9 | # AlgoDS | 数据结构与算法 10 | 11 | # Network & OS | 网络与操作系统 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /前端/Node-Interview.md: -------------------------------------------------------------------------------- 1 | # Node Interview 2 | 3 | - NPM 安装依赖的时候是如何处理依赖冲突问题的? 4 | 5 | # Internals 6 | 7 | - Node 的底层事件模型是如何实现的? 8 | 9 | - Node 的异步 IO 在操作系统层面是如何实现的? 10 | 11 | # Framework 12 | 13 | # GraphQL 14 | 15 | - GraphQL 与 REST 在设计理念上有和区别?在实际使用 GraphQL 的过程中有何痛点? 16 | -------------------------------------------------------------------------------- /服务端架构/DistributedComputing-Interview.md: -------------------------------------------------------------------------------- 1 | # 分布式计算面试题集锦 2 | 3 | # 并发编程 4 | 5 | - 并发与并行的区别是什么?同步、异步、阻塞、非阻塞的区别是什么?在实际的编程中会如何体现这些区别? 6 | 7 | - 并发场景下是否线程数越多越好?如何衡量引入并发多线程后的性能、效率得失? 8 | 9 | - 进程、线程、协程的区别是什么?Java 中是否一定需要引入协程模型? 10 | 11 | - Linux 中的线程是如何实现的?Java 的线程与 Linux 中的线程有何联系或区别? 12 | -------------------------------------------------------------------------------- /服务端架构/Virtualization-Interview.md: -------------------------------------------------------------------------------- 1 | # 虚拟化与编排面试集锦 2 | 3 | # Kubernetes 4 | 5 | - 为什么在Kubernetes我们不直接使用一个单独的容器(container),而是用Pod来封装一个或多个容器呢?为什么我们要运行多个容器呢?我们能将我们所有的应用程序都放到一个容器里面运行么? 6 | 7 | - Pod,Deployment,Service 与 Ingress 分别在 K8s 集群中起到了怎样的作用? 8 | 9 | - Service 定义中的 port,targetPort 与 nodePort 各自的区别是什么? 10 | 11 | - 对于使用 nodePort 方式对外暴露的服务,其数据网络流向是什么样子的? 12 | -------------------------------------------------------------------------------- /服务端架构/Java-Interview.md: -------------------------------------------------------------------------------- 1 | # Awesome Java Interview | Java 面试题集锦 2 | 3 | # 语法基础 4 | 5 | # 数据结构 6 | 7 | # 并发编程 8 | 9 | ## 锁 10 | 11 | ## 同步 12 | 13 | - CountDownLatch、CyclicBarrier、Semaphore 共同之处与区别以及各自使用场景? 14 | 15 | ## NIO 16 | 17 | ## Akka 18 | 19 | # Spring 20 | 21 | ## MyBatis 22 | 23 | ## Hibernate 24 | 25 | - 简述下 Hibernate 的优劣特性。 26 | 27 | # Toolkits & Framework 28 | -------------------------------------------------------------------------------- /算法与大数据/README.md: -------------------------------------------------------------------------------- 1 | # 数据科学、机器学习、深度学习面试题 2 | 3 | 1、决策树的实现、ID3、C4.5、CART(贝壳) 4 | 2、CART 回归树是怎么实现的?(贝壳) 5 | 3、CART 分类树和 ID3 以及 C4.5 有什么区别(贝壳) 6 | 4、剪枝有哪几种方式(贝壳) 7 | 5、树集成模型有哪几种实现方式?(贝壳)boosting 和 bagging 的区别是什么?(知乎、阿里) 8 | 6、随机森林的随机体现在哪些方面(贝壳、阿里) 9 | 7、AdaBoost 是如何改变样本权重,GBDT 分类树的基模型是?(贝壳) 10 | 8、gbdt,xgboost,lgbm 的区别(百度、滴滴、阿里,头条) 11 | 9、bagging 为什么能减小方差?(知乎) 12 | 13 | # 链接 14 | 15 | - https://www.zhihu.com/question/62482926 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /面试基础/智力题.md: -------------------------------------------------------------------------------- 1 | # 智力题 2 | 3 | # Monty Hall Problem | 三门问题 4 | 5 | 三门问题(Monty Hall problem)亦称为蒙提霍尔问题、蒙特霍问题或蒙提霍尔悖论,大致出自美国的电视游戏节目 Let’s Make a Deal。问题名字来自该节目的主持人蒙提·霍尔(Monty Hall)。参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门会否增加参赛者赢得汽车的概率?如果严格按照上述的条件,即主持人清楚地知道,哪扇门后是羊,那么答案是会。不换门的话,赢得汽车的概率是 1/3。换门的话,赢得汽车的概率是 2/3。 6 | 7 | $$ 8 | P(汽车在 A 门|最初选择 A 门,主持人打开 B 门)=\frac{P(最初选择 A 门,主持人打开 B 门|汽车在 A 门)P(汽车在 A 门)}{P(最初选择 A 门,主持人打开 B 门)} \\ 9 | P(汽车在 B 门|最初选择 A 门,主持人打开 B 门)=\frac{P(最初选择 A 门,主持人打开 B 门|汽车在 B 门)P(汽车在 B 门)}{P(最初选择 A 门,主持人打开 B 门)} \\ 10 | P(汽车在 C 门|最初选择 A 门,主持人打开 B 门)=\frac{P(最初选择 A 门,主持人打开 B 门|汽车在 C 门)P(汽车在 C 门)}{P(最初选择 A 门,主持人打开 B 门)} 11 | $$ 12 | 13 | 各个概率计算如下 14 | 15 | $$ 16 | P(汽车在 A 门|最初选择 A 门,主持人打开 B 门)=\frac{(1/2)⋅(1/3)}{1/2}=\frac{1}{3} \\ 17 | P(汽车在 B 门|最初选择 A 门,主持人打开 B 门)=\frac{0⋅(1/3)}{1/2}=0 \\ 18 | P(汽车在 C 门|最初选择 A 门,主持人打开 B 门)=\frac{1⋅(1/3)}{1/2}=\frac{2}{3} 19 | $$ 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 王下邀月熊 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /前端/Web-Interview.md: -------------------------------------------------------------------------------- 1 | # Web Interview 2 | 3 | # 语法基础 4 | 5 | ## HTML 6 | 7 | ## CSS 8 | 9 | ## DOM 10 | 11 | # 工程实践 12 | 13 | ## 客户端可用性 14 | 15 | - 如何设计一个客户端错误上报系统?应该如何捕获常见的浏览器错误? 16 | 17 | - 如果设计一个客户端实时录屏系统,可能的技术挑战点会在哪里?应该如何去设计前后端架构? 18 | 19 | ## 状态管理 20 | 21 | - Redux 的设计理念,其与 Flux 的区别?为什么 Redux 的 Store 会使用不可变数据类型? 22 | 23 | - Redux 中的 Reducer 为何要设置为纯函数?常见的 Side Effects 应当在哪个模块中处理?combineReducer 函数是如何实现的? 24 | 25 | - Redux 的中间件是如何实现的?如何在 Redux 中实现简单的 Promise 中间件? 26 | 27 | - Redux 常见的异步处理机制,简单的 Thunk 组件实现? 28 | 29 | - Redux Sagas 为何要使用 Generator?put, get 等函数的原理是什么?其是如何处理 Effects 的? 30 | 31 | - MobX 是如何实现响应式监听的?MobX 与 Redux 相比其适用场景、工程案例上有何差异? 32 | 33 | - Dva 中的典型模型由哪几个部分组成,各自负责些什么? 34 | 35 | ## 响应式界面 36 | 37 | - 如何实现动态主题切换的效果? 38 | 39 | # 架构与优化 40 | 41 | - 简单概述浏览器工作原理,即从用户输入某个 URL 开始到渲染,经历了哪些主要的步骤?浏览器的核心组件包含哪些? 42 | 43 | - 如何设计一个 JavaScript 应用沙箱? 44 | 45 | # React 46 | 47 | - 为何在 JSX 或者 TSX 的文件首部需要引入 React? 48 | 49 | - 在 Antd 中如何实现主题切换的特性,如何在单个项目中打包多个不同版本的 Antd? 50 | 51 | - Hooks 函数式组件与类组件相比各有何优劣? 52 | 53 | - 猜想一下,React DevTools 是如何监听 React 的状态变化? 54 | 55 | - 调用 setState 之后发生了什么? 56 | 57 | - React 中 Element 与 Component 的区别是? 58 | 59 | - 在什么情况下你会优先选择使用 Class Component 而不是 Functional Component? 60 | 61 | - React 中 keys 的作用是什么? 62 | 63 | - 如果你创建了类似于下面的 `Twitter` 元素,那么它相关的类定义是啥样子的? 64 | 65 | ```js 66 | 67 | {user => (user === null ? : )} 68 | 69 | ``` 70 | 71 | - Controlled Component 与 Uncontrolled Component 之间的区别是什么? 72 | 73 | - 在生命周期中的哪一步你应该发起 AJAX 请求? 74 | 75 | - shouldComponentUpdate 的作用是啥以及为何它这么重要? 76 | 77 | - 如何告诉 React 它应该编译生产环境版本? 78 | 79 | - 为什么我们需要使用 React 提供的 Children API 而不是 JavaScript 的 map? 80 | 81 | - 概述下 React 中的事件处理逻辑? 82 | 83 | - createElement 与 cloneElement 的区别是什么? 84 | 85 | - 传入 setState 函数的第二个参数的作用是什么? 86 | 87 | # Vue 88 | 89 | - Vue 单文件组件是如何解析的?Vue 中是否使用到了 Virtual DOM? 90 | 91 | - v-if 指令是如何实现的? 92 | 93 | - vue-class-component 是如何实现的?如何在页面跳转前后添加自定义的操作?如何自定义装饰器? 94 | 95 | # 链接 96 | 97 | - https://zhuanlan.zhihu.com/p/74258351 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://i.postimg.cc/LXfPysx5/image.png) 2 | 3 | # Awesome Interviews 4 | 5 | 古语有云,知行合一,学以致用,Awesome Interviews 系列不仅仅是为了应对面试,也是对整个 ITCS 体系融会贯通的程度的检验;同时 Awesome Interviews 也包含了笔者多年面试与考察候选人的心得体会。 6 | 7 | - 点面结合:网状问题点状问,点状问题网状问,如果是一个复杂的网状问题,你就考他是不是能够三言两语跟外行说清楚。如果是一个简单的问题呢?你就看他能不能把它还原成一个知识网络。 8 | 9 | - 正反结合:对于某个技术、框架,不仅要问它的优势,也要问在实际应用过程中感受到的痛点与不足。 10 | 11 | # Home & More | 延伸阅读 12 | 13 | ![](https://i.postimg.cc/CMDmg2SQ/image.png) 14 | 15 | 您可以通过以下导航来在 Gitbook 中阅读笔者的系列文章,涵盖了技术资料归纳、编程语言与理论、Web 与大前端、服务端开发与基础架构、云计算与大数据、数据科学与人工智能、产品设计等多个领域: 16 | 17 | - 知识体系:《[Awesome Lists | CS 资料集锦](https://ngte-al.gitbook.io/i/)》、《[Awesome CheatSheets | 速学速查手册](https://ngte-ac.gitbook.io/i/)》、《[Awesome Interviews | 求职面试必备](https://github.com/wx-chevalier/Awesome-Interviews)》、《[Awesome RoadMaps | 程序员进阶指南](https://github.com/wx-chevalier/Awesome-RoadMaps)》、《[Awesome MindMaps | 知识脉络思维脑图](https://github.com/wx-chevalier/Awesome-MindMaps)》、《[Awesome-CS-Books | 开源书籍(.pdf)汇总](https://github.com/wx-chevalier/Awesome-CS-Books)》 18 | 19 | - 编程语言:《[编程语言理论](https://ngte-pl.gitbook.io/i/)》、《[Java 实战](https://ngte-pl.gitbook.io/i/java/java)》、《[JavaScript 实战](https://ngte-pl.gitbook.io/i/javascript/javascript)》、《[Go 实战](https://ngte-pl.gitbook.io/i/go/go)》、《[Python 实战](https://ngte-pl.gitbook.io/i/python/python)》、《[Rust 实战](https://ngte-pl.gitbook.io/i/rust/rust)》 20 | 21 | - 软件工程、模式与架构:《[编程范式与设计模式](https://ngte-se.gitbook.io/i/)》、《[数据结构与算法](https://ngte-se.gitbook.io/i/)》、《[软件架构设计](https://ngte-se.gitbook.io/i/)》、《[整洁与重构](https://ngte-se.gitbook.io/i/)》、《[研发方式与工具](https://ngte-se.gitbook.io/i/)》 22 | 23 | * Web 与大前端:《[现代 Web 开发基础与工程实践](https://ngte-web.gitbook.io/i/)》、《[数据可视化](https://ngte-fe.gitbook.io/i/)》、《[iOS](https://ngte-fe.gitbook.io/i/)》、《[Android](https://ngte-fe.gitbook.io/i/)》、《[混合开发与跨端应用](https://ngte-fe.gitbook.io/i/)》 24 | 25 | * 服务端开发实践与工程架构:《[服务端基础](https://ngte-be.gitbook.io/i/)》、《[微服务与云原生](https://ngte-be.gitbook.io/i/)》、《[测试与高可用保障](https://ngte-be.gitbook.io/i/)》、《[DevOps](https://ngte-be.gitbook.io/i/)》、《[Node](https://ngte-be.gitbook.io/i/)》、《[Spring](https://github.com/wx-chevalier/Spring-Series)》、《[信息安全与渗透测试](https://ngte-be.gitbook.io/i/)》 26 | 27 | * 分布式基础架构:《[分布式系统](https://ngte-infras.gitbook.io/i/)》、《[分布式计算](https://ngte-infras.gitbook.io/i/)》、《[数据库](https://ngte-infras.gitbook.io/i/)》、《[网络](https://ngte-infras.gitbook.io/i/)》、《[虚拟化与编排](https://ngte-infras.gitbook.io/i/)》、《[云计算与大数据](https://ngte-infras.gitbook.io/i/)》、《[Linux 与操作系统](https://ngte-infras.gitbook.io/i/)》 28 | 29 | * 数据科学,人工智能与深度学习:《[数理统计](https://ngte-aidl.gitbook.io/i/)》、《[数据分析](https://ngte-aidl.gitbook.io/i/)》、《[机器学习](https://ngte-aidl.gitbook.io/i/)》、《[深度学习](https://ngte-aidl.gitbook.io/i/)》、《[自然语言处理](https://ngte-aidl.gitbook.io/i/)》、《[工具与工程化](https://ngte-aidl.gitbook.io/i/)》、《[行业应用](https://ngte-aidl.gitbook.io/i/)》 30 | 31 | * 产品设计与用户体验:《[产品设计](https://ngte-pd.gitbook.io/i/)》、《[交互体验](https://ngte-pd.gitbook.io/i/)》、《[项目管理](https://ngte-pd.gitbook.io/i/)》 32 | 33 | * 行业应用:《[行业迷思](https://github.com/wx-chevalier/Business-Series)》、《[功能域](https://github.com/wx-chevalier/Business-Series)》、《[电子商务](https://github.com/wx-chevalier/Business-Series)》、《[智能制造](https://github.com/wx-chevalier/Business-Series)》 34 | 35 | 此外,你还可前往 [xCompass](https://wx-chevalier.github.io/home/#/search) 交互式地检索、查找需要的文章/链接/书籍/课程;或者在 [MATRIX 文章与代码索引矩阵](https://github.com/wx-chevalier/Developer-Zero-To-Mastery)中查看文章与项目源代码等更详细的目录导航信息。最后,你也可以关注微信公众号:『**某熊的技术之路**』以获取最新资讯。 36 | -------------------------------------------------------------------------------- /前端/React-Interview.md: -------------------------------------------------------------------------------- 1 | - 调用 setState 之后发生了什么? 2 | 3 | 在代码中调用 `setState` 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。 4 | 5 | - React 中 Element 与 Component 的区别是? 6 | 7 | 简单而言,React Element 是描述屏幕上所见内容的数据结构,是对于 UI 的对象表述。典型的 React Element 就是利用 JSX 构建的声明式代码片然后被转化为 `createElement` 的调用组合。而 React Component 则是可以接收参数输入并且返回某个 React Element 的函数或者类。更多介绍可以参考[React Elements vs React Components](https://tylermcginnis.com/react-elements-vs-react-components/)。 8 | 9 | - 在什么情况下你会优先选择使用 Class Component 而不是 Functional Component? 10 | 11 | 在组件需要包含内部状态或者使用到生命周期函数的时候使用 Class Component ,否则使用函数式组件。 12 | 13 | - React 中 refs 的作用是什么? 14 | 15 | Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。我们可以为元素添加`ref`属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回: 16 | 17 | ```js 18 | class CustomForm extends Component { 19 | handleSubmit = () => { 20 | console.log('Input Value: ', this.input.value); 21 | }; 22 | render() { 23 | return ( 24 |
25 |   (this.input = input)} /> {' '} 26 |  {' '} 27 |
28 | ); 29 | } 30 | } 31 | ``` 32 | 33 | 上述代码中的`input`域包含了一个`ref`属性,该属性声明的回调函数会接收`input`对应的 DOM 元素,我们将其绑定到`this`指针以便在其他的类函数中使用。另外值得一提的是,refs 并不是类组件的专属,函数式组件同样能够利用闭包暂存其值: 34 | 35 | ```js 36 | function CustomForm({ handleSubmit }) { 37 | let inputElement; 38 | return ( 39 |
handleSubmit(inputElement.value)}> 40 |   (inputElement = input)} /> {' '} 41 |  {' '} 42 |
43 | ); 44 | } 45 | ``` 46 | 47 | - React 中 keys 的作用是什么? 48 | 49 | Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。 50 | 51 | ```js 52 | render () { 53 |   return ( 54 |   59 |   ) 60 | } 61 | ``` 62 | 63 | 在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 Key 的重要性。 64 | 65 | - 如果你创建了类似于下面的 `Twitter` 元素,那么它相关的类定义是啥样子的? 66 | 67 | ```js 68 | 69 | {user => (user === null ? : )} 70 | 71 | ``` 72 | 73 | ```js 74 | import React, { Component, PropTypes } from 'react'; 75 | import fetchUser from 'twitter'; 76 | // fetchUser take in a username returns a promise 77 | // which will resolve with that username's data. 78 | class Twitter extends Component { 79 | // finish this 80 | } 81 | ``` 82 | 83 | 如果你还不熟悉回调渲染模式(Render Callback Pattern),这个代码可能看起来有点怪。这种模式中,组件会接收某个函数作为其子组件,然后在渲染函数中以`props.children`进行调用: 84 | 85 | ```js 86 | import React, { Component, PropTypes } from 'react'; 87 | import fetchUser from 'twitter'; 88 | class Twitter extends Component { 89 | state = { 90 | user: null 91 | }; 92 | static propTypes = { 93 | username: PropTypes.string.isRequired 94 | }; 95 | componentDidMount() { 96 | fetchUser(this.props.username).then(user => this.setState({ user })); 97 | } 98 | render() { 99 | return this.props.children(this.state.user); 100 | } 101 | } 102 | ``` 103 | 104 | 这种模式的优势在于将父组件与子组件解耦和,父组件可以直接访问子组件的内部状态而不需要再通过 Props 传递,这样父组件能够更为方便地控制子组件展示的 UI 界面。譬如产品经理让我们将原本展示的`Badge`替换为`Profile`,我们可以轻易地修改下回调函数即可: 105 | 106 | ```js 107 | 108 |   {user => (user === null ? : )} 109 | 110 | ``` 111 | 112 | - Controlled Component 与 Uncontrolled Component 之间的区别是什么? 113 | 114 | React 的核心组成之一就是能够维持内部状态的自治组件,不过当我们引入原生的 HTML 表单元素时(input,select,textarea 等),我们是否应该将所有的数据托管到 React 组件中还是将其仍然保留在 DOM 元素中呢?这个问题的答案就是受控组件与非受控组件的定义分割。受控组件(Controlled Component)代指那些交由 React 控制并且所有的表单数据统一存放的组件。譬如下面这段代码中`username`变量值并没有存放到 DOM 元素中,而是存放在组件状态数据中。任何时候我们需要改变`username`变量值时,我们应当调用`setState`函数进行修改。 115 | 116 | ```js 117 | class ControlledForm extends Component { 118 | state = { 119 | username: '' 120 | }; 121 | updateUsername = e => { 122 | this.setState({ 123 | username: e.target.value 124 | }); 125 | }; 126 | handleSubmit = () => {}; 127 | render() { 128 | return ( 129 |
130 | {' '} 131 | 136 |  {' '} 137 |
138 | ); 139 | } 140 | } 141 | ``` 142 | 143 | 而非受控组件(Uncontrolled Component)则是由 DOM 存放表单数据,并非存放在 React 组件中。我们可以使用 refs 来操控 DOM 元素: 144 | 145 | ```js 146 | class UnControlledForm extends Component { 147 | handleSubmit = () => { 148 | console.log('Input Value: ', this.input.value); 149 | }; 150 | render() { 151 | return ( 152 |
153 | (this.input = input)} /> 154 |  {' '} 155 |
156 | ); 157 | } 158 | } 159 | ``` 160 | 161 | 竟然非受控组件看上去更好实现,我们可以直接从 DOM 中抓取数据,而不需要添加额外的代码。不过实际开发中我们并不提倡使用非受控组件,因为实际情况下我们需要更多的考虑表单验证、选择性的开启或者关闭按钮点击、强制输入格式等功能支持,而此时我们将数据托管到 React 中有助于我们更好地以声明式的方式完成这些功能。引入 React 或者其他 MVVM 框架最初的原因就是为了将我们从繁重的直接操作 DOM 中解放出来。 162 | 163 | - 在生命周期中的哪一步你应该发起 AJAX 请求? 164 | 165 | 我们应当将 AJAX 请求放到 componentDidMount 函数中执行,主要原因有下: 166 | 167 | - React 下一代调和算法 Fiber 会通过开始或停止渲染的方式优化应用性能,其会影响到 componentWillMount 的触发次数。对于 componentWillMount 这个生命周期函数的调用次数会变得不确定,React 可能会多次频繁调用 componentWillMount。如果我们将 AJAX 请求放到 componentWillMount 函数中,那么显而易见其会被触发多次,自然也就不是好的选择。 168 | 169 | - 如果我们将 AJAX 请求放置在生命周期的其他函数中,我们并不能保证请求仅在组件挂载完毕后才会要求响应。如果我们的数据请求在组件挂载之前就完成,并且调用了`setState`函数将数据添加到组件状态中,对于未挂载的组件则会报错。而在 componentDidMount 函数中进行 AJAX 请求则能有效避免这个问题。 170 | 171 | - shouldComponentUpdate 的作用是啥以及为何它这么重要? 172 | 173 | shouldComponentUpdate 允许我们手动地判断是否要进行组件更新,根据组件的应用场景设置函数的合理返回值能够帮我们避免不必要的更新。 174 | 175 | - 如何告诉 React 它应该编译生产环境版本? 176 | 177 | 通常情况下我们会使用 Webpack 的 DefinePlugin 方法来将 NODE_ENV 变量值设置为 production。编译版本中 React 会忽略 propType 验证以及其他的告警信息,同时还会降低代码库的大小,React 使用了 Uglify 插件来移除生产环境下不必要的注释等信息。 178 | 179 | - 为什么我们需要使用 React 提供的 Children API 而不是 JavaScript 的 map? 180 | 181 | `props.children`并不一定是数组类型,譬如下面这个元素: 182 | 183 | ```jsx 184 | 185 |  

Welcome.

186 |
187 | ``` 188 | 189 | 如果我们使用`props.children.map`函数来遍历时会受到异常提示,因为在这种情况下`props.children`是对象(object)而不是数组(array)。React 当且仅当超过一个子元素的情况下会将`props.children`设置为数组,就像下面这个代码片: 190 | 191 | ```jsx 192 | 193 |

Welcome.

 

props.children will now be an array

194 |
195 | ``` 196 | 197 | 这也就是我们优先选择使用`React.Children.map`函数的原因,其已经将`props.children`不同类型的情况考虑在内了。 198 | 199 | - 概述下 React 中的事件处理逻辑 200 | 201 | 为了解决跨浏览器兼容性问题,React 会将浏览器原生事件(Browser Native Event)封装为合成事件(SyntheticEvent)传入设置的事件处理器中。这里的合成事件提供了与原生事件相同的接口,不过它们屏蔽了底层浏览器的细节差异,保证了行为的一致性。另外有意思的是,React 并没有直接将事件附着到子元素上,而是以单一事件监听器的方式将所有的事件发送到顶层进行处理。这样 React 在更新 DOM 的时候就不需要考虑如何去处理附着在 DOM 上的事件监听器,最终达到优化性能的目的。 202 | 203 | - createElement 与 cloneElement 的区别是什么? 204 | 205 | createElement 函数是 JSX 编译之后使用的创建 React Element 的函数,而 cloneElement 则是用于复制某个元素并传入新的 Props。 206 | 207 | - 传入 setState 函数的第二个参数的作用是什么? 208 | 209 | 该函数会在`setState`函数调用完成并且组件开始重渲染的时候被调用,我们可以用该函数来监听渲染是否完成: 210 | 211 | ```js 212 | this.setState({ username: 'tylermcginnis33' }, () => 213 | console.log('setState has finished and the component has re-rendered.') 214 | ); 215 | ``` 216 | 217 | - 下述代码有错吗? 218 | 219 | ```js 220 | this.setState((prevState, props) => { 221 | return { 222 | streak: prevState.streak + props.count 223 | }; 224 | }); 225 | ``` 226 | 227 | 这段代码没啥问题,不过只是不太常用罢了,详细可以参考 [React 中 setState 同步更新策略](https://zhuanlan.zhihu.com/p/24781259?refer=wx-chevalier)。 228 | -------------------------------------------------------------------------------- /服务端架构/README.md: -------------------------------------------------------------------------------- 1 | # Backend Interview | 服务端架构面试题集锦 2 | 3 | [Backend Interview]() 是 [Awesome Interviews]() 系列的组成,涵盖了笔者在日常积累中总结而来的可成为面试题的知识要点与场景案例。 4 | 5 | 本文所提及的问题皆可在下列文档矩阵中寻找到解答,请自行索引。 6 | 7 | 全局唯一有序 ID。 snowflake ,timestamp 加前面,然后后面加机器 id 等冯诺依曼体系 8 | shell 命令的执行过程信息熵程序运行中的栈式结构,栈溢出攻击 9 | TCP/IP 有关知识。TCP 传输层加端口号,IP 网络层加 ip 地址;路由器就主要工作在 IP 网络层同步与阻塞并行与并发 10 | Java 线程的本质,内核线程与用户线程,线程调度,并行级别内核态与用户态,中断 11 | CPU 与内存与磁盘缓存行与伪共享内存分配管理,段页式。jemalloc 12 | 13 | Java 程序的运行原理普通可执行程序的运行原理缓存行与伪共享。两个面试官都问,可见十分重要,还好都答出来了从浏览器发出请求开始,到服务端应用接受到请求为止的过程 14 | HashMap ,hash 碰撞,hash 算法的优化单点登录正向代理与反向代理反爬机制,爬虫模拟浏览器行为 15 | cglib 方法拦截动态代理依赖注入 16 | Servlet 的本质 17 | TCP 长连接。心跳包,websocket 18 | Netty 百万级长连接优化 19 | DSL 解析到 AST 。lexer 和 parser 20 | JVM 相关。(你读过 GC 相关源码吗?)代码规范,包命名规范大学里最有成就感的事读过的 Java 书籍。(四大名著之类) 21 | 22 | 后端清单全局唯一有序 ID。 snowflake ,timestamp 加前面,然后后面加上机器 id 等冯诺依曼体系 23 | shell 命令的执行过程信息熵程序运行中的栈式结构,栈溢出攻击 24 | TCP/IP 有关知识。TCP 传输层加端口号,IP 网络层加 ip 地址;路由器就主要工作在 IP 网络层同步与阻塞并行与并发 25 | Java 线程的本质,内核线程与用户线程,线程调度,并行级别内核态与用户态,中断 26 | CPU 与内存与磁盘缓存行与伪共享内存分配管理,段页式。jemalloc 27 | Java 程序的运行原理普通可执行程序的运行原理缓存行与伪共享。两个面试官都问,可见十分重要,还好都答出来了从浏览器发出请求开始,到服务端应用接受到请求为止的过程 28 | HashMap ,hash 碰撞,hash 算法的优化单点登录正向代理与反向代理反爬机制,爬虫模拟浏览器行为 29 | cglib 方法拦截动态代理依赖注入 30 | Servlet 的本质 31 | TCP 长连接。心跳包,websocket 32 | Netty 百万级长连接优化 33 | DSL 解析到 AST 。lexer 和 parser 34 | JVM 相关。(你读过 GC 相关源码吗?)代码规范,包命名规范收集箱 35 | 36 | 4、微服务的高可用怎么保证的? 37 | 38 | 5、常用的负载均衡,该怎么用,你能说下吗? 39 | 40 | 6、网关能够为后端服务带来哪些好处? 41 | 42 | 7、Spring Bean 的生命周期 43 | 44 | 8、xml 中配置的 init、destroy 方法怎么可以做到调用具体的方法? 45 | 46 | 9、反射的机制 47 | 48 | 10、Object 类中的方法 49 | 50 | 11、hashcode 和 equals 方法常用地方 51 | 52 | 12、对象比较是否相同 53 | 54 | 13、hashmap put 方法存放的时候怎么判断是否是重复的 55 | 56 | 14、Object toString 方法常用的地方,为什么要重写该方法 57 | 58 | 15、Set 和 List 区别? 59 | 60 | 16、ArrayList 和 LinkedList 区别 61 | 62 | 17、如果存取相同的数据,ArrayList 和 LinkedList 谁占用空间更大? 63 | 64 | 18、Set 存的顺序是有序的吗? 65 | 66 | 19、常见 Set 的实现有哪些? 67 | 68 | 20、TreeSet 对存入对数据有什么要求呢? 69 | 70 | 21、HashSet 的底层实现呢 71 | 72 | 22、TreeSet 底层源码有看过吗? 73 | 74 | 23、HashSet 是不是线程安全的?为什么不是线程安全的? 75 | 76 | 24、Java 中有哪些线程安全的 Map? 77 | 78 | 25、Concurrenthashmap 是怎么做到线程安全的? 79 | 80 | 26、HashTable 你了解过吗? 81 | 82 | 27、如何保证线程安全问题? 83 | 84 | 28、synchronized、lock 85 | 86 | 29、volatile 的原子性问题?为什么 i++ 这种不支持原子性?从计算机原理的设计来讲下不能保证原子性的原因 87 | 88 | 30、happens before 原理 89 | 90 | 31、cas 操作 91 | 92 | 32、lock 和 synchronized 的区别? 93 | 94 | 33、公平锁和非公平锁 95 | 96 | 34、Java 读写锁 97 | 98 | 35、读写锁设计主要解决什么问题? 99 | 100 | 36、你项目除了写 Java 代码,还有前端代码,那你知道前端有哪些框架吗? 101 | 102 | 37、MySQL 分页查询语句 103 | 104 | 38、MySQL 事务特性和隔离级别 105 | 106 | 39、不可重复读会出现在什么场景? 107 | 108 | 40、sql having 的使用场景 109 | 110 | 41、前端浏览器地址的一个 http 请求到后端整个流程是怎么样?能够说下吗? 111 | 112 | 42、http 默认端口,https 默认端口 113 | 114 | 43、DNS 你知道是干嘛的吗? 115 | 116 | 44、你们开发用的 ide 是啥?你能说下 idea 的常用几个快捷键吧? 117 | 118 | 45、代码版本管理你们用的是啥? 119 | 120 | # 编程语言 121 | 122 | ## Java 123 | 124 | ### 并发编程 125 | 126 | - Java 中的线程与 Linux 操作系统中的进程或者线程概念是如何映射的? 127 | 128 | - 对于原子操作而言,synchronized, cas, AtomicInterger, LongAdder 哪种方式性能较好,为什么? 129 | 130 | - synchronized 是如何保证 JMM 中的原子性、可见性与有序性的? 131 | 132 | - 如下单例模式的代码可能存在什么问题?请从内存模型的角度思考。 133 | 134 | ```java 135 | public class Singleton { 136 | static Singleton instance; 137 | static Singleton getInstance(){ 138 | if (instance == null) { 139 | synchronized(Singleton.class) { 140 | if (instance == null) 141 | instance = new Singleton(); 142 | } 143 | } 144 | return instance; 145 | } 146 | } 147 | ``` 148 | 149 | ### JVM 150 | 151 | - 有时候在模拟有大量超时情况的 JMeter 压力测试中,前数分钟响应经常会超时,但是后面会突然降到毫秒级别,这可能是因为什么? 152 | 153 | ## Go 154 | 155 | - Goroutine 机制简述,其与 JVM 线程的区别?为什么 Go 的线程调度使用了 G-P-M 模型而不是 G-M 模型? 156 | - Go 中应该如何创建新的对象,make 关键字常用于哪些场景下。 157 | 158 | # 编程基础 159 | 160 | ## Java 161 | 162 | 关于此部分的详细索引可以参考笔者的[Java 入门与最佳实践](https://github.com/wx-chevalier/WXJavaToolkits)系列文章。 163 | 164 | # 数据结构与算法 165 | 166 | 关于数据结构与算法系列详细的文章列表可以参考笔者的[数据结构与算法系列综述](https://github.com/wx-chevalier/just-coder-handbook/blob/master/DataStructure/README.md#graph%E5%9B%BE) 167 | 笔者也是本次校招开始之后短短月余的时间才开始刷题,如果只是为了应付校招多学点套路也能说得过去,但是刷题本身的热趣确实挺有意思。关注笔者的博客或者 Github 的朋友应该知道,笔者过去几年里一直以工程应用于产品开发为重,老实说,很多时候解决真实场景下的问题需要动的脑子不如做几个算法题,可能带来的成就感也见仁见智。以华为为例,还有一种常见的 OJ 题目便是场景题,并不需要多么复杂的算法设计与考虑,而主要考察你对于用户需求的理解与具体编程能力、编程的精细度与代码掌控力的探查。 168 | 169 | 1.为什么不建议使用订单号作为主键? 2.为什么要在需要排序的字段上加索引? 170 | 3.for update 的记录不存在会导致锁住全表? 171 | 4.Redo Log 和 Binlog 有什么区别? 172 | 5.MySQL 如何回滚一条 sql ? 173 | 6.char(50) 和 varchar(50) 效果是一样的么? 174 | 175 | 一条 SQL 语句执行得很慢的原因有哪些? 176 | 177 | # 服务端基础 178 | 179 | ## 微服务与云原生 180 | 181 | - 有状态服务与无状态服务的区别在哪里?如何设计幂等性服务? 182 | 183 | ## Spring 184 | 185 | - 你所在的公司/负责的项目组,是否使用过微服务;如果使用过,那么完整的研发部署流程会包含哪些关键的步骤、组件? 186 | 187 | - Spring Boot 默认的 Worker 线程池大小是多少? 188 | 189 | - 是否使用过 MyBatis 提供的缓存机制,是否开启过二级缓存,如果开启过,那么缓存返回的对象是否是线程安全的? 190 | 191 | - 目前在项目中使用的数据库连接池是什么?如果是 HikariCP,那么其为什么性能相较于其他数据库会比较好? 192 | 193 | - Spring 中的定时器,在单线程模型下,假如定时任务是 5 秒执行一次,但是第一个任务就执行了 8 秒,第二个会怎么样呢? 194 | 195 | ## DevOps 196 | 197 | ## Test 198 | 199 | - 在服务测试中如何模拟百万级并发请求? 200 | 201 | ## 高可用架构 202 | 203 | - 如何设计多租户隔离系统?可以从系统隔离、服务隔离、异地多活等多领域阐述? 204 | 205 | - 常见的流量控制、熔断降级的手段有哪些? 206 | 207 | - Sentinel 是否会对服务带来额外负载? 208 | 209 | - 在发生故障时,我们应该优先恢复局部故障还是全局故障? 210 | 211 | # 基础架构 212 | 213 | ## Linux 与操作系统 214 | 215 | ## 分布式系统 216 | 217 | - 如何理解 CAP 理论?常用的保障 CA/CP/AP 的策略有哪些?如何理解 BASE 理论? 218 | 219 | ## 分布式计算 220 | 221 | ### 并发编程 222 | 223 | - IO 多路复用属于同步阻塞型 IO 模型还是异步非阻塞 IO 模型? 224 | 225 | ## 数据库 226 | 227 | ### MySQL 与关系型数据库 228 | 229 | - MySQL 中的主键应该选择怎样的策略去创建?常见的分布式 ID 生成的策略有哪些?为什么不建议使用订单号作为主键? 230 | 231 | - 简述 `select city,name,age from person where city(存在索引)='武汉' order by name limit 100;` 的底层执行逻辑?为什么数据库索引中常使用合并排序算法?如果针对 `city-name` 添加了联合索引,那么执行逻辑上会有何区别?为什么要在需要排序的字段上加索引? 232 | 233 | - 是否应该尽可能地添加列索引?应该以什么原则选择需要索引的列?像性别这样的列是否应该添加索引? 234 | 235 | * InnoDB 事务提交后在底层都干了些什么?如果发生写失效(页 16KB 数据,只写了 8Kb),可以通过重做日志进行恢复,为什么还需要 double_write? 236 | 237 | - 简述 `update person set age = 30 where id = 1;` 在数据库引擎中的执行流程。 238 | 239 | - MySQL 并发控制策略中的锁机制与 MVCC 分别会被用于哪些场景下?for update 的记录不存在会导致锁住全表? 240 | 241 | * 如果某条 SQL 执行较慢,能否分析下其原因? 242 | 243 | * Redo Log 和 Binlog 有什么区别? 244 | 245 | ### 缓存 246 | 247 | - 如何保证缓存与数据库的双写一致性?譬如如何保证 MySQL 与 Redis 中地数据一致性? 248 | - 如何设计一个大规模高并发的数据缓存系统? 249 | 250 | ### 数据库拆分与中间件 251 | 252 | - 如何设计一个分布式用户登录系统,能够根据用户 ID 将请求分发到不同的服务器?如果某台服务器出现了故障,应该如何进行重划分? 253 | 254 | - 在 MySQL 数据库中,一般单表数据量超过多少后会建议分库分表?为什么会有这样的考量? 255 | 256 | - 在分库分表的情况下,一般如何设计跨库的分页查询;如果进行分页查询,应该使用 `limit 100,10 ORDER BY id` 还是 `where id > ? limit 10` 的形式? 257 | 258 | ## 分布式计算 259 | 260 | ### 并发编程 261 | 262 | - 什么是协程?协程相对于线程的优势是什么?Go 中协程模型是如何实现的?在什么情况下应该优先选择协程?在什么情况下应该优先选择多线程? 263 | 264 | ### 消息中间件 MOM 265 | 266 | - 是否了解过常见的消息中间件?能否简述下不同的业务场景下应该如何去选择合适的消息中间件? 267 | 268 | - 常见的消息中间件采取怎样的持久化策略? 269 | 270 | - 常见的消息中间件是如何保障其高可用特性的? 271 | 272 | ## 容器与虚拟化 273 | 274 | ### Docker 275 | 276 | - Docker 中如何配置容器访问主机?可以设置网络为 host 模式,或者设置主机的 DNS 解析规则。 277 | 278 | # 典型业务系统 279 | 280 | ## BPM 流程引擎 281 | 282 | ## IM 283 | 284 | - 如何设计 Feed 流系统,针对十万、千万、十亿等不同的用户体量时其设计有什么差异? 285 | 286 | # 链接 287 | 288 | - https://mp.weixin.qq.com/s/4Zip0DVMGuJPMUnv_ySGIg 289 | - https://github.com/digoal/blog/blob/master/201806/20180623_01.md 290 | 291 | > [Java 进阶面试问题列表](https://zhuanlan.zhihu.com/p/24910702)翻译自[Java developer interview questions: The hard part](https://howtotrainyourjava.com/2016/07/14/java-developer-interview-questions-the-hard-part/),从属于笔者的[Java 入门与工程实践](https://github.com/wx-chevalier/Java-Introduction-And-Engineering-Practices)系列。最近公司打算招几个 Java 开发人员,正巧在 Reddit 上看到了该文,顺手翻译了一波。只是单纯的问题列表,可能较水,慎进。 292 | 293 | ![](https://coding.net/u/hoteam/p/Cache/git/raw/master/2017/1/2/QQ2017011611fas.png) 294 | 295 | # 面向对象编程的基本理念与核心设计思想 296 | 297 | - 解释下多态性(polymorphism),封装性(encapsulation),内聚(cohesion)以及耦合(coupling)。 298 | - 继承(Inheritance)与聚合(Aggregation)的区别在哪里。 299 | - 你是如何理解干净的代码(Clean Code)与技术负载(Technical Debt)的。 300 | - 描述下常用的重构技巧。 301 | - 阐述下 [SOLID](http://howtotrainyourjee.com/2014/08/28/rock-solid-code/) 原则。 302 | - 其他的譬如 KISS,DRY,YAGNI 等原则又是什么含义。 303 | - 什么是设计模式(Design Patterns)?你知道哪些设计模式? 304 | - 你有了解过存在哪些反模式(Anti-Patterns)吗? 305 | - 你会如何设计登陆舰/数学表达式计算程序/一条龙? 306 | - 你知道哪些基本的排序算法,它们的计算复杂度如何?在给定数据的情况下你会倾向于使用哪种算法呢? 307 | - 尝试编写如下代码: 308 |     - 计算指定数字的阶乘 309 | 310 | - 开发 [Fizz Buzz](http://c2.com/cgi/wiki?FizzBuzzTest)  小游戏 311 |     - 倒转句子中的单词 312 |     - 回文字符串检测 313 | 314 | - 枚举给定字符串的所有排列组合 315 | 316 | # Java 核心概念 317 | 318 | - equals 与 hashCode 的异同点在哪里?Java 的集合中又是如何使用它们的。 319 | - 描述下 Java 中集合(Collections),接口(Interfaces),实现(Implementations)的概念。LinkedList 与 ArrayList 的区别是什么? 320 | - 基础类型(Primitives)与封装类型(Wrappers)的区别在哪里? 321 | - final 与 static 关键字可以用于哪里?它们的作用是什么? 322 | - 阐述下 Java 中的访问描述符(Access Modifiers)。 323 | - 描述下 String,StringBuilder 以及 StringBuffer 区别。 324 | - 接口(Interface)与抽象类(Abstract Class)的区别在哪里。 325 | - 覆盖(Overriding)与重载(OverLoading)的区别在哪里。 326 | - 异常分为哪几种类型?以及所谓的`handle or declare`原则应该如何理解? 327 | - 简述垃圾回收器的工作原理。 328 | - 你是如何处理内存泄露或者栈溢出问题的? 329 | - 如何构建不可变的类结构?关键点在哪里? 330 | - 什么是 JIT 编译? 331 | - Java 8 / Java 7 为我们提供了什么新功能?即将到来的 Java 9 又带来了怎样的新功能? 332 | 333 | # Hibernate / 数据库 334 | 335 | - 请解释下 ORM。 336 | - Hibernate 与 JPA 区别在哪? 337 | - Hibernate 最新版提供了哪些特性? 338 | - 什么是懒加载(Lazy Loading)? 339 | - 什么是 N+1 难题? 340 | - 介绍一些熟悉的 Hibernate 注释。 341 | - 简介下 Hibernate Session 与 SessionFactory。 342 | - Entity Beans 的状态有哪些。 343 | - Hibernate 中的缓存分为几层。 344 | - Hibernate 中事务的支持分为几级? 345 | - 什么是乐观锁(Optimistic Locking)? 346 | - 简述下 ACID 原则。 347 | - 简述下数据库正则化(Normalizations)。 348 | - 请介绍下你日常工作中优化慢查询(Slow Query)的策略。 349 | 350 | # Spring 351 | 352 | - 新版的 Spring 中有哪些新特性? 353 | - 介绍下 Spring 的优势与缺陷。 354 | - 什么是控制反转(Inversion of Control)与依赖注入(Dependency Injection)? 355 | - 你用过哪些 Spring 的模块? 356 | - Spring 中是如何使用依赖注入的? 357 | - Spring 中提供了几种自动注入的机制? 358 | - 介绍下 Spring MVC。 359 | - Spring 中 Scopes 有哪些? 360 | - Spring 中 Bean 的生命周期包含哪些步骤? 361 | - Spring Bean 与 EJB Bean 的区别在哪里? 362 | 363 | # 其他主题 364 | 365 | - 介绍下切面编程(Aspect Oriented Programming)。 366 | - 概述下 GET 与 POST 的区别。 367 | - Web Server、Web Container 与 Application Server 的区别是什么? 368 | - 简要介绍下从浏览器输入 URL 开始到获取到请求界面之后 Java Web 应用中发生了什么。 369 | - 什么是 N 层架构? 370 | - 微服务(MicroServices)与巨石型应用(Monolithic Applications)之间的区别在哪里? 371 | - 你知道哪些商业级设计模式? 372 | - 你是如何测试一个应用的?知道哪些测试框架? 373 | - 你是如何测试单个方法的? 374 | - 在你的职业生涯中,算得上最困难的技术挑战是什么? 375 | - 什么是领域驱动开发(Domain Driven Development)? 376 | - 介绍下一些你最爱的 IDE 的常用插件。 377 | - 除了 IDE 之外,你的日常工作中还会用到哪些工具? 378 | - 你使用什么版本管理工具? 379 | - 分支(Branch)与标签(Tag)之间的区别在哪里? 380 | - 你常用的持续集成(Continuous Integration)、静态代码分析(Static Code Analysis)工具有哪些? 381 | 382 | # 综合系统设计能力 383 | 384 | - 秒杀系统设计。 385 | 386 | - 短链接系统设计。 387 | 388 | - 点赞系统设计。 389 | 390 | # 链接 391 | 392 | - https://zhuanlan.zhihu.com/p/70410011 393 | -------------------------------------------------------------------------------- /前端/JavaScript-Interview.md: -------------------------------------------------------------------------------- 1 | # JavaScript Interview 2 | 3 | # 异步并发 4 | 5 | - Event Loop 的基础概念是否了解?浏览器中的 Event Loop 与 Node.js 中的 Event Loop 有何区别? 6 | 7 | - JavaScript 常见的异步写法,Promise.finally 的实现? 8 | 9 | # TypeScript 10 | 11 | - 如何在 TypeScript 中设计简单的 IoC & DI 框架?如何实现简单的接口注解以自动生成类 Swagger 文档? 12 | 13 | - 在 TypeScript 中如何定义递归类型,譬如 `[1, [2, 3, 4], 5]`? 14 | 15 | - TypeScript 的 Partial 在底层是如何定义的? 16 | 17 | - TypeScript 中如何进行类型断言与类型捕获的? 18 | 19 | # V8 20 | 21 | - V8 引擎中的对象与数组是如何存储的?为何 JS 的数组每个数据类型都可以不一样?为何 JS 的数组无需提前设置长度,是可变数组?为何数组可以像 Object 一样挂载任意属性?如果浏览器需要进行大规模数组运算,应该选择怎样的存储结构? 22 | 23 | # 数据结构 24 | 25 | ## 数组 26 | 27 | - 找出整型数组中乘积最大的三个数,给定一个包含整数的无序数组,要求找出乘积最大的三个数。 28 | 29 | ```js 30 | let unsorted_array = [-10, 7, 29, 30, 5, -10, -70]; 31 | 32 | computeProduct(unsorted_array); // 21000 33 | 34 | function sortIntegers(a, b) { 35 | return a - b; 36 | } 37 | 38 | // greatest product is either (min1 * min2 * max1 || max1 * max2 * max3) 39 | function computeProduct(unsorted) { 40 | let sorted_array = unsorted.sort(sortIntegers), 41 | product1 = 1, 42 | product2 = 1, 43 | array_n_element = sorted_array.length - 1; // Get the product of three largest integers in sorted array 44 | 45 | for (let x = array_n_element; x > array_n_element - 3; x--) { 46 | product1 = product1 * sorted_array[x]; 47 | } 48 | product2 = sorted_array[0] * sorted_array[1] * sorted_array[array_n_element]; 49 | 50 | if (product1 > product2) return product1; 51 | 52 | return product2; 53 | } 54 | ``` 55 | 56 | - 寻找连续数组中的缺失数,给定某无序数组,其包含了 n 个连续数字中的 n - 1 个,已知上下边界,要求以 `O(n)` 的复杂度找出缺失的数字。 57 | 58 | ```js 59 | // The output of the function should be 8 60 | let array_of_integers = [2, 5, 1, 4, 9, 6, 3, 7]; 61 | let upper_bound = 9; 62 | let lower_bound = 1; 63 | 64 | findMissingNumber(array_of_integers, upper_bound, lower_bound); //8 65 | 66 | function findMissingNumber(array_of_integers, upper_bound, lower_bound) { 67 | // Iterate through array to find the sum of the numbers 68 | let sum_of_integers = 0; 69 | for (let i = 0; i < array_of_integers.length; i++) { 70 | sum_of_integers += array_of_integers[i]; 71 | } // 以高斯求和公式计算理论上的数组和 // Formula: [(N * (N + 1)) / 2] 72 | 73 | -[(M * (M - 1)) / 2]; // N is the upper bound and M is the lower bound 74 | upper_limit_sum = (upper_bound * (upper_bound + 1)) / 2; 75 | lower_limit_sum = (lower_bound * (lower_bound - 1)) / 2; 76 | 77 | theoretical_sum = upper_limit_sum - lower_limit_sum; // 78 | 79 | return theoretical_sum - sum_of_integers; 80 | } 81 | ``` 82 | 83 | - 数组去重,给定某无序数组,要求去除数组中的重复数字并且返回新的无重复数组。 84 | 85 | ```js 86 | // ES6 Implementation 87 | let array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8]; 88 | 89 | Array.from(new Set(array)); // [1, 2, 3, 5, 9, 8] 90 | 91 | // ES5 Implementation 92 | let array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8]; 93 | 94 | uniqueArray(array); // [1, 2, 3, 5, 9, 8] 95 | 96 | function uniqueArray(array) { 97 | let hashmap = {}; 98 | let unique = []; 99 | for (let i = 0; i < array.length; i++) { 100 | // If key returns null (unique), it is evaluated as false. 101 | if (!hashmap.hasOwnProperty([array[i]])) { 102 | hashmap[array[i]] = 1; 103 | unique.push(array[i]); 104 | } 105 | } 106 | return unique; 107 | } 108 | ``` 109 | 110 | - 数组中元素最大差值计算,给定某无序数组,求取任意两个元素之间的最大差值,注意,这里要求差值计算中较小的元素下标必须小于较大元素的下标。譬如`[7, 8, 4, 9, 9, 15, 3, 1, 10]`这个数组的计算值是 11( 15 - 4 ) 而不是 14(15 - 1),因为 15 的下标小于 1。 111 | 112 | ```js 113 | let array = [7, 8, 4, 9, 9, 15, 3, 1, 10]; 114 | // [7, 8, 4, 9, 9, 15, 3, 1, 10] would return `11` based on the difference between `4` and `15` 115 | // Notice: It is not `14` from the difference between `15` and `1` because 15 comes before 1. 116 | 117 | findLargestDifference(array); 118 | 119 | function findLargestDifference(array) { 120 | // 如果数组仅有一个元素,则直接返回 -1 121 | 122 | if (array.length <= 1) return -1; // current_min 指向当前的最小值 123 | 124 | let current_min = array[0]; 125 | let current_max_difference = 0; // 遍历整个数组以求取当前最大差值,如果发现某个最大差值,则将新的值覆盖 current_max_difference // 同时也会追踪当前数组中的最小值,从而保证 `largest value in future` - `smallest value before it` 126 | 127 | for (let i = 1; i < array.length; i++) { 128 | if ( 129 | array[i] > current_min && 130 | array[i] - current_min > current_max_difference 131 | ) { 132 | current_max_difference = array[i] - current_min; 133 | } else if (array[i] <= current_min) { 134 | current_min = array[i]; 135 | } 136 | } // If negative or 0, there is no largest difference 137 | 138 | if (current_max_difference <= 0) return -1; 139 | 140 | return current_max_difference; 141 | } 142 | ``` 143 | 144 | - 数组中元素乘积,给定某无序数组,要求返回新数组 output ,其中 output[i] 为原数组中除了下标为 i 的元素之外的元素乘积,要求以 O(n) 复杂度实现。 145 | 146 | ```js 147 | let firstArray = [2, 2, 4, 1]; 148 | let secondArray = [0, 0, 0, 2]; 149 | let thirdArray = [-2, -2, -3, 2]; 150 | 151 | productExceptSelf(firstArray); // [8, 8, 4, 16] 152 | productExceptSelf(secondArray); // [0, 0, 0, 0] 153 | productExceptSelf(thirdArray); // [12, 12, 8, -12] 154 | 155 | function productExceptSelf(numArray) { 156 | let product = 1; 157 | let size = numArray.length; 158 | let output = []; // From first array: [1, 2, 4, 16] // The last number in this case is already in the right spot (allows for us) // to just multiply by 1 in the next step. // This step essentially gets the product to the left of the index at index + 1 159 | 160 | for (let x = 0; x < size; x++) { 161 | output.push(product); 162 | product = product * numArray[x]; 163 | } // From the back, we multiply the current output element (which represents the product // on the left of the index, and multiplies it by the product on the right of the element) 164 | 165 | let product = 1; 166 | for (let i = size - 1; i > -1; i--) { 167 | output[i] = output[i] * product; 168 | product = product * numArray[i]; 169 | } 170 | 171 | return output; 172 | } 173 | ``` 174 | 175 | - 数组交集,给定两个数组,要求求出两个数组的交集,注意,交集中的元素应该是唯一的,`intersection([2, 2, 4, 1], [1, 2, 0, 2]); // [2, 1]`。 176 | 177 | ```js 178 | let firstArray = [2, 2, 4, 1]; 179 | let secondArray = [1, 2, 0, 2]; 180 | 181 | intersection(firstArray, secondArray); // [2, 1] 182 | 183 | function intersection(firstArray, secondArray) { 184 | // The logic here is to create a hashmap with the elements of the firstArray as the keys. 185 | // After that, you can use the hashmap's O(1) look up time to check if the element exists in the hash 186 | // If it does exist, add that element to the new array. 187 | 188 | let hashmap = {}; 189 | let intersectionArray = []; 190 | 191 | firstArray.forEach(function(element) { 192 | hashmap[element] = 1; 193 | }); // Since we only want to push unique elements in our case... we can implement a counter to keep track of what we already added 194 | 195 | secondArray.forEach(function(element) { 196 | if (hashmap[element] === 1) { 197 | intersectionArray.push(element); 198 | hashmap[element]++; 199 | } 200 | }); 201 | 202 | return intersectionArray; // Time complexity O(n), Space complexity O(n) 203 | } 204 | ``` 205 | 206 | ## 字符串 207 | 208 | - 颠倒字符串,给定某个字符串,要求将其中单词倒转之后然后输出,譬如 "Welcome to this Javascript Guide!" 应该输出为 "emocleW ot siht tpircsavaJ !ediuG"。 209 | 210 | ```js 211 | let string = 'Welcome to this Javascript Guide!'; 212 | 213 | // Output becomes !ediuG tpircsavaJ siht ot emocleW 214 | let reverseEntireSentence = reverseBySeparator(string, ''); 215 | 216 | // Output becomes emocleW ot siht tpircsavaJ !ediuG 217 | let reverseEachWord = reverseBySeparator(reverseEntireSentence, ' '); 218 | 219 | function reverseBySeparator(string, separator) { 220 | return string 221 | .split(separator) 222 | .reverse() 223 | .join(separator); 224 | } 225 | ``` 226 | 227 | - 乱序同字母字符串,给定两个字符串,判断是否颠倒字母而成的字符串,譬如 `Mary` 与 `Army` 就是同字母而顺序颠倒: 228 | 229 | ```js 230 | let firstWord = 'Mary'; 231 | let secondWord = 'Army'; 232 | 233 | isAnagram(firstWord, secondWord); // true 234 | 235 | function isAnagram(first, second) { 236 | // For case insensitivity, change both words to lowercase. 237 | let a = first.toLowerCase(); 238 | let b = second.toLowerCase(); // Sort the strings, and join the resulting array to a string. Compare the results 239 | 240 | a = a 241 | .split('') 242 | .sort() 243 | .join(''); 244 | b = b 245 | .split('') 246 | .sort() 247 | .join(''); 248 | 249 | return a === b; 250 | } 251 | ``` 252 | 253 | - 回文字符串,判断某个字符串是否为回文字符串,譬如 `racecar` 与 `race car` 都是回文字符串: 254 | 255 | ```js 256 | isPalindrome('racecar'); // true 257 | isPalindrome('race Car'); // true 258 | 259 | function isPalindrome(word) { 260 | // Replace all non-letter chars with "" and change to lowercase 261 | let lettersOnly = word.toLowerCase().replace(/\s/g, ''); // Compare the string with the reversed version of the string 262 | 263 | return ( 264 | lettersOnly === 265 | lettersOnly 266 | .split('') 267 | .reverse() 268 | .join('') 269 | ); 270 | } 271 | ``` 272 | 273 | ## 栈与队列 274 | 275 | - 使用两个栈实现入队与出队。 276 | 277 | ```js 278 | let inputStack = []; // First stack 279 | let outputStack = []; // Second stack 280 | 281 | // For enqueue, just push the item into the first stack 282 | function enqueue(stackInput, item) { 283 | return stackInput.push(item); 284 | } 285 | 286 | function dequeue(stackInput, stackOutput) { 287 | // Reverse the stack such that the first element of the output stack is the 288 | // last element of the input stack. After that, pop the top of the output to 289 | // get the first element that was ever pushed into the input stack 290 | if (stackOutput.length <= 0) { 291 | while (stackInput.length > 0) { 292 | let elementToOutput = stackInput.pop(); 293 | stackOutput.push(elementToOutput); 294 | } 295 | } 296 | 297 | return stackOutput.pop(); 298 | } 299 | ``` 300 | 301 | - 判断大括号是否闭合,创建一个函数来判断给定的表达式中的大括号是否闭合,`isBalanced({}{{}); // false`。 302 | 303 | ```js 304 | let expression = '{{}}{}{}'; 305 | let expressionFalse = '{}{{}'; 306 | 307 | isBalanced(expression); // true 308 | isBalanced(expressionFalse); // false 309 | isBalanced(''); // true 310 | 311 | function isBalanced(expression) { 312 | let checkString = expression; 313 | let stack = []; // If empty, parentheses are technically balanced 314 | 315 | if (checkString.length <= 0) return true; 316 | 317 | for (let i = 0; i < checkString.length; i++) { 318 | if (checkString[i] === '{') { 319 | stack.push(checkString[i]); 320 | } else if (checkString[i] === '}') { 321 | // Pop on an empty array is undefined 322 | if (stack.length > 0) { 323 | stack.pop(); 324 | } else { 325 | return false; 326 | } 327 | } 328 | } // If the array is not empty, it is not balanced 329 | 330 | if (stack.pop()) return false; 331 | return true; 332 | } 333 | ``` 334 | 335 | ## 递归 336 | 337 | - 二进制转换,通过某个递归函数将输入的数字转化为二进制字符串,`decimalToBinary(1000); // 1111101000`。 338 | 339 | ```js 340 | decimalToBinary(3); // 11 341 | decimalToBinary(8); // 1000 342 | decimalToBinary(1000); // 1111101000 343 | 344 | function decimalToBinary(digit) { 345 | if (digit >= 1) { 346 | // If digit is not divisible by 2 then recursively return proceeding 347 | // binary of the digit minus 1, 1 is added for the leftover 1 digit 348 | if (digit % 2) { 349 | return decimalToBinary((digit - 1) / 2) + 1; 350 | } else { 351 | // Recursively return proceeding binary digits 352 | return decimalToBinary(digit / 2) + 0; 353 | } 354 | } else { 355 | // Exit condition 356 | return ''; 357 | } 358 | } 359 | ``` 360 | 361 | - 二分搜索,`recursiveBinarySearch(array, value, leftPosition, rightPosition)` 362 | 363 | ```js 364 | function recursiveBinarySearch(array, value, leftPosition, rightPosition) { 365 | // Value DNE 366 | if (leftPosition > rightPosition) return -1; 367 | 368 | let middlePivot = Math.floor((leftPosition + rightPosition) / 2); 369 | if (array[middlePivot] === value) { 370 | return middlePivot; 371 | } else if (array[middlePivot] > value) { 372 | return recursiveBinarySearch(array, value, leftPosition, middlePivot - 1); 373 | } else { 374 | return recursiveBinarySearch(array, value, middlePivot + 1, rightPosition); 375 | } 376 | } 377 | ``` 378 | 379 | ## 数字 380 | 381 | - 判断是否为 2 的指数值,`isPowerOfTwo(64); // true`。 382 | 383 | ```js 384 | isPowerOfTwo(4); // true 385 | isPowerOfTwo(64); // true 386 | isPowerOfTwo(1); // true 387 | isPowerOfTwo(0); // false 388 | isPowerOfTwo(-1); // false 389 | 390 | // For the non-zero case: 391 | function isPowerOfTwo(number) { 392 | // `&` uses the bitwise n. 393 | // In the case of number = 4; the expression would be identical to: 394 | // `return (4 & 3 === 0)` 395 | // In bitwise, 4 is 100, and 3 is 011. Using &, if two values at the same 396 | // spot is 1, then result is 1, else 0. In this case, it would return 000, 397 | // and thus, 4 satisfies are expression. 398 | // In turn, if the expression is `return (5 & 4 === 0)`, it would be false 399 | // since it returns 101 & 100 = 100 (NOT === 0) 400 | 401 | return number & (number - 1 === 0); 402 | } 403 | 404 | // For zero-case: 405 | function isPowerOfTwoZeroCase(number) { 406 | return number !== 0 && (number & (number - 1)) === 0; 407 | } 408 | ``` 409 | --------------------------------------------------------------------------------