├── .gitignore ├── docs ├── assets │ ├── imgs │ │ ├── bone.png │ │ ├── hero.jpg │ │ ├── learn.jpg │ │ ├── team.png │ │ └── books.jpeg │ └── css │ │ ├── air.css │ │ ├── modest.css │ │ └── github-markdown.css ├── .vuepress │ ├── override.styl │ └── config.js ├── Collection │ ├── closure_moyu.assets │ │ ├── 1527622788167.png │ │ ├── 1527656171423.png │ │ ├── 1527656311145.png │ │ ├── 1527656577721.png │ │ ├── 1527657051063.png │ │ ├── 1527657323488.png │ │ └── 1527657728413.png │ ├── SEO.md │ ├── LinkAndImport.md │ ├── semantization.md │ ├── NumberExpression.md │ ├── ExpressionAndStatement.md │ ├── iframeUse.md │ ├── SendData.md │ ├── Geili.md │ ├── DozensOfVisits.md │ ├── WhiteScreen.md │ ├── sprite.md │ ├── NewHtmlTag.md │ ├── OftenAsked.md │ ├── Template.md │ ├── memorization.md │ ├── Clojure.md │ ├── Events.md │ ├── Inherit.md │ ├── Currying.md │ └── closure_moyu.md ├── guide │ ├── team.md │ ├── architecture.md │ ├── README.md │ ├── entry.md │ ├── basic.md │ ├── foundation.md │ ├── framework.md │ └── advanced.md ├── README.md └── team │ ├── Team.md │ └── Stages.md ├── deploy.sh ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | node_modules 3 | .cache 4 | dist 5 | -------------------------------------------------------------------------------- /docs/assets/imgs/bone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/assets/imgs/bone.png -------------------------------------------------------------------------------- /docs/assets/imgs/hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/assets/imgs/hero.jpg -------------------------------------------------------------------------------- /docs/assets/imgs/learn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/assets/imgs/learn.jpg -------------------------------------------------------------------------------- /docs/assets/imgs/team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/assets/imgs/team.png -------------------------------------------------------------------------------- /docs/assets/imgs/books.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/assets/imgs/books.jpeg -------------------------------------------------------------------------------- /docs/.vuepress/override.styl: -------------------------------------------------------------------------------- 1 | // showing default values 2 | $accentColor = #35a8dc 3 | $textColor = #2c3e50 4 | $borderColor = #eaecef 5 | $codeBgColor = #282c34 -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #! /bin/zsh 2 | cd dist 3 | git init 4 | git add -A 5 | git commit -m 'deploy' 6 | git push -f git@github.com:Mountain-Buzhou/Interview-Book.git master:gh-pages -------------------------------------------------------------------------------- /docs/Collection/closure_moyu.assets/1527622788167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/Collection/closure_moyu.assets/1527622788167.png -------------------------------------------------------------------------------- /docs/Collection/closure_moyu.assets/1527656171423.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/Collection/closure_moyu.assets/1527656171423.png -------------------------------------------------------------------------------- /docs/Collection/closure_moyu.assets/1527656311145.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/Collection/closure_moyu.assets/1527656311145.png -------------------------------------------------------------------------------- /docs/Collection/closure_moyu.assets/1527656577721.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/Collection/closure_moyu.assets/1527656577721.png -------------------------------------------------------------------------------- /docs/Collection/closure_moyu.assets/1527657051063.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/Collection/closure_moyu.assets/1527657051063.png -------------------------------------------------------------------------------- /docs/Collection/closure_moyu.assets/1527657323488.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/Collection/closure_moyu.assets/1527657323488.png -------------------------------------------------------------------------------- /docs/Collection/closure_moyu.assets/1527657728413.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountain-Buzhou/Interview-Book/HEAD/docs/Collection/closure_moyu.assets/1527657728413.png -------------------------------------------------------------------------------- /docs/guide/team.md: -------------------------------------------------------------------------------- 1 | # Team 2 | 这部分内容更多是非技术方向上的一些杂谈,看看就好。 3 | 4 | ## Management 5 | - [给你一个二十人的新团队,你作为前端负责人你怎样去做?](/team/Team.md) 6 | ## Growing 7 | - [工程师的阶段是怎样的?不同阶段应该具备怎样的技能?](/team/Stages.md) 8 | -------------------------------------------------------------------------------- /docs/guide/architecture.md: -------------------------------------------------------------------------------- 1 | # Architecture 2 | 3 | 说到架构,我认为前端很难存在架构一职,或者说`前端架构的工作`并不足以完整匹配`架构的职责`。 4 | 己方观点,欢迎讨论。 5 | 6 | - [互联网公司技术架构](https://github.com/davideuler/architecture.of.internet-product) 7 | - [后端架构师技术图谱](https://github.com/xingshaocheng/architect-awesome) -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | actionText: 点击阅读 → 4 | actionLink: /guide/ 5 | features: 6 | - title: 前端入门 7 | details: 切图仔 8 | - title: 进阶知识 9 | details: JS从入门到退学 10 | - title: 工程师 11 | details: 解决问题 12 | footer: MIT Licensed | Copyright © 2018-present Mountain Buzhou 13 | --- -------------------------------------------------------------------------------- /docs/Collection/SEO.md: -------------------------------------------------------------------------------- 1 | ## Q: 前端需要注意哪些SEO? 2 | 3 | ## A: 4 | 01,合理的title,description,keywords。 5 | 6 | 02,语义化的HTML代码。好处,让搜索引擎更好搜索。 7 | 8 | 03,重要的HTML内容放前面。 9 | 10 | 04,重要的内容,不要用JS输出。爬虫不会执行JS获取内容。 11 | 12 | 05,少用iframe。搜索引擎不会抓取iframe的内容。 13 | 14 | 06,图片加上alt和title。 15 | 16 | 07,保证网站打开速度。 -------------------------------------------------------------------------------- /docs/Collection/LinkAndImport.md: -------------------------------------------------------------------------------- 1 | ## Q: link和@import的区别? 2 | 3 | ## A: 4 | 5 | 1. link是HTML方式, @import是CSS方式 6 | 2. link最大限度支持并行下载,@import过多嵌套导致串行下载,出现FOUC 7 | 3. link可以通过rel="alternate stylesheet"指定候选样式 8 | 4. 浏览器对link支持早于@import,可以使用@import对老浏览器隐藏样式 9 | 5. @import必须在样式规则之前,可以在css文件中引用其他文件 10 | 6. 总体来说:link优于@import 11 | -------------------------------------------------------------------------------- /docs/Collection/semantization.md: -------------------------------------------------------------------------------- 1 | ## Q: 2 | 3 | ## A: 4 | 5 | 01,语义化,就是通过HTML标签来表示页面包含的信息。 6 | 7 | 02,其中有HTML标签的语义化和CSS命名的语义化。 8 | 9 | 03,HTML标签语义化的的含义是: 10 | 11 | 通过使用含有语义的标签(如h1~h6,aside)来表示文档结构。 12 | 13 | 04,CSS语义化的含义是: 14 | 15 | 为HTML标签添加有意义的class和id来补充未表达的语义。 16 | 17 | 05,为什么需要语义化 18 | 19 | - 结构清晰。便于维护。 20 | - 盲人可以用阅读器来阅读。 21 | - 使搜索引擎更好的抓取网页。利于收录。 -------------------------------------------------------------------------------- /docs/Collection/NumberExpression.md: -------------------------------------------------------------------------------- 1 | ## Q: `(0, 1, 2)` 的结果是什么? 2 | 3 | ## A: 4 | 5 | 6 | 7 | result:2 8 | 9 | 10 | 11 | 原因解析: 12 | 13 | 括号内是逗号表达式。 14 | 15 | 逗号运算符可以在一条语句中执行多个运算,并返回表达式中最后一个运算结果。 16 | 17 | 18 | 19 | 例子: 20 | 21 | ```javascript 22 | for(var i =0,j =10;i 38 | 39 | #### SVG 雪碧图 40 | 41 | 42 | 01,原理和普通图片雪碧图一样。 43 | 44 | 02,好处是不再需要为高清屏准备额外的2倍图。因为SVG与分辨率无关。 45 | 46 | 03,实现方式: 47 | 48 | ​ 方式1:所有的图标使用``元素来定义在 SVG 代码中,并且隐藏它。然后使用``元素来通过`` 的 `xlink:href="#id"`来引用它。 49 | 50 | ​ 方式2:用SVG的`viewbox`属性来指定显示SVG画布的区域,跟`background-position`原理差不多。 -------------------------------------------------------------------------------- /docs/Collection/NewHtmlTag.md: -------------------------------------------------------------------------------- 1 | ## Q: html5新标签有哪些 2 | 3 | ## A: 4 | 5 | ### 最常用的 6 | 7 | canvas 8 | 9 | svg 10 | 11 | video 12 | 13 | audio 14 | 15 | 16 | 17 | ### 一般使用 18 | 19 | 20 | 21 | 【01】article(IE8不支持) 22 | 23 | 【01】details 24 | 25 | 【02】aside(IE8不支持) 26 | 27 | 【03】header(IE8不支持) 28 | 29 | 【04】footer(IE8不支持) 30 | 31 | 【06】nav(IE8不支持) 32 | 33 | 【07】section 34 | 35 | 【08】figure(IE8不支持) 36 | 37 | 【09】figcaption(IE8不支持) 38 | 39 | 【10】embed 40 | 41 | 【11】address 42 | 43 | 【13】summary 44 | 45 | 【14】menu 46 | 47 | 【18】section 48 | 49 | 【19】address 50 | 51 | 【20】time 52 | 53 | ------ 54 | 55 | rp(IE8不支持) 56 | 57 | rt(IE8不支持) 58 | 59 | ruby(IE8不支持) 60 | 61 | --- 62 | 63 | 64 | 65 | ### 较少支持的 66 | 67 | 68 | 69 | 【01】command(没有浏览器支持) 70 | 71 | 【02】datalist(IE和Safari不支持) 72 | 73 | 【03】details(只有chrome支持) 74 | 75 | 【04】dialog(只有chrome支持) 76 | 77 | 【05】keygen(IE不支持) 78 | 79 | 【06】meter(IE不支持) 80 | 81 | 【07】output(IE不支持) 82 | 83 | 【08】progress(IE10+支持) 84 | 85 | 【09】summary(IE,firefox,opera不支持) 86 | 87 | 【10】time(都不支持) 88 | 89 | 【11】track(IE9和firefox和Safari不支持) 90 | 91 | 【12】wbr(IE不支持) 92 | 93 | 【13】bdi(只有firefix和chrome支持) 94 | 95 | 【14】hgroup -------------------------------------------------------------------------------- /docs/guide/README.md: -------------------------------------------------------------------------------- 1 | # Introduce 2 | 3 | ## Abstract 4 | 5 | 网络上的资源其实已经足够多了,所以在进行搜索的时候需要极大的筛选成本。为了减少这种低效的筛选,我将一些零散的知识整理在一起。 6 | 7 | ## Guidance 8 | `Entry`这个部分是几个前端知识库的链接,里面的内容比较浅显易懂。先看看整个结构性的题目,找到自己的知识的盲区,再去针对性学习。 9 | 10 | `Basic`是一些基础、简单的面试题,可以在`Entry`中的找到更全的题目内容。 11 | 12 | `Advanced`则是一些稍微有难度的题目,主要来自于日常的思考、交流,以及一些常见的前端的进阶问题、算法题。 13 | 14 | `Framework`则是跟框架、原理相关的题目。 15 | 16 | `Team`这个部分则是关于团队管理、以及个人非技术上的一些发展相关的杂谈。 17 | 18 | `Foundation`这个部分是计算机基础的概念,包括计算机组成原理、操作系统、编译原理、计算机网络、数据结构与算法、数据库系统、软件工程。这个部分就是所谓的补基础,构建完整的计算机体系结构,是向上成长的过程中必不可少的。 19 | 20 | **对于这种资讯类的repo来说,很少有提及基础的重要性,希望能够引起阅读者的重视**。 21 | 22 | **欢迎大家在issue里留下自己的奇思妙想,或者直接pr。** 23 | 24 | ## Hortation 25 | 希望大家能够带着成为一个优秀的软件工程师的想法,来合理的利用这份资料。 26 | 27 | 这份资料并非单纯的前端工程师的面试题,我更希望它能够在工程师成长的道路上,起到梳理知识结构的作用。可以精通前端,但不要局限在狭义的前端,将知识面扩展到后端,了解更多基础的知识结构,才能够成为更加优秀的工程师。 28 | 29 | 这里面大部分的题目都是非常规的提问法,但涉及知识点都极其基础。后续我们可能会添加一些别的方向的内容,比如node、go之类的,但主要还是跟进前端的新动态。 30 | 31 | 最后提到需要辩证地看待这种资源,它只是知识结构,而非万灵药,更多的知识还需要在工作中去实践、去学习。 32 | 33 | **“非知之难,行之惟难;非行之难,终之斯难。”——魏征** 34 | 35 | 36 | ## Contributors 37 | [@liyuk](https://github.com/Liyuk) 38 | [@onion](https://github.com/dcy0701) 39 | [@heaven](https://github.com/NE-SmallTown) 40 | [@Tristan](https://github.com/Troland) 41 | [@张庆东](https://github.com/q986171791) 42 | [@moyu](https://github.com/moyuling) -------------------------------------------------------------------------------- /docs/guide/entry.md: -------------------------------------------------------------------------------- 1 | # Entry 2 | 3 | 我将**最基础**的前端的知识点分为三个部分: 4 | 5 | - HTML CSS JavaScript(闭包、作用域、异步、继承) 6 | - 网络、性能、测试、编码 7 | - 自动化、工程化的开发 8 | 9 | 这三个划分出来的只是最为基础的内容,学习这部分内容一方面需要对于书面知识的阅读,也需要在项目中加以实践。 10 | 11 | ## Naive 12 | 基础的面试问题题库已经有很多了,个人觉得这个里面的题大概是入门级别的,刚学的时候看看就可以了。 13 | >[中文前端面试大全:qiu-deqing/FE-interview](https://github.com/qiu-deqing/FE-interview) 14 | 15 | 白皮书里关于非技术的问题值得一读。 16 | >[yangshun/tech-interview-handbook](https://github.com/yangshun/tech-interview-handbook) 17 | 18 | 这本书里面梳理的非常全面,可以作为知识体系的梳理来进行学习。 19 | >[front-end-developer-handbook-2018](https://frontendmasters.gitbooks.io/front-end-developer-handbook-2018/) 20 | 21 | ## Interesting 22 | 关于一些Javascript里细节的点,可以看看这位大哥的博客,写的很清晰,代码实现很完整。 23 | >[冴羽的博客](https://github.com/mqyqingfeng/Blog) 24 | 25 | 《前端要给力之系列》是一系列非常有趣的文章,同时讲的非常深入 26 | >[前端要给力之系列](/collection/Geili.md) 27 | 28 | 如果你喜欢看一些函数式编程、编译原理之类的东西,那么可以看看何幻大神的知乎专栏进行一些~~初步~~深入的学习。 29 | >[业余程序员的个人修养](https://zhuanlan.zhihu.com/self-discipline) 30 | 31 | 32 | ## Recommend 33 | 这本书里面涵盖的知识点非常基础,作者整理了四个月,刷完了十几本书,还有leetcode四百题,梳理了非常多的知识结构。   34 | 35 | 其中包括**计算机网络、操作系统、算法、面向对象、数据库、java、分布式、工具**等等丰富的内容,这也是我在后文里提到的内容。 36 | 37 | 我极力推崇这样的知识梳理的repo,在这个repo中扩展了我在本文最后提到的书本中的知识点。 38 | 如果你希望加强基础的学习,或者在往后端进行技术拓展,这本书可以作为大纲梳理。 39 | 40 | >[面试白皮书](https://github.com/CyC2018/Interview-Notebook)   41 | 42 | -------------------------------------------------------------------------------- /docs/guide/basic.md: -------------------------------------------------------------------------------- 1 | # Basic 2 | 3 | ## HTML 4 | - [html5新标签有哪些](/collection/NewHtmlTag.md) 5 | - canvas、svg、webGL 6 | - [你是如何理解 HTML 语义化的,有什么好处](/collection/semantization.md) 7 | - [前端需要注意哪些SEO?](/collection/SEO.md) 8 | - manifest、worker、socket 9 | - input和textarea的区别 10 | - 用一个div模拟textarea的实现 11 | 12 | ## CSS 13 | - css3有什么新特性,浏览器支持怎么样 14 | - 伪类是什么?有哪些?会有哪些兼容性问题?如何处理? 15 | - css预处理器知道吗?用过哪些?有什么优劣?后处理器知道吗? 16 | - 盒模型有哪几种?怪异模式和标准模式? 17 | - less、sass、postcss、prefix 18 | - 层叠优先级 19 | - 圣杯、双飞燕布局 20 | - float清除浮动 21 | - flex布局、 grid布局、table布局 22 | - css以及中轴旋转、动画变换 23 | - 绘制三角形、矩形、菱形、梯形(奇巧淫技,可以不问) 24 | - [sprite图(雪碧图)知道吗?svg雪碧图了解吗?](/collection/sprite.md) 25 | - px、em、rem、vw、vh?rem的根节点样式在什么时候设置? 26 | - position有哪些?他们的定位原点是什么? 27 | - 媒体查询用css好还是用js好? 28 | - [link和@import的区别?](/collection/LinkAndImport.md) 29 | - 响应式布局的原理 30 | - css低版本浏览器兼容问题,额外需要什么后缀来声明浏览器兼容 31 | - !important意义,是否应当规避使用? 32 | - BFC块级上下文、IFC,实现双栏高度对齐 33 | - BEM命名法,有什么优势,有什么劣势 34 | - 1px边框问题 35 | - (水平)居中有哪些实现方式、(垂直)居中有哪些实现方式 36 | 37 | ## JavaScript 38 | - typeof以及弱类型转换规则?NaN、undefined、null 39 | - dom的节点操作?能够背api还是知道api? 40 | - ajax是什么?知道底层实现原理吗?知道fetch吗?自己封装过吗? 41 | - GET、POST意义?restful架构下还有别的什么请求?OPTION请求是什么? 42 | - 事件冒泡和事件捕获是怎样的?对应的默认方法有什么?一般在什么情况使用? 43 | - call、apply、bind 44 | - 如何判断数据类型? 45 | - hoisting是什么?具体表现是怎样的? 46 | - 匿名函数是什么?函数表达式和函数声明的区别? 47 | - let、const暂时性锁区知道吗?表现是怎样的? 48 | - 严格模式是什么?有什么好处?'use strict' 49 | - arguments是什么类型?callee和caller有什么区别? 50 | - Date.format实现过吗?思路是怎样的? 51 | - 动画:setTimeout何时执行,requestAnimationFrame的优点 52 | - 说说YSlow(可以详细一点) 53 | - 你知道new一个对象有几步吗?(参考ES6标准文档) 54 | 55 | -------------------------------------------------------------------------------- /docs/guide/foundation.md: -------------------------------------------------------------------------------- 1 | # Foundation 2 | 我非常希望看到这里的同学能够认认真真去系统性的学习整个计算机体系结构。因此我将各个模块中偏向应用的东西都梳理了出来。这些梳理出来的点比较偏工程,稍做迁移就可以应用在我们工作当中。学习的时候可以暂时根据这些梳理出来的关键字去过一下知识点。 3 | 4 | 我省略了《软件工程》与《数据库系统》的内容,因为前者方法论适合实践总结,后者我还不太熟悉。我推荐一本《计算机程序的构造和解释(SICP)》,是MIT本科的第一门课,讲述如何构造和分析复杂系统(程序)。这些书我自己也定期的回顾,之前与大佬讨论,不论科班还是非科班出身,不断回顾并思考计算机基础的东西,是非常重要的。 5 | 6 | ![基础书籍](../assets/imgs/books.jpeg) 7 | 8 | ## Operating System 9 | - 进程与线程 10 | - 虚拟地址,物理地址 11 | - 进程间通信:临界区、忙等待互斥、睡眠与唤醒、信号量、互斥量、管程、消息传递、屏障、避免锁 12 | - 进程调度策略:批处理、交互式、实时; 13 | - 批处理调度:FCFS、SJF、SRTF 14 | - 交互式调度:轮转、优先级、多级队列、最短进程优先、保证调度、彩票调度、公平分享调度 15 | - 实时调度:硬实时、软实时、周期性 16 | - [IPC问题:读者-写者、生产者-消费者、哲学家进餐、银行家算法](https://www.zybuluo.com/zhengbuqian/note/243560) 17 | - 页面置换算法:最优页面置换算法、最近未使用页面置换算法(NRU)、先进先出页面置换算法(FIFO)、第二次机会页面置换算法、时钟页面置换算法(clock)、最近最少使用页面置换算法(LRU)、软件模拟LRU、工作集页面置换算法、工作集时钟页面置换算法 18 | 19 | ## Computer Organization 20 | - 缺页中断——FIFO、LRU、OPT三种置换算法 21 | - 流水线、指令集 22 | 23 | ## Network 24 | - [帧、报文、报文段、分组、包、数据报的概念](http://www.cnblogs.com/sddai/p/5649939.html) 25 | - DNS原理 26 | - UDP和TCP 27 | - 可靠性数据传输原理、拥塞控制原理 28 | - 路由选择:RIP、OSPF、BGP 29 | - 差错检验和纠正技术 30 | - 计算机网络安全 31 | 32 | ## Algorithm 33 | - 递归与非递归 34 | - 排序算法(8种) 35 | - 栈、队列、散列表、二叉树、红黑树 36 | - 动态规划、贪心、平摊分析 37 | - B树、二项堆、斐波那契堆、不相交集合 38 | - 最小生成树Kruskal和Prim,最短路Dijstra和Bellman-Ford 39 | - 最短路Floyd-Warshall和Johnson,最大流Ford-Fulkerson 40 | - 排序网络、矩阵运算、线性规划、多项式与快速傅立叶变换 41 | - 有限数论,字符串匹配Rabin-Karp和KMP 42 | - 计算几何学、NP完全性、近似算法 43 | 44 | ## Compliers 45 | - 词法分析、自动机、DFA 46 | - 语法分析、语法制导 47 | - 中间代码、AST树、类型检查 48 | - 堆、栈管理,垃圾回收机制 49 | - 目标代码生成、代码优化 50 | - 指令集并行性 51 | - 并行性与局部性优化 52 | - 过程间分析 53 | -------------------------------------------------------------------------------- /docs/Collection/OftenAsked.md: -------------------------------------------------------------------------------- 1 | ## Q: 面试常问问题及问答思路 2 | 3 | ## A: 4 | 5 | ## Q: 面试常问问题及问答思路 6 | 7 | ## A: 8 | 9 | - **你经常看或仔细研读过的书有哪些?** 10 | - 01,枚举几个经典书籍。 11 | - 02,从事什么就阐述相关类型的书籍。 12 | 13 | 14 | - **你认为你应聘我们公司的XXXX,你自身的优势在哪?** 15 | - 01,融洽,没有领导希望你带领团队每天打嘴仗,你必须说明你能在以往团队中与其他人和谐相处。 16 | - 02,技术,千万不要谦虚,对方要的就是技术过硬、能力出众的人才。你只需要说明你成功解决过什么难题,并且你对 XX技术、XX 中间件、XX 系统有多么的熟悉。 17 | 18 | 19 | 20 | 21 | - **未来几年的规划** 22 | - 根据个人发展技术回答即可。 23 | - **期待薪资** 24 | - 根据个人的期待回答即可。 25 | - **除了工资,还有什么福利最吸引你?** 26 | - 尽可能诚实,如果你做足了功课,你就知道他们会提供什么,回答尽可能和他们提供的相配。如果你觉得自己该得到更多,也可以多要一点。 27 | - **你做了这么多项目,让你感受最深,印象最深的是哪个项目?你从中学到了什么?为什么会感受最深?** 28 | - **你对公司有什么需要了解的?** 29 | - **简单自我介绍一下自己。**(3、5分钟内) 30 | - **离职原因** 31 | - **你认为一个项目如何进行才正确?** 32 | - **你认为项目中最重要的是哪些过程?** 33 | - **做前端开发这么多年来?说下你的感受吧!** 34 | - **你认为项目中最重要的是哪些过程?** 35 | - **最近看的一篇Javascript的文章是?** 36 | - **除了前端以外还了解什么其它技术么?你最最厉害的技能是什么?** 37 | - **你常用的开发工具是什么,为什么?** 38 | - **对前端界面工程师这个职位是怎么样理解的?它的前景会怎么样?** 39 | - **加班的看法?** 40 | - **平时如何管理你的项目?** 41 | - **如何设计突发大规模并发架构?** 42 | - **说说最近最流行的一些东西吧?常去哪些网站?** 43 | - **移动端(Android IOS)怎么做好用户体验?** 44 | - **你在现在的团队处于什么样的角色,起到了什么明显的作用?** 45 | - **你认为怎样才是全端工程师(Full Stack developer)?** 46 | - **介绍一个你最得意的作品吧?** 47 | - **最近在学什么?** 48 | - **你遇到过比较难的技术问题是?你是如何解决的?** 49 | - **常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?** 50 | - **页面重构怎么操作?** 51 | - **列举IE 与其他浏览器不一样的特性?** 52 | - **99%的网站都需要被重构是那本书上写的?** 53 | - **什么叫优雅降级和渐进增强?** 54 | - **WEB应用从服务器主动推送Data到客户端有那些方式?** 55 | - **对Node的优点和缺点提出了自己的看法?** 56 | - **你有哪些性能优化的方法?** 57 | - **如何编写高性能的Javascript?** 58 | - **那些操作会造成内存泄漏?** 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/Collection/Template.md: -------------------------------------------------------------------------------- 1 | ## Q: 实现一个基本的模版引擎 2 | 3 | ## A: 4 | 5 | `Author: @liyuk` 6 | 7 | 主要思路为使用正则表达式匹配出全局的变量,替换称为对应的data中的数据。 8 | 9 | ```js 10 | // 封装 11 | function _.template(templateId, data){ 12 | // 获取模板字符串 13 | var str = document.getElementById(templateId).innerHTML; 14 | // 正则表达式 标记<%= name %> 这里的变量命名规则只能是字母或数字不能有特殊字符 15 | var reg = /<%=\s*(\w+)\s*%>/; 16 | // exec返回一个匹配数组 17 | var arrReg = ''; 18 | while (arrReg = reg.exec(str)){ 19 | str = str.replace(arrReg[0],data[arrReg[1]]); 20 | } 21 | return str; 22 | } 23 | 24 | var data = { 25 | "name":"haha", 26 | "age":22 27 | }; 28 | // 调用模板引擎 29 | var html = _.template('template',data); 30 | document.body.innerHTML = html; 31 | ``` 32 | 33 | ```html 34 | 35 | 39 | ``` 40 | 41 | 简单的实现实际上就是正则匹配,加上字符串替换。 42 | - 如果涉及对象的key调用,要用正则做点的分隔来实现层级区分 43 | - 如果再涉及自定义属性,那么需要加入语法解析的内容去获取保留字面量以及对应所匹配的参数,类似v-if、v-for这类 44 | - 同时还需要涉及到模板的执行语句,预编译 45 | - 唯一标识符用来强调模板中的字面量 46 | - xss漏洞防范,使用转义字符 47 | ```js 48 | function strip(html) { 49 | return String(html) 50 | .replace(/&/g, '&')//& 51 | .replace(//g, '>')//右尖号 53 | .replace(/"/g, '"')//双引号" 54 | .replace(/'/g, ''');//IE下不支持'' 55 | } 56 | ``` 57 | 58 | ## Roast 59 | 这个题很简单,基本概念。 60 | 但是如果深入的话,我们可以推出如下题目: 61 | - 正则引擎如何实现? 62 | - 模板引擎中设计的词法分析、语法分析、语义分析是什么? 63 | - 能否用非正则的方式实现模板引擎? 64 | - 如何利用递归和非递归分别实现AST树? 65 | - 模板引擎中内容发生变化时,AST树执行了什么操作? -------------------------------------------------------------------------------- /docs/Collection/memorization.md: -------------------------------------------------------------------------------- 1 | ## Q: 函数记忆是什么?什么场景下使用?(动态规划) 2 | 3 | ## A: 4 | 5 | 01,将上次计算结果保存起来的函数,称为有记忆能力(memorization)的函数。 6 | 7 | ``` 8 | function memorize(f) { 9 | var cache = {}; 10 | return function() { 11 | var key = arguments.length + Array.prototype.join.call(arguments,","); 12 | if (key in cache) return cache[key]; 13 | else return cache[key] = f.apply(this, arguments); 14 | }; 15 | } 16 | ``` 17 | 18 | - 01,利用闭包,将结算结果保存在私有的缓存对象里。 19 | - 02,将实参长度加实参参数作为缓存对象属性。 20 | - 03,如果key属性不存在,就将结果保存在key属性的值。 21 | 22 | 下面的代码展示了如何使用memorize(): 23 | 24 | ``` 25 | // 返回两个整数的最大公约数 26 | // 使用欧几里德算法:http://en.wikipedia.org/wiki/Euclidean_algorithm 27 | function gcd(a,b) { // 这里省略对a和b的类型检查 28 | var t; // 临时变量用来存储交换数值 29 | if (a < b) t=b, b=a, a=t; // 确保 a >= b 30 | while(b != 0) t=b, b = a%b, a=t; // 这是求最大公约数的欧几里德算法 31 | return a; 32 | } 33 | var gcdmemo = memorize(gcd); 34 | gcdmemo(85, 187) // => 17 35 | ``` 36 | 37 | 代码分析By魔芋 38 | 39 | var gcdmemo = memorize(gcd); 40 | 41 | f=gcd(a,b); 42 | 43 | 第一次调用时,cache为空对象。 gcdmemo为返回的匿名函数。 44 | 45 | key为285,187 46 | 47 | 第二次调用时,cache.key已存在,将直接返回计算值。 48 | 49 | ------ 50 | 51 | 应用一:实现记忆功能的递归函数: 52 | 53 | ``` 54 | var factorial = memorize(function(n) { 55 | return (n <= 1) ? 1 : n * factorial(n-1); 56 | }); 57 | factorial(5) // => 120.对于4~1的值也有缓存 58 | ``` 59 | 60 | 应用二:数组去重: 61 | 62 | ``` 63 | unction unique(arr) { 64 | var ret = [] 65 | var hash = {} 66 | for (var i = 0; i < arr.length; i++) { 67 | var item = arr[i] 68 | var key = typeof(item) + item; 69 | if (hash[key] !== 1) { 70 | ret.push(item) 71 | hash[key] = 1 72 | } 73 | } 74 | return ret; 75 | } 76 | ``` 77 | 78 | ** -------------------------------------------------------------------------------- /docs/Collection/Clojure.md: -------------------------------------------------------------------------------- 1 | ## Q: 闭包 javascript 2 | 3 | ## A: 4 | 5 | `Author: @liyuk` 6 | 7 | 闭包这个东西,无疑是js中最为坑的一个地方。 8 | 暂时不想写了,高程和相关资料很多。 9 | 重点是对于函数构成作用域的理解,理解了什么是函数作用域,正推、反推都可以解决大部分的闭包问题。 10 | 11 | 这里推荐一篇翻译的很好的文章,讲清楚了闭包的原理。 12 | 13 | [【译】看权威的wikipedia如何解释闭包 译者@ne_smalltown](https://segmentfault.com/a/1190000007386162) 14 | 15 | 再一个就是闭包的变体题目实在是非常多,如果认真准备的话,去多刷刷变体题目吧。 16 | 这里写几个闭包相关的题目。 17 | 18 | ```js 19 | var num = 1; 20 | var o = { 21 | num: 2, 22 | add: function() { 23 | this.num = 3; 24 | console.log('add', this); 25 | (function() { 26 | console.log('closure', this); 27 | console.log(this.num); 28 | this.num = 4; 29 | })(); 30 | console.log(this.num); 31 | }, 32 | sub: function() { 33 | console.log(this.num); 34 | } 35 | } 36 | o.add(); 37 | console.log(o.num); 38 | console.log(num); 39 | var sub = o.sub; 40 | sub(); 41 | 42 | // 请写出输出结果 43 | ``` 44 | 45 | ```js 46 | function fun(n,o) { 47 | console.log(o) 48 | return { 49 | fun:function(m){ 50 | return fun(m,n); 51 | } 52 | }; 53 | } 54 | var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,? 55 | var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,? 56 | var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,? 57 | 58 | //问:三行a,b,c的输出分别是什么? 59 | ``` 60 | 61 | ```js 62 | // 最基础题 63 | for(var i = 1; i < 10; i ++){ 64 | setTimeout(function(){ 65 | console.log(i); 66 | }, 1000); 67 | } 68 | 69 | // 变体一 70 | for (var i = 1; i < 10; i++) { 71 | (function(i){ 72 | setTimeout(function(){ 73 | console.log(i); 74 | }, i * 1000); 75 | })(i); 76 | } 77 | 78 | // 变体二 79 | for (var i = 1; i < 10; i++) { 80 | (function(){ 81 | setTimeout(function(){ 82 | console.log(i); 83 | }, i * 1000); 84 | })(); 85 | } 86 | 87 | // 变体三 88 | for (var i = 1; i < 10; i++) { 89 | (function(){ 90 | setTimeout(function(i){ 91 | console.log(i); 92 | }, i * 1000); 93 | })(); 94 | } 95 | ``` 96 | 97 | 理解闭包形成的原因,理解**定义时**和**运行时**的区别。 98 | -------------------------------------------------------------------------------- /docs/Collection/Events.md: -------------------------------------------------------------------------------- 1 | 2 | ## Q: 写一个events,backbone或者jquery,包括on、off、once、trigger 3 | 4 | ## A: 5 | 6 | `Author: @backbone @yeelan0319 @liyuk @bailnl` 7 | 8 | ### struct 9 | ```js 10 | this._events = { 11 | change: [callback_on_change1, callback_on_change2, ...], 12 | ... 13 | } 14 | ``` 15 | 16 | ### on 17 | ```js 18 | Events.on = function(name, callback, context) { 19 | if (callback) { 20 | var handlers = events[name] || (events[name] = []); 21 | handlers.push({callback: callback, context: context, ctx: context || this}); 22 | } 23 | return this; 24 | }; 25 | ``` 26 | 27 | #### off 28 | ```js 29 | Events.off = function(name, callback, context) { 30 | // 无参数清空所有 31 | if (!name && !callback && !context) { 32 | this._events = void 0; 33 | return this; 34 | } 35 | // 有name时,清空name对应 36 | if (!callback && !context) { 37 | delete this._events[name]; 38 | continue; 39 | } 40 | // 有callback时检查 41 | var remaining = []; 42 | if( 43 | callback && callback !== handler.callback && 44 | callback !== handler.callback._callback || 45 | context && context !== handler.context 46 | ){ 47 | //保留回调函数在数组中 48 | } 49 | } 50 | ``` 51 | 52 | ### trigger 53 | ```js 54 | //当绑定3个以下回调函数的时候Backbone会做如下优化处理,据说这样是可以提高执行效率的。 55 | var triggerEvents = function(events, args) { 56 | var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]; 57 | switch (args.length) { 58 | case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; 59 | case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return; 60 | case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return; 61 | case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return; 62 | default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return; 63 | } 64 | }; 65 | ``` 66 | 67 | ### once 68 | ```js 69 | var once = _.once(function(){ 70 | self.off(name, once); 71 | callback.apply(this, arguments); 72 | }); 73 | return this.on(name, once, context); 74 | ``` 75 | 76 | ## Roast: 77 | - Events的引入减少了callback的层级调用。 78 | - 解耦,一对多的关系。 79 | 这个问题是一个基本概念,但不要因为简单而忽视了这个基本概念。 80 | -------------------------------------------------------------------------------- /docs/guide/framework.md: -------------------------------------------------------------------------------- 1 | # Framework 2 | 3 | ## React 4 | - React的生命周期mount和update描述下 5 | - [React的生命周期中的isBatchingUpdates了解吗?Transaction知道吗](https://zhuanlan.zhihu.com/p/20328570) 6 | - React的vdom如何实现?jsx是怎样解析的? 7 | - React的Fiber是什么?具有什么样的特性? 8 | - React的diff/patch算法原理 9 | - React的组件逻辑(受控、非受控)?如何设计一个组件库 10 | - React的数据流,Redux、Mobx、Rxjs,发布订阅模式、观察者模式,flux和no-flux 11 | - React的事件注册和事件分发知道吗? 12 | - Redux解决了什么痛点(有什么优点),又有什么缺点 13 | - Redux的中间件有哪些?redux-actions、redux-promise、redux-thunk、redux-saga、redux-immutable了解过哪些?说说中间件的意义 14 | - Redux有什么优化方案? 15 | - SSR了解过吗?怎样做?了解Koa么? 16 | - React-Native了解过吗?JavascriptCore是什么? 17 | 18 | ## Vue 19 | - [Vue是如何设计响应式系统的?(依赖收集)](https://zhuanlan.zhihu.com/p/29318017) 20 | - 什么时候使用computed, methods, watch?之间有什么样区别? 21 | - template 和 render(jsx) 有什么的联系? 22 | - this.$nextTick是如何设计的? 23 | - Vue 组件 data 为什么必须是函数? 24 | 25 | ## AngularJS 26 | 尽管angularJS已经基本退出了历史舞台,但是相信有的同学还是做过相关的项目,并很有可能被面试官问起。 27 | 28 | - angularJS的数据绑定采用什么机制?详述原理 29 | - 如果通过angularJS的 directive/component 规划一套全组件化体系,可能遇到哪些挑战? 30 | - 一个angularJS应用应当如何良好地分层? 31 | - ng-click中写的表达式,能使用JS原生对象上的方法,比如Math.max之类的吗?为什么? 32 | 33 | ## Wheel 34 | 一系列教你如何徒手造轮子的文,翻译质量很不错。来自`@Tristan` 35 | 36 | - [项目结构](https://github.com/Troland/writing-a-javascript-framework/wiki/1.%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84) 37 | - [执行时间](https://github.com/Troland/writing-a-javascript-framework/wiki/2.%E6%89%A7%E8%A1%8C%E6%97%B6%E9%97%B4) 38 | - [代码运行沙箱](https://github.com/Troland/writing-a-javascript-framework/wiki/3.%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E6%B2%99%E7%AE%B1) 39 | - [数据绑定简介](https://github.com/Troland/writing-a-javascript-framework/wiki/4.%E6%95%B0%E6%8D%AE%E7%BB%91%E5%AE%9A%E7%AE%80%E4%BB%8B) 40 | - [基于-ES6-代理的数据绑定](https://github.com/Troland/writing-a-javascript-framework/wiki/5.%E5%9F%BA%E4%BA%8E-ES6-%E4%BB%A3%E7%90%86%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%91%E5%AE%9A) 41 | - [自定义元素](https://github.com/Troland/writing-a-javascript-framework/wiki/6.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%85%83%E7%B4%A0) 42 | - [客户端路由](https://github.com/Troland/writing-a-javascript-framework/wiki/7.%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%B7%AF%E7%94%B1) 43 | 44 | ## Nodejs 45 | 46 | - [node各种模块](https://github.com/parro-it/awesome-micro-npm-packages) 47 | - [如何~~通过饿了么 Node.js 面试~~进入阿里](https://elemefe.github.io/node-interview/#/sections/zh-cn/) 48 | 49 | ## Future 50 | 一些关于未来的GUI编程以及可能存在的变化 51 | 52 | - web-assembly 53 | - pwa的优劣 54 | - new ui:VR、AR、speech 55 | - learning to learn 56 | - web operating system (web 3.0) 57 | - new html spec. 58 | -------------------------------------------------------------------------------- /docs/assets/css/air.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | *, 3 | *:before, 4 | *:after { 5 | background: transparent !important; 6 | color: #000 !important; 7 | box-shadow: none !important; 8 | text-shadow: none !important; 9 | } 10 | 11 | a, 12 | a:visited { 13 | text-decoration: underline; 14 | } 15 | 16 | a[href]:after { 17 | content: " (" attr(href) ")"; 18 | } 19 | 20 | abbr[title]:after { 21 | content: " (" attr(title) ")"; 22 | } 23 | 24 | a[href^="#"]:after, 25 | a[href^="javascript:"]:after { 26 | content: ""; 27 | } 28 | 29 | pre, 30 | blockquote { 31 | border: 1px solid #999; 32 | page-break-inside: avoid; 33 | } 34 | 35 | thead { 36 | display: table-header-group; 37 | } 38 | 39 | tr, 40 | img { 41 | page-break-inside: avoid; 42 | } 43 | 44 | img { 45 | max-width: 100% !important; 46 | } 47 | 48 | p, 49 | h2, 50 | h3 { 51 | orphans: 3; 52 | widows: 3; 53 | } 54 | 55 | h2, 56 | h3 { 57 | page-break-after: avoid; 58 | } 59 | } 60 | 61 | html { 62 | font-size: 12px; 63 | } 64 | 65 | @media screen and (min-width: 32rem) and (max-width: 48rem) { 66 | html { 67 | font-size: 15px; 68 | } 69 | } 70 | 71 | @media screen and (min-width: 48rem) { 72 | html { 73 | font-size: 16px; 74 | } 75 | } 76 | 77 | body { 78 | line-height: 1.85; 79 | } 80 | 81 | p, 82 | .air-p { 83 | font-size: 1rem; 84 | margin-bottom: 1.3rem; 85 | } 86 | 87 | h1, 88 | .air-h1, 89 | h2, 90 | .air-h2, 91 | h3, 92 | .air-h3, 93 | h4, 94 | .air-h4 { 95 | margin: 1.414rem 0 .5rem; 96 | font-weight: inherit; 97 | line-height: 1.42; 98 | } 99 | 100 | h1, 101 | .air-h1 { 102 | margin-top: 0; 103 | font-size: 3.998rem; 104 | } 105 | 106 | h2, 107 | .air-h2 { 108 | font-size: 2.827rem; 109 | } 110 | 111 | h3, 112 | .air-h3 { 113 | font-size: 1.999rem; 114 | } 115 | 116 | h4, 117 | .air-h4 { 118 | font-size: 1.414rem; 119 | } 120 | 121 | h5, 122 | .air-h5 { 123 | font-size: 1.121rem; 124 | } 125 | 126 | h6, 127 | .air-h6 { 128 | font-size: .88rem; 129 | } 130 | 131 | small, 132 | .air-small { 133 | font-size: .707em; 134 | } 135 | 136 | /* https://github.com/mrmrs/fluidity */ 137 | 138 | img, 139 | canvas, 140 | iframe, 141 | video, 142 | svg, 143 | select, 144 | textarea { 145 | max-width: 100%; 146 | } 147 | 148 | @import url(http://fonts.googleapis.com/css?family=Open+Sans:300italic,300); 149 | 150 | body { 151 | color: #444; 152 | font-family: 'Open Sans', Helvetica, sans-serif; 153 | font-weight: 300; 154 | margin: 6rem auto 1rem; 155 | max-width: 48rem; 156 | text-align: center; 157 | } 158 | 159 | img { 160 | border-radius: 50%; 161 | height: 200px; 162 | margin: 0 auto; 163 | width: 200px; 164 | } 165 | 166 | a, 167 | a:visited { 168 | color: #3498db; 169 | } 170 | 171 | a:hover, 172 | a:focus, 173 | a:active { 174 | color: #2980b9; 175 | } 176 | 177 | pre { 178 | background-color: #fafafa; 179 | padding: 1rem; 180 | text-align: left; 181 | } 182 | 183 | blockquote { 184 | margin: 0; 185 | border-left: 5px solid #7a7a7a; 186 | font-style: italic; 187 | padding: 1.33em; 188 | text-align: left; 189 | } 190 | 191 | ul, 192 | ol, 193 | li { 194 | text-align: left; 195 | } 196 | 197 | p { 198 | color: #777; 199 | } -------------------------------------------------------------------------------- /docs/assets/css/modest.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | *, 3 | *:before, 4 | *:after { 5 | background: transparent !important; 6 | color: #000 !important; 7 | box-shadow: none !important; 8 | text-shadow: none !important; 9 | } 10 | a, 11 | a:visited { 12 | text-decoration: underline; 13 | } 14 | a[href]:after { 15 | content: " (" attr(href) ")"; 16 | } 17 | abbr[title]:after { 18 | content: " (" attr(title) ")"; 19 | } 20 | a[href^="#"]:after, 21 | a[href^="javascript:"]:after { 22 | content: ""; 23 | } 24 | pre, 25 | blockquote { 26 | border: 1px solid #999; 27 | page-break-inside: avoid; 28 | } 29 | thead { 30 | display: table-header-group; 31 | } 32 | tr, 33 | img { 34 | page-break-inside: avoid; 35 | } 36 | img { 37 | max-width: 100% !important; 38 | } 39 | p, 40 | h2, 41 | h3 { 42 | orphans: 3; 43 | widows: 3; 44 | } 45 | h2, 46 | h3 { 47 | page-break-after: avoid; 48 | } 49 | } 50 | 51 | pre, 52 | code { 53 | font-family: Menlo, Monaco, "Courier New", monospace; 54 | } 55 | 56 | pre { 57 | padding: .5rem; 58 | line-height: 1.25; 59 | overflow-x: scroll; 60 | } 61 | 62 | a, 63 | a:visited { 64 | color: #3498db; 65 | } 66 | 67 | a:hover, 68 | a:focus, 69 | a:active { 70 | color: #2980b9; 71 | } 72 | 73 | .modest-no-decoration { 74 | text-decoration: none; 75 | } 76 | 77 | html { 78 | font-size: 12px; 79 | } 80 | 81 | @media screen and (min-width: 32rem) and (max-width: 48rem) { 82 | html { 83 | font-size: 15px; 84 | } 85 | } 86 | 87 | @media screen and (min-width: 48rem) { 88 | html { 89 | font-size: 16px; 90 | } 91 | } 92 | 93 | body { 94 | line-height: 1.85; 95 | } 96 | 97 | p, 98 | .modest-p { 99 | font-size: 1rem; 100 | margin-bottom: 1.3rem; 101 | } 102 | 103 | h1, 104 | .modest-h1, 105 | h2, 106 | .modest-h2, 107 | h3, 108 | .modest-h3, 109 | h4, 110 | .modest-h4 { 111 | margin: 1.414rem 0 .5rem; 112 | font-weight: inherit; 113 | line-height: 1.42; 114 | } 115 | 116 | h1, 117 | .modest-h1 { 118 | margin-top: 0; 119 | font-size: 3.998rem; 120 | } 121 | 122 | h2, 123 | .modest-h2 { 124 | font-size: 2.827rem; 125 | } 126 | 127 | h3, 128 | .modest-h3 { 129 | font-size: 1.999rem; 130 | } 131 | 132 | h4, 133 | .modest-h4 { 134 | font-size: 1.414rem; 135 | } 136 | 137 | h5, 138 | .modest-h5 { 139 | font-size: 1.121rem; 140 | } 141 | 142 | h6, 143 | .modest-h6 { 144 | font-size: .88rem; 145 | } 146 | 147 | small, 148 | .modest-small { 149 | font-size: .707em; 150 | } 151 | 152 | 153 | /* https://github.com/mrmrs/fluidity */ 154 | 155 | img, 156 | canvas, 157 | iframe, 158 | video, 159 | svg, 160 | select, 161 | textarea { 162 | max-width: 100%; 163 | } 164 | 165 | @import url(http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700); 166 | @import url(http://fonts.googleapis.com/css?family=Arimo:700,700italic); 167 | html { 168 | font-size: 18px; 169 | max-width: 100%; 170 | } 171 | 172 | body { 173 | color: #444; 174 | font-family: 'Open Sans Condensed', sans-serif; 175 | font-weight: 300; 176 | margin: 0 auto; 177 | max-width: 48rem; 178 | line-height: 1.45; 179 | padding: .25rem; 180 | } 181 | 182 | h1, 183 | h2, 184 | h3, 185 | h4, 186 | h5, 187 | h6 { 188 | font-family: Arimo, Helvetica, sans-serif; 189 | } 190 | 191 | h1, 192 | h2, 193 | h3 { 194 | border-bottom: 2px solid #fafafa; 195 | margin-bottom: 1.15rem; 196 | padding-bottom: .5rem; 197 | text-align: center; 198 | } 199 | 200 | blockquote { 201 | border-left: 8px solid #fafafa; 202 | padding: 0.5rem; 203 | } 204 | 205 | pre, 206 | code { 207 | background-color: #fafafa; 208 | } -------------------------------------------------------------------------------- /docs/guide/advanced.md: -------------------------------------------------------------------------------- 1 | # Advanced 2 | 3 | 我们会尽可能地增加`Advanced`(进阶)这里面的题目的数量和难度,当然也包含很多基础知识点的详细内容。这里的知识点的区分暂时并不是特别明显,之后onion来整理这块儿内容。 4 | 5 | ## Browser 6 | 7 | - [打开一个网页经历了那些过程?](http://web.jobbole.com/94150/) 8 | - [浏览器加载白屏是什么原因?](/Collection/WhiteScreen.md) 9 | - [千万访问量的项目,前端需要注意些什么?](/Collection/DozensOfVisits.md) 10 | 11 | ## JavaScript 12 | 这一章我们尽量带来较深层的JavaScript语言层次的问题,我们会拿出几个JavaScript较深入的点来讲。 13 | 14 | - [表达式和语句有什么区别?如何把语句转换为表达式?](/Collection/ExpressionAndStatement.md) 15 | - 什么叫执行上下文栈(Execution Context Stack)? 一个函数调用会产生多少个上下文环境?如何激活一个上下文,什么叫caller(调用者),什么叫callee(被调用者)?给你一段代码能否画出执行过程中的上下文堆栈变化? 16 | - 执行上下文包括哪些结构(状态/属性),如何追踪关联代码的执行进度? 17 | - eval在调用的时候有哪些特别的地方?eval函数自身会产生上下文吗?会影响当前的调用上下文吗? 18 | - 什么叫变量对象?什么叫活动对象? 19 | - [词法作用域是什么?闭包是如何形成的?](/Collection/closure_moyu.md) 20 | - `var foo = function bar () {}` 命名函数表达式中(上述的foo函数)bar变量是定义在哪一层作用域的? 21 | - [`(0, 1, 2)` 的结果是什么?](/Collection/NumberExpression.md) 22 | - `var foo = { value: 2, bar: function () { return this.value; }` 中`(foo.bar, foo.bar)()`的`this`值是什么?`(foo.bar = foo.bar)()`、`(false || foo.bar)()`呢? 23 | 24 | ## Application 25 | 这里将JavaScript除去基本语言特性之外的东西整理出来,主要是JavaScript在工程上的应用场景,以及一些原理性问题。 26 | 27 | - [继承(重点)](/Collection/Inherit.md) 28 | - [异步(重点)](https://blog.risingstack.com/writing-a-javascript-framework-execution-timing-beyond-settimeout/ ) 29 | - [new操作符做了什么](http://blog.csdn.net/aimingoo/article/details/6105048) 30 | - [JavaScript 内存管理](https://github.com/Troland/how-javascript-works/blob/master/memory-management.md) 31 | - [实现一个Promise](https://github.com/Liyuk/code-repertory/blob/master/promise/promise.js) 32 | - [js模块化现状?AMD和CMD是什么?](https://segmentfault.com/a/1190000009591055) 33 | - 如何在前端解析二进制?流媒体、图片二进制数据怎样渲染到页面上? 34 | - [函数记忆是什么?什么场景下使用?(动态规划)](/Collection/memorization.md) 35 | - 实现一个Lazyman [Answer 1](http://www.cnblogs.com/walls/p/6341614.html) [Answer 2](http://web.jobbole.com/89626/) 36 | - [实现throttle和debounce (必会)](https://jinlong.github.io/2016/04/24/Debouncing-and-Throttling-Explained-Through-Examples/) 37 | - require.js的实现原理,[webpack的实现原理与loader的实现](http://taobaofed.org/blog/2016/09/09/webpack-flow/) 38 | - [Babel是如何实现的](https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md) 39 | - [前端工程师可以用编译做什么?](https://www.zhihu.com/question/274357154) 40 | - [如何用正则表达式实现模板引擎?(正则表达式相关知识点)](http://louiszhai.github.io/2016/06/13/regexp/) 41 | 42 | ## HTML 43 | - 讲一下whatwg标准上的event loop规范。(别说你没看过 44 | - microTask的有哪些,Task的有哪些?(最好答出来所有的 45 | - 构思一下利用Task和microTask来完成框架层面的时间调度( 比如vue是如何利用microTask来实现batch update的 46 | - 讲一下你对web components的理解 47 | - web worker适合哪些场景 48 | 49 | ## Function Program 50 | - [闭包(重点)](/Collection/Clojure.md) 51 | - [柯里化(Currying)](/Collection/Currying.md) 52 | 53 | ## HTTP 54 | - http1.0和http1.1的区别 55 | - http请求码有哪些?206、302、303、304、307 56 | - 能说下304具体怎样实现吗? 57 | - http缓存逻辑是怎样的?协商缓存与强缓存?Last-Modified / Etag / Expires / Cache-Control ? 58 | - osi七层协议和tcp/ip四层协议 59 | - 三次握手和四次握手 60 | - 跨域是什么?http协议中如何判断跨域?如何解决跨域问题? 61 | - http2具体内容?SDPY了解么? 62 | - HTTPS如何实现?tsl/ssl是什么?对称加密、非对称加密在什么时候、对什么数据加密? 63 | - DNS劫持是什么? 64 | - [浏览器在一次 HTTP 请求中,需要传输一个 4097 字节的文本数据给服务端,可以采用那些方式?](/Collection/SendData.md) 65 | 66 | ## Optimization 67 | - 首屏优化 68 | - 预加载资源、预解析DNS 69 | - 懒加载图片怎么做 70 | - [iframe一般怎么使用?](/Collection/iframeUse.md) 71 | - window.onload、document.ready顺序?iframe会阻塞吗? 72 | - cdn是什么?如何查找最近的cdn? 73 | - gzip、chucked 74 | - 前端安全:xss攻击和防范、CSRF、CORS 75 | - 硬件加速怎样开启 76 | - 优化中会提到缓存的问题,问:静态资源或者接口等如何做缓存优化 77 | - 页面DOM节点太多,会出现什么问题?如何优化? 78 | 79 | ## Products 80 | 这里主要是一些生产中真实存在的问题。 81 | 82 | - 一个feed流,有哪些展现方式?如果当前页面可视区有5个格子,而你有20条信息需要展示,请问有哪些自动展示的算法? 83 | - [移动端的缓存机制有哪几种?](https://segmentfault.com/a/1190000004132566) 84 | - 小程序如何与native通信?react-native实现原理?jsbridge如何实现? 85 | - 过万条数据如何加载和渲染? 86 | - 如何在前端解析二进制,流媒体、图片二进制数据怎样渲染到页面上? 87 | - 如何解析二进制音频、视频? 88 | - 文件如何显示上传百分比? 89 | - 如何制作一个富文本,需要考虑哪些结构? 90 | - html5的播放器怎么做?视频直播如何在浏览器里面实现?HLS、RTMP 91 | - 如何在浏览器里面裁剪图片?如何裁剪视频,对视频做逐帧分析? 92 | - 如何实现一个具有引导功能的组件库? 93 | - 如何封装一个Form和FormItem,使其能够跟input、select、checkbox、radio等组件进行 数据存储、数据校验(自定义逻辑)、校验反馈? 94 | - echart这类图像库的实现原理? 95 | - i18n的国际化方案应该是怎样的? 96 | - 数据埋点的意义是什么?应当针对哪些数据进行埋点?如何构建一个埋点系统? 97 | - 小程序的实现原理是什么?[这【五篇】文章将带你深入了解「微信小程序」](https://github.com/phodal/articles/issues/32) 98 | - 小游戏的实现原理是什么?[Cocos知乎文章:微信小游戏上手](https://www.zhihu.com/org/cocos-3/posts)、[深入理解使用白鹭引擎开发微信小游戏的构建机制](https://zhuanlan.zhihu.com/p/32749103) 99 | - mpvue这样h5转小程序的工具的原理是什么?怎样去实现?[官方宣传文档](https://zhuanlan.zhihu.com/p/34450979)、[如何看待美团开源mpvue](https://www.zhihu.com/question/268421668) 100 | 101 | ## Whiteboard 102 | 前端所需要的白板面试题算法难度不高,主要针对JavaScript基础类型的遍历与扩展。 103 | 但是如果有喜欢考算法题的,可能会考的很难。所以还是推荐如果有时间的话,可以去把leetcode的easy和medium刷一下,hard可以跳过不看。 104 | 国内的面试难度其实很小,有兴趣的朋友看看国外的面试题就知道自己有多么菜了。 105 | 106 | - parseQuery 107 | - flatten 108 | - [乱序算法(Fisher–Yates)](https://github.com/Mountain-Buzhou/Interview-Book/issues/1) 109 | - [模版引擎](/Collection/Template.md) 110 | - 反转二叉树 111 | - 将两个有序数组合并成为一个有序数组 112 | - 全选和单行选中的联动 113 | - 数组去重,考虑object、NaN、数字1,弱类型转换 114 | - 汉诺塔的实现 115 | - bind 116 | - currying 117 | - 一个无重复元素的数组,求所有两数之和为k的组合 118 | - 变体题:一个无重复元素的数组,求元素和(元素个数小于n)为k的组合 119 | - [实现events(发布订阅/观察者模式)](/Collection/Events.md) 120 | - 找出数组中最大的两数之差 121 | - 棋盘最短路:动态规划、搜索+剪枝、时间优化、空间优化 122 | - 二叉树遍历:前序、后序、中序,时间复杂度,空间复杂度O(1),递归非递归 123 | - 双向链表寻找中间的元素,单向链表寻找中间的元素 124 | - 查找数组中第k大的数 125 | 126 | 127 | 128 | ## System Design 129 | 这类题目非常繁琐以及复杂,主要出现在高级工程师的最终面试里。对于不同层级的开发人员的回答要求各不相同,但有必要全局地了解整个系统的设计结构和基本概念。 130 | 131 | - 请设计一个前端的组件库,包括组件的分类、具体的内容、API的规范、协作开发的规范。 132 | - [System Design Primer 中文](https://github.com/donnemartin/system-design-primer/blob/master/README-zh-Hans.md) 133 | - [System Design Interview](https://github.com/checkcheckzz/system-design-interview) 134 | 135 | - [面试常问问题及问答思路](/Collection/OftenAsked.md) 136 | 137 | -------------------------------------------------------------------------------- /docs/Collection/Inherit.md: -------------------------------------------------------------------------------- 1 | ## Q: 继承 2 | 3 | ## A: 4 | 5 | `Author: @liyuk @高程(三)` 6 | 7 | 这部分内容其实在2015年就有过详细的编写,但是最近发现当年的代码似乎并没有很明白的阐述原理,重新翻了高程整理一下。 8 | 特别强调一下,基本概念!基本概念!基本概念!(怨念) 9 | 10 | ## ES5 11 | 12 | ### 1-原型链 13 | ```js 14 | function Super() {} 15 | 16 | function Sub() {} 17 | 18 | // 继承 19 | Sub.prototype = new Super(); 20 | 21 | // 生成实例 22 | var sub = new Sub(); 23 | 24 | ``` 25 | 26 | - 所有的类型默认原型为Object 27 | - 确定原型和实例的关系 28 | ```js 29 | // instanceof 30 | console.log(sub instanceof Sub); 31 | console.log(sub instanceof Super); 32 | console.log(sub instanceof Object); 33 | 34 | // isPrototypeOf 35 | console.log(Object.prototype.isPrototypeOf(sub)); 36 | ``` 37 | - 定义方法时,要注意区分子类和超类的方法定义,使用字面量创建原型方法会重写原型链 38 | ```js 39 | Sub.prototype = { 40 | name: 'liyuk' 41 | } 42 | ``` 43 | 44 | #### 注意 45 | - 如果原型包含引用类型,所有实例会共享该类型 46 | - 创建子类型时,无法在不影响其他实例的情况下,给超类的构造函数传递参数 47 | 48 | 49 | **实际使用时会较少单独使用原型链** 50 | 51 | ### 2-构造函数 52 | 53 | ```js 54 | function Super() {}; 55 | 56 | function Sub() { 57 | // 继承 58 | Super.call(this); // apply 也可以 59 | } 60 | 61 | // 生成实例 62 | var sub = new Sub(); 63 | ``` 64 | - 子类型构造函数可以向超类型构造函数传递参数 65 | ```js 66 | function Super(name) { 67 | this.name = name; 68 | } 69 | 70 | function Sub() { 71 | Super.call(this, 'liyuk'); 72 | } 73 | ``` 74 | #### 注意 75 | - 函数无法复用 76 | 77 | ### 3-组合继承 78 | 即将原型链和构造函数组合在一起。 79 | 通过原型链实现对原型属性和方法的继承,通过构造函数来实现对实例属性的继承。 80 | ```js 81 | function Super() {}; 82 | 83 | function Sub(name) { 84 | // 构造函数继承 85 | Super.call(this, name); 86 | }; 87 | 88 | // 原型链继承 89 | Sub.prototype = new Super(); 90 | // 增强对象 91 | Sub.prototype.constructor = Sub; 92 | 93 | // 生成实例 94 | var sub = new Sub(); 95 | ``` 96 | **最常用的的继承方法** 97 | #### 注意 98 | - 会调用两次超类型的构造函数:一次是在创建子类型原型,一次是在子类型构造函数内部 99 | 100 | ### 4-原型式继承 101 | 借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。 102 | ```js 103 | function _object(o) { 104 | // 临时构造函数 105 | function F() {}; 106 | F.prototype = o; 107 | return new F(); 108 | } 109 | 110 | var Super = {}; 111 | 112 | // 继承 113 | var sub = _object(Super); 114 | ``` 115 | es5中的`Object.create`与`_object`实现类似,都是用来创建新对象,即副本。 116 | #### 注意 117 | - 可以理解为浅拷贝,引用类型依旧会指向同一个地址,与原型链继承一样存在共享值的问题。 118 | 119 | ### 5-寄生式继承 120 | 创建一个仅用于封装继承过程的函数,该函数内部以某种方式增强对象,最后(像)做完所有工作后返回对象。 121 | ```js 122 | function _create(o) { 123 | var clone = _object(o); 124 | // method 125 | return clone; 126 | } 127 | ``` 128 | 寄生本质上就是进行浅拷贝后生成了新的对象,然后在新的对象上去添加方法,最后返回该新对象。从而实现不对原对象进行修改,并获得了原对象所有方法。 129 | 130 | ### 6-寄生组合式继承 131 | 组合式继承会有两次调用超类型构造函数的问题。 132 | 133 | ```js 134 | function Super() {}; 135 | 136 | function Sub(name) { 137 | // 构造函数继承 138 | Super.call(this, name); // 第二次调用Super 139 | }; 140 | 141 | // 原型链继承 142 | Sub.prototype = new Super(); // 第一次调用Super 143 | // 增强对象 144 | Sub.prototype.constructor = Sub; 145 | 146 | // 生成实例 147 | var sub = new Sub(); 148 | ``` 149 | 第二次在Sub构造函数内部调用Super时,生成了新的属性,从而屏蔽了原型中(超类型)的同名属性。 150 | 151 | 寄生组合式继承,**即通过构造函数来继承属性,通过原型链的混成形式来集成方法。** 152 | 基本思路是**不必为了指定子类型的原型而调用超类型的构造函数** 153 | ```js 154 | // 寄生 155 | function inherit(sub, super) { 156 | // 高程三中的写法是 var prototype = Object(super.prototype); 157 | // 这样写可能有些问题,会污染超类型的原型,保持疑惑 158 | // 所以有可能是用Object.create,或者上文提到的原型式继承_obejct,或者寄生式继承的_create 159 | // Comment: @bramble 160 | var prototype = Object(super.prototype); // 创建对象,创建超类型原型副本 161 | prototype.constructor = sub; // 增强对象,弥补因重写原型而失去的默认constructor 162 | sub.prototype = prototype; // 指定对象 163 | } 164 | ``` 165 | 修改后的寄生组合模式为 166 | ```js 167 | function Super() {}; 168 | 169 | function Sub() { 170 | // 使用构造函数来继承属性 171 | Super.call(this); 172 | }; 173 | 174 | // 使用寄生来混入原型链 175 | _inherit(Sub, Super); 176 | 177 | // 生成实例 178 | var sub = new Sub(); 179 | 180 | ``` 181 | **寄生组合式继承是最`引用`类型最理想的继承范式** 182 | 183 | ### 7-Object.create `@MDN` `兼容性:IE9+` 184 | ```js 185 | // Super - 父类(superclass) 186 | function Super() { 187 | this.x = 0; 188 | this.y = 0; 189 | } 190 | 191 | // 父类的方法 192 | Super.prototype.move = function(x, y) { 193 | this.x += x; 194 | this.y += y; 195 | console.info('Super moved.'); 196 | }; 197 | 198 | // Sub - 子类(subclass) 199 | function Sub() { 200 | Super.call(this); // call super constructor. 201 | } 202 | 203 | // 子类续承父类 204 | Sub.prototype = Object.create(Super.prototype); 205 | Sub.prototype.constructor = Sub; 206 | 207 | // 因为使用“.prototype =...”后,constructor会改变为“=...”的那个 208 | // constructor,所以要重新指定.constructor 为自身。 209 | ``` 210 | 211 | #### polyfill 212 | 尽管在 ES5 中 Object.create支持设置为[[Prototype]]为null,但因为那些ECMAScript5以前版本限制,此 polyfill 无法支持该特性。 213 | 214 | ```js 215 | if (typeof Object.create !== "function") { 216 | Object.create = function (proto, propertiesObject) { 217 | if (typeof proto !== 'object' && typeof proto !== 'function') { 218 | throw new TypeError('Object prototype may only be an Object: ' + proto); 219 | } else if (proto === null) { 220 | throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument."); 221 | } 222 | 223 | if (typeof propertiesObject != 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument."); 224 | 225 | function F() {} 226 | F.prototype = proto; 227 | 228 | return new F(); 229 | }; 230 | } 231 | ``` 232 | 233 | ## ES6 234 | ### Class extends `@ruanyifeng` 235 | es6的class其实就是个语法糖,babel转出来的依旧是寄生组合式继承。 236 | 具体的使用没有太多的可以说的,需要注意super即可以当函数,也可以实例。这部分不做细说,因为很复杂,有兴趣参考[es6 Class的继承](http://es6.ruanyifeng.com/#docs/class-extends#super-关键字)。 237 | 需要注意的是,**ES5的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。** 238 | 239 | ### Object.setPrototypeOf 240 | 将一个指定的对象的原型设置为另一个对象或者null 241 | 242 | ```js 243 | // 语法 244 | Object.setPrototypeOf(obj, prototype) 245 | 246 | // 实现原理 247 | Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) { 248 | obj.__proto__ = proto; 249 | return obj; 250 | } 251 | ``` 252 | 253 | ## 其他 254 | 255 | ### 继承在js当中的使用 256 | - 高阶函数+工厂模式,可以实现继承的效果,原理偏向于构造函数实现继承 257 | - react、vue等基础库对于各种基础类型的继承 258 | - 复杂数据结构,诸如树、图等结构的复用和扩展 259 | - canvas,基本图像类 派生出 线 圆 等各个需要的东西`@vamcc` 260 | 261 | ### 多继承 262 | 多继承是个伪命题,会导致菱形继承。 263 | ```js 264 | B extends A 265 | C extends A 266 | 267 | D extends B, C 268 | 269 | // 原型链合并 270 | var sub = new Sub(); 271 | 272 | Sub.prototype = Object.assign({}, Sub.prototype, new Super2()); 273 | 274 | // 构造函数 275 | function Sub() { 276 | Super1.call(this); 277 | Super2.call(this); 278 | } 279 | ``` 280 | 有兴趣去看看C++的菱形继承和虚继承,没兴趣不用在意。 281 | 282 | 283 | ## Roast 284 | 基本概念!基本概念!基本概念! 285 | 一脸懵逼,生无可恋。 286 | -------------------------------------------------------------------------------- /docs/Collection/Currying.md: -------------------------------------------------------------------------------- 1 | ## Q: Currying 2 | 3 | ## A: 4 | 5 | `Author: @liyuk` 6 | `Proofreader: @沉禹` 7 | 8 | ### 简单介绍 9 | 柯里化又叫部分求值,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 10 | 11 | --- 12 | ### 基础阅读 13 | 14 | 如果需要了解学习柯里化的概念,何幻大神的《柯里化的前生今世》系列十三篇文章讲的非常全,并且很深入浅出、浅显易懂(数学不好就难懂了) 15 | 16 | [知乎专栏:业余程序员的个人修养](https://zhuanlan.zhihu.com/self-discipline?group_id=954635149120458752) 17 | 18 | 19 | 对于使用Javascript来学习函数式编程,槽点很多,具体可以看看这两个链接: 20 | 21 | [Functional Programming in Javascript === Garbage](https://awardwinningfjords.com/2014/04/21/functional-programming-in-javascript-equals-garbage.html) 22 | 23 | [贺老关于《Functional Programming in Javascript === Garbage》的吐槽](https://github.com/hax/hax.github.com/issues/14) 24 | 25 | [Jim的吐槽: JavaScript可以作为函数式语言学习吗? - Jim Liu的回答 - 知乎]( 26 | https://www.zhihu.com/question/36525679/answer/67924020) 27 | 28 | --- 29 | ### 面试题库 30 | 31 | 柯里化(Currying)具有:延迟计算、参数复用、动态生成函数的作用。相关的出题都是围绕着三个点来的,同时需要明确理解Clojure与Currying之间的联系([简单了解Clojure与Lisp](https://www.jianshu.com/p/a41a9a46e0a1?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation))。但网上的资料都过于浅显,所以还是需要自己去做一些深入的了解。 32 | 接下来说面试题,主要引用了[柯里化在工程中有什么好处? - 赵雨森的回答 - 知乎]( 33 | https://www.zhihu.com/question/37774367/answer/192978122),以及我之前积累的几段代码。 34 | 35 | #### 延迟计算 36 | 37 | ```js 38 | // curring 函数 39 | function currying(func) { 40 | const args = []; 41 | return function result(...rest) { 42 | if (rest.length === 0) 43 | return func(...args); 44 | args.push(...rest); 45 | return result; 46 | } 47 | } 48 | 49 | const add = (...args) => args.reduce((a, b) => a + b); 50 | 51 | const sum = currying(add); 52 | 53 | sum(1,2)(3); 54 | sum(4); 55 | sum(); // 10 56 | 57 | ``` 58 | 59 | 这个题目稍微简化一下,当我们不使用currying函数、不存在拆分arguments,而是只是实现一个简单功能的时候,比如 60 | `sum(1)(2)(3)() = 6`这样的问题时,可以使用递归进行实现,这里就不进行代码实现了。 61 | 同时我们也许可以选择一个更难一点的问题,比如`sum(1)(2)(3) = 6`这个问题的实现,则需要考虑取值的结果,实际上考点一个是`递归`,一个是`求值`,也就是`valueOf`和`toString`。 62 | ```js 63 | // add(1)(2)(3)(4) 64 | 65 | // method 1 66 | function add(num) { 67 | var sum = 0; 68 | sum += num; 69 | var tempFun = function(nnum) { 70 | if (arguments.length === 0) { 71 | return sum; 72 | } else { 73 | sum += nnum; 74 | return tempFun; 75 | } 76 | } 77 | tempFun.valueOf = function() { 78 | return sum; 79 | } 80 | tempFun.toString = function() { 81 | return sum + ''; 82 | } 83 | return tempFun; 84 | } 85 | 86 | // method 2 87 | function add(num) { 88 | var args = []; 89 | 90 | function addNum() { 91 | if (arguments.length === 0) { 92 | return calulate; 93 | } else { 94 | Array.prototype.push.apply(args, Array.prototype.splice.call(arguments, 0)); 95 | return addNum; 96 | } 97 | } 98 | 99 | function calulate() { 100 | var result = args.reduce((previousValue, currentValue) => { 101 | return previousValue + currentValue; 102 | }, 0); 103 | args = []; 104 | return result; 105 | } 106 | 107 | addNum.valueOf = function() { 108 | return calulate(); 109 | } 110 | addNum.toString = function() { 111 | return calulate() + ''; 112 | } 113 | return addNum; 114 | } 115 | 116 | 117 | // add(args) = sum(1, 2, 3, 4) 118 | function add(args) { 119 | return sum.apply(this, args); 120 | } 121 | ``` 122 | 123 | #### 参数复用 124 | 125 | 例如兼容现代浏览器和IE浏览器的添加事件方法,我们通常会这样写: 126 | ```js 127 | const addEvent = function (elem, type, fn, cature) { 128 | if (window.addEventListener) { 129 | elem.addEventListener(type, (e) => fn.call(elem, e), capture); 130 | } else if (window.attachEvent) { 131 | elem.attachEvent('on' + type, (e) => fn.call(elem, e); 132 | } 133 | } 134 | ``` 135 | 这种方法显然有个问题,就是每次添加事件处理都要执行一遍`if {...} else if {...}`。其实用下面的方法只需判断一次即可: 136 | ```js 137 | const addEvent = (function () { 138 | if (window.addEventListener) { 139 | return (elem, type, fn, capture) => { 140 | elem.addEventListener(type, (e) => fn.call(elem, e), capture); 141 | }; 142 | } else { 143 | return (elem, type, fn, capture) => { 144 | elem.attachEvent('on' + type, (e) => fn.call(elem, e); 145 | }; 146 | } 147 | })(); 148 | ``` 149 | 这个例子,第一次`if {...} else if {...}`判断之后,完成了部分计算,动态创建新的函数来处理后面传入的参数,以后就不必重新进行计算了。这是一个典型的柯里化的应用。 150 | 151 | #### 动态生成函数 152 | 153 | 当多次调用同一个函数,并且传递的参数绝大多数是相同的时候,那么该函数就是一个很好的柯里化候选。例如我们经常会用`Function.prototype.bind`方法来解决上述问题。 154 | ```js 155 | const obj = { name: 'test' }; 156 | const foo = function (prefix, suffix) { 157 | console.log(prefix + this.name + suffix); 158 | }.bind(obj, 'currying-'); 159 | 160 | foo('-function'); // currying-test-function 161 | ``` 162 | 与`call`/`apply`方法直接执行不同,`bind`方法将第一个参数设置为函数执行的上下文,其他参数依次传递给调用方法(函数的主体本身不执行,可以看成是延迟执行),并动态创建返回一个新的函数。这很符合柯里化的特征。下面来手动实现一下`bind`方法: 163 | ```js 164 | // es6 165 | Function.prototype.bind = function (context, ...args) { 166 | return (...rest) => this.call(context, ...args, ...rest); 167 | }; 168 | 169 | // es5 170 | Function.prototype.bind = function(oThis) { 171 | var args = Array.prototype.slice.call(arguments, 1); 172 | var fToBind = this; 173 | var F = function() {}; 174 | var fBound = function() { 175 | return ftoBind.apply(this instanceof F ? this : oThis || this, 176 | args.concat(Array.prototype.slice.call(arguments))); 177 | } 178 | F.prototype = fToBind.prototype; 179 | fBound.prototype = new F(); 180 | return fBound; 181 | } 182 | 183 | ``` 184 | --- 185 | ### uncurrying 186 | ```js 187 | Function.prototype.uncurry = function() { 188 | var _this = this; 189 | return function() { 190 | return Function.prototype.call.apply(_this, arguments); 191 | } 192 | } 193 | ``` 194 | - 为Function原型添加unCurrying方法,这样所有的function都可以被借用; 195 | - 返回一个借用其它方法的函数,这是目的; 196 | - 借用call方法实现,但call方法参数传入呢?借用apply,至此完毕。 197 | 198 | --- 199 | ### 推荐库 200 | #### Ramda.js 201 | 函数式编程优势主要体现在**数据不变性**和**函数无副作用**两方面。虽然 Ramda 没有对此特别加强,但它在这两方面支持的非常好。 202 | Ramda 的目标更为专注:专门为函数式编程风格而设计,更容易创建函数式 pipeline、且从不改变用户已有数据。 203 | Ramda 主要特性如下: 204 | - Ramda 强调更加纯粹的函数式风格。数据不变性和函数无副作用是其核心设计理念。这可以帮助你使用简洁、优雅的代码来完成工作。 205 | - Ramda 函数本身都是自动柯里化的。这可以让你在只提供部分参数的情况下,轻松地在已有函数的基础上创建新函数。 206 | - Ramda 函数参数的排列顺序更便于柯里化。通常最后提供要操作的数据。 207 | 最后两点一起,使得将多个函数构建为简单的函数序列变得非常容易,每个函数对数据进行变换并将结果传递给下一个函数。Ramda 的设计能很好地支持这种风格的编程。 208 | [Document](http://ramdajs.com/0.19.0/index.html) 209 | [Github](https://github.com/ramda/ramda) 210 | 211 | #### Lodash.js / Underscore.js 212 | 213 | Lodash 214 | 是一个一致性、模块化、高性能的 JavaScript 实用工具库。 215 | 216 | [Lodash document](https://www.lodashjs.com) 217 | 218 | Underscore一个JavaScript实用库,提供了一整套函数式编程的实用功能,但是没有扩展任何JavaScript内置对象。它是这个问题的答案:“如果我在一个空白的HTML页面前坐下, 并希望立即开始工作, 我需要什么?“...它弥补了部分jQuery没有实现的功能,同时又是Backbone.js必不可少的部分。 219 | 220 | [Underscore document](http://underscorejs.org) 221 | 222 | --- 223 | ## Roast: 224 | 在自己并没有彻底吃透的区域,搬运其实也有风险的,可能会有知识误区,不仅误导自己也误导他人。 225 | 因此我也只能说是在Javascript这门语言的fp(函数式编程)上,稍微能够理解`一点点`这种并不太能广泛应用却可以用来吹逼的知识点,因而觉得整理的资料也许还是有些用处。 226 | 事实上,Javascript并不太适合用于学习fp,因为业界对于fp这个东西,除去对于表层概念的瞎吹,核心的问题并没有得到解决。而对于Lodash这类库的使用,也更多表现为基础操作库,而并非是应用fp的一些核心概念,`活生生用得像个语法糖一样`。 227 | 如果需要再进一步的学习了解,可以看看ClojureScript相关资料,解决了一些Javascript在fp上的不彻底的一些问题(具体问题我也无法举例,因为学习不彻底)。再一个可以看看youtube上这个视频[ClojureScript for Skeptics - Derek Slager](https://www.youtube.com/watch?v=gsffg5xxFQI)。 228 | 229 | --- 230 | ## 扩展阅读 231 | **《泛函分析》** -------------------------------------------------------------------------------- /docs/Collection/closure_moyu.md: -------------------------------------------------------------------------------- 1 | # 闭包之魔芋理解 2 | 3 | `Author: @魔芋` 4 | 5 | 纯属个人理解,可能存在错误。欢迎指教。 6 | 7 | 8 | 9 | ### 【魔芋】概念解释: 10 | 11 | 01,在一个函数内声明一个函数,形成了嵌套函数。此时,外边的函数称为外部函数。内部的称为内部函数。或称为父函数和子函数。 12 | 13 | 14 | 15 | 02,闭包wiki: 16 | 17 | 18 | 19 | 03,JS采用词法作用域(lexical scoping),函数的执行依赖于函数作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。 20 | 21 | - 词法作用域:词法作用域也叫静态作用域,是指作用域在词法解析阶段就已经确定了,不会改变。 22 | - 动态作用域:是指作用域在运行时才能确定。 23 | 24 | 25 | 26 | 参看下面的例子,引自[杨志的回答](https://www.zhihu.com/question/20032419/answer/13742892) 27 | 28 | ``` 29 | var foo=1; 30 | 31 | function static(){ 32 | alert(foo); 33 | } 34 | 35 | !function(){ 36 | var foo=2; 37 | static(); 38 | 39 | }(); 40 | ``` 41 | 42 | 在js中,会弹出1而非2,因为static的scope在创建时,记录的foo是1。 43 | 如果js是动态作用域,那么他应该弹出2 44 | 45 | 46 | 47 | 48 | 49 | 04,魔芋:识别闭包,在词法分析阶段已经确定了。 50 | 51 | 当外部函数运行的时候,一个闭包就形成了,他由内部函数的代码以及任何内部函数中指向外部函数局部变量的引用组成。 52 | 53 | 54 | 55 | 56 | 57 | ------ 58 | 59 | 60 | 61 | 62 | 63 | ### 【Q】函数第一次被调用时,会发生什么? 64 | 65 | 当函数第一次被调用时,会创建一个执行环境(execution context)及相应的作用域链,并把作用域链赋值给一个特殊的内部属性(即`[[Scope]]`)。 66 | 67 | 然后,使用`this`、`arguments`和其他参数来初始化函数的活动对象(activation object)。 68 | 69 | 在作用域链中,内部函数的活动对象出于第一位,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位,……直至作为作用域链终点的全局执行环境。 70 | 71 | 每次调用JS函数时,会为之创建一个新的对象来保存所有的局部变量(函数定义的变量,函数参数。),把这个对象添加到作用域链中。函数体内部的变量都保存在函数作用域内。 72 | 73 | 我们将作用域链看做一个对象列表,而不是一个栈。(魔芋:栈是一种线性表,仅允许在表的一端进行插入和删除运算。) 74 | 75 | 当函数返回的时候,就从作用域链中将这个绑定变量的对象删除。 76 | 77 | 如果这个函数不存在嵌套的函数,也没有其他引用指向这个绑定变量的对象,它就会被当做垃圾回收掉(魔芋:这个操作由浏览器自动完成)。 78 | 79 | 80 | 81 | ### 【Q】闭包是什么? 82 | 83 | 闭包(closure)是可以访问外部函数作用域中的变量的函数。(外部函数的参数也可以访问) 84 | 85 | 86 | 87 | 88 | 89 | ### 【Q】为什么闭包函数可以访问外部函数的变量? 90 | 91 | 因为闭包函数的作用域链包含了外部函数的作用域。 92 | 93 | 94 | 95 | ### 【Q】如何创建闭包? 96 | 97 | 在一个函数类内创建另外一个函数。内部函数使用了外部函数的变量,就形成了闭包。 98 | 99 | 100 | 101 | ### 【Q】普通函数的内部函数是闭包函数么? 102 | 103 | 魔芋:不是。 104 | 105 | 106 | 107 | ### 【Q】闭包函数必须返回(return)么,return这个闭包函数? 108 | 109 | 魔芋:不必要返回,只要使用外部函数的变量即可。 110 | 111 | 代码: 112 | 113 | ``` 114 | function fn1() { 115 | var a = 1; 116 | 117 | 118 | 119 | function fn2() { 120 | console.log(a); 121 | } 122 | 123 | fn2(); 124 | 125 | 126 | } 127 | 128 | fn1(); 129 | ``` 130 | 131 | 132 | 133 | ### 【Q】 如果用不同的变量引用函数中的闭包函数。 它们是相同的么? 134 | 135 | 是不同的。 136 | 137 | 简单的例子: 138 | 139 | ``` 140 | function outter(){ 141 | var x = 0; 142 | return function(){ 143 | return x++; 144 | } 145 | } 146 | var a = outter(); 147 | console.log(a()); 148 | console.log(a()); 149 | var b = outter(); 150 | console.log(b()); 151 | console.log(b()); 152 | ``` 153 | 154 | 运行结果为: 155 | 0 156 | 1 157 | 0 158 | 1 159 | 160 | 161 | 162 | ### 【Q】闭包的用途? 163 | 164 | - 可以创建私有变量。 165 | 166 | 因为只有闭包函数可以访问外部函数的变量。 167 | 168 | 169 | 170 | 171 | 172 | ### 【Q】请写出一个闭包实例? 173 | 174 | ``` 175 | function moyu(){ 176 | var name = "魔芋"; 177 | return function(){ 178 | console.log(name+" 你好~"); 179 | } 180 | } 181 | var res = moyu(); 182 | res();//"魔芋 你好~" 183 | ``` 184 | 185 | 186 | 187 | ![1527622788167](closure_moyu.assets/1527622788167.png) 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | ### 【Q】闭包的缺点: 196 | 197 | - 闭包函数作用域中,使用的外部函数变量不会被立刻销毁回收,所以会占用更多的内存。过度使用闭包会导致性能下降。建议在非常有必要的时候才使用闭包。 198 | 199 | 200 | 201 | ------ 202 | 203 | ### 魔芋归纳的一些注意点: 204 | 205 | 01,同一个闭包函数,所访问的外部函数的变量是同一个变量。 206 | 207 | 02,如果把闭包函数,赋值给不同的变量,那么不同的变量指向的是不同的闭包函数,所使用的外部函数变量是不同的。 208 | 209 | 03,闭包函数分为定义时,和运行时。只有运行时,才会访问外部函数的变量。 210 | 211 | 04,在for循环的闭包函数,只有在运行时,才在作用域中寻找变量。for循环会先运行完毕,此时,闭包函数并没有运行。 212 | 213 | 例子:如果闭包中使用for的i。那么闭包中的i是for循环中的最后一个值。 214 | 215 | 05,如果在for循环中,使用闭包的自执行函数。那么闭包会使用for循环的变量i(0-*,假设i从0开始)。 216 | 217 | 06,一个函数里,可以有多个闭包。 218 | 219 | 220 | 221 | ### 【Q】闭包和内存泄漏? 222 | 223 | 在IE中,JS对象和DOM对象使用不同的垃圾收集机制。 224 | 225 | 事件绑定中的匿名函数也是闭包函数。 226 | 227 | 如果闭包函数中有HTML元素。那么该元素由于有引用,所以无法被回收。 228 | 229 | ```javascript 230 | function moyu_test(){ 231 | 232 | var _div = document.getElementById("moyu"); 233 | 234 | _div.onclick=function(){ 235 | 236 | console.log(_div.innerHTML); 237 | 238 | } 239 | 240 | } 241 | 242 | moyu_test();//这里_div元素有引用,除非浏览器关闭才会回收。 243 | 244 | 245 | ``` 246 | 247 | 改进方式:主动解除引用。 248 | 249 | 250 | 251 | ```javascript 252 | function moyu_test(){ 253 | 254 | var _div = document.getElementById("moyu"); 255 | 256 | _div.onclick=function(){ 257 | 258 | console.log(_div.innerHTML); 259 | 260 | } 261 | 262 | _div=null;//解除引用 263 | 264 | } 265 | 266 | moyu_test(); 267 | 268 | 269 | ``` 270 | 271 | 272 | 273 | ### 【Q】闭包中的this? 274 | 275 | 对于某个函数来说,如果函数在全局环境中,this指向window。 276 | 277 | 如果在对象中,就指向这个对象。 278 | 279 | 而对象中的闭包函数,this指向window。因为闭包并不属于这个对象的属性或方法。 280 | 281 | 282 | 283 | ```javascript 284 | var user = 'The Window'; 285 | var obj = { 286 | user : 'The Object', 287 | getUserFunction : function () { 288 | return function () { //闭包不属于obj,里面的this 指向window 289 | return this.user; 290 | }; 291 | } 292 | }; 293 | alert(obj.getUserFunction()()); //The window 294 | //可以强制指向某个对象 295 | alert(obj.getUserFunction().call(obj)); //The Object 296 | //也可以从上一个作用域中得到对象 297 | getUserFunction : function () { 298 | var that = this; //从对象的方法里得对象 299 | return function () { 300 | return that.user; 301 | }; 302 | } 303 | ``` 304 | 305 | 306 | 307 | ### 【Q】闭包和arguments? 308 | 309 | arguments是函数的实参对象。闭包有自己的arguments,所以无法直接访问外部函数的arguments。可以将外部函数的arguments保存到一个变量中,然后在闭包中使用。 310 | 311 | 312 | 313 | 314 | 315 | ------ 316 | 317 | ### 【判断题】 318 | 319 | ###### 题1: 320 | 321 | ```javascript 322 | function createFunctions(){ 323 | var result = new Array(); 324 | 325 | for (var i=0; i < 10; i++){ 326 | result[i] = function(num){ 327 | return function(){ 328 | return num; 329 | }; 330 | }(i); 331 | } 332 | 333 | return result; 334 | } 335 | 336 | var res = createFunctions(); 337 | console.log(res[5]()); 338 | ``` 339 | 340 | 341 | 342 | 结果为5; 343 | 344 | 魔芋解析:在for循环中,数组元素赋值调用了闭包函数,此时`num为`for循环中的`i`值。 345 | 346 | 考察点:闭包函数在调用时,从作用域查找变量值。 347 | 348 | 349 | 350 | ###### 题2: 351 | 352 | ```js 353 | var subduction =(function(){ 354 | 355 | var moyu = 0; 356 | return function(){ 357 | return moyu -=1; 358 | } 359 | 360 | 361 | })(); 362 | 363 | subduction(); 364 | subduction(); 365 | subduction(); 366 | 367 | /*moyu等于几?*/ 368 | ``` 369 | 370 | 结果为-3。 371 | 372 | 考察点:同一个闭包变量使用同样的变量。 373 | 374 | 375 | 376 | ###### 题3: 377 | 378 | 379 | 380 | ```js 381 | var num = 1; 382 | var o = { 383 | num: 2, 384 | add: function() { 385 | this.num = 3; 386 | console.log('add', this); 387 | (function() { 388 | console.log('closure', this); 389 | console.log(this.num); 390 | this.num = 4; 391 | })(); 392 | console.log(this.num); 393 | }, 394 | sub: function() { 395 | console.log(this.num); 396 | } 397 | } 398 | o.add(); 399 | console.log(o.num); 400 | console.log(num); 401 | var sub = o.sub; 402 | sub(); 403 | 404 | // 请写出输出结果 405 | 406 | 407 | ``` 408 | 409 | ![1527656311145](closure_moyu.assets/1527656311145.png) 410 | 411 | 412 | 413 | 魔芋的解释: 414 | 415 | 01,o.add(); 416 | 417 | 第一个console.log('add', this);//输出o这个对象。 418 | 419 | 在对象方法中,方法中的this指向这个对象。 420 | 421 | 第一个this.num = 3; 422 | 423 | 表示:o.num =3; 424 | 425 | 02,匿名自执行函数中的this,指向全局环境变量。为window。 426 | 427 | 所以 428 | 429 | (function() { 430 | 431 | ​ console.log('closure', this);//这里的this是指向哪里?window 432 | 433 | ​ console.log(this.num);//1 434 | 435 | ​ this.num = 4;//window.num = 4; 436 | 437 | })(); 438 | 439 | 匿名自执行函数的this.num为window.num。为1。 440 | 441 | this.num = 4;//window.num = 4; 442 | 443 | 03, 444 | 445 | console.log(o.num);//3,因为前面修改了o.num=3; 446 | 447 | 04,console.log(num);//4 448 | 449 | 这里,num为window.num。 450 | 451 | 05,var sub = o.sub; 452 | 453 | sub();//4 454 | 455 | 魔芋:sub为函数。全局函数中的this指向全局环境,也就是window。 456 | 457 | 所以为window.num为4; 458 | 459 | 460 | 461 | 462 | 463 | ###### 题4: 464 | 465 | ```js 466 | for(var i = 1; i < 10; i ++){ 467 | setTimeout(function(){ 468 | console.log(i); 469 | }, 1000); 470 | } 471 | ``` 472 | 473 | 474 | 475 | 结果为1秒后的9个10。 476 | 477 | ![1527656577721](closure_moyu.assets/1527656577721.png) 478 | 479 | 魔芋解析:for循环结束后,`i`值为10,在任务队列中加入9个定时器。1秒后,调用闭包函数,此时闭包函数在作用域中使用`i`值。 480 | 481 | 考察点:闭包函数在调用时,使用变量的当前值。 482 | 483 | 484 | 485 | ###### 题5: 486 | 487 | ```js 488 | // 变体一 489 | for (var i = 1; i < 10; i++) { 490 | (function(i){ 491 | setTimeout(function(){ 492 | console.log(i); 493 | }, i * 1000); 494 | })(i); 495 | } 496 | ``` 497 | 498 | 499 | 500 | 结果,每隔1秒,依次的输出1到9。 501 | 502 | ![1527657051063](closure_moyu.assets/1527657051063.png) 503 | 504 | 魔芋解析:在for循环中,每次调用匿名自执行函数。定时器中的闭包函数使用的是传递进来的for的`i`值(1-9)。 505 | 506 | 考察点:闭包函数在调用时,使用变量的当前值。 507 | 508 | 509 | 510 | ###### 题6: 511 | 512 | ```js 513 | // 变体二 514 | for (var i = 1; i < 10; i++) { 515 | (function(){ 516 | setTimeout(function(){ 517 | console.log(i); 518 | }, i * 1000); 519 | })(); 520 | } 521 | ``` 522 | 523 | 524 | 525 | 结果:每隔1秒输出10。进行9次。 526 | 527 | ![1527657323488](closure_moyu.assets/1527657323488.png) 528 | 529 | 530 | 531 | 魔芋解析:每次for循环中,给任务队列加入定时器,定时器中的闭包函数,在定义时,并没有传递i值。所以闭包函数在调用时,在自己的作用域中使用for循环结束后的i值。 532 | 533 | 534 | 535 | 536 | 537 | ###### 题7: 538 | 539 | ```js 540 | // 变体三 541 | for (var i = 1; i < 10; i++) { 542 | (function(){ 543 | setTimeout(function(i){ 544 | console.log(i); 545 | }, i * 1000); 546 | })(); 547 | } 548 | ``` 549 | 550 | 结果: 551 | 552 | 依次输出9个undefined。 553 | 554 | ![1527657728413](closure_moyu.assets/1527657728413.png) 555 | 556 | 557 | 558 | 魔芋解析:在定时器中的闭包函数,它有形参`i`,但是,并没有传递实参。所以形参i的值为undefined。i*1000 的i还是来自for循环中的i。 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Interview Book 2 | 3 | > Contributors: 4 | [@liyuk](https://github.com/Liyuk) [@onion](https://github.com/dcy0701) [@heaven](https://github.com/NE-SmallTown) [@Tristan](https://github.com/Troland) [@张庆东](https://github.com/q986171791) [@moyu](https://github.com/moyuling) 5 | 6 | > 更好的阅读体验: 7 | 8 | > [**如何运行项目?如何贡献代码?**](https://github.com/Mountain-Buzhou/Interview-Book/issues/14) 9 | 10 | ## Abstract 11 | 网络上的资源其实已经足够多了,所以在进行搜索的时候需要极大的筛选成本。为了减少这种低效的筛选,我将一些零散的知识整理在一起。 12 | 13 | ### Hortation 14 | 希望大家能够带着成为一个优秀的软件工程师的想法,来合理的利用这份资料。 15 | 16 | 这份资料并非单纯的前端工程师的面试题,我更希望它能够在工程师成长的道路上,起到梳理知识结构的作用。可以精通前端,但不要局限在狭义的前端,将知识面扩展到后端,了解更多基础的知识结构,才能够成为更加优秀的工程师。 17 | 18 | 这里面大部分的题目都是非常规的提问法,但涉及知识点都极其基础。后续我们可能会添加一些别的方向的内容,比如node、go之类的,但主要还是跟进前端的新动态。 19 | 20 | 最后提到需要辩证地看待这种资源,它只是知识结构,而非万灵药,更多的知识还需要在工作中去实践、去学习。 21 | 22 | **“非知之难,行之惟难;非行之难,终之斯难。”——魏征** 23 | 24 | ### Guidance 25 | `Entry`这个部分是几个前端知识库的链接,里面的内容比较浅显易懂。先看看整个结构性的题目,找到自己的知识的盲区,再去针对性学习。 26 | 27 | `Collection`来自日常的面试、闲聊和偶尔的突发奇想,主要是觉得比较有趣,所以有做一些记录和分类。我和onion讨论了下,决定把这个模块分为三个大的内容,基础、进阶、框架,以及一些我之前整理的问题(与`Entry`有所部分重复)。 28 | 29 | `Teamwork`这个部分则是关于团队管理、以及个人非技术上的一些发展相关的杂谈。 30 | 31 | `Foundation`这个部分是计算机基础的概念,包括计算机组成原理、操作系统、编译原理、计算机网络、数据结构与算法、数据库系统、软件工程。这个部分就是所谓的补基础,构建完整的计算机体系结构,是向上成长的过程中必不可少的。 32 | 33 | **对于这种资讯类的repo来说,很少有提及基础的重要性,希望能够引起阅读者的重视**。 34 | 35 | **欢迎大家在issue里留下自己的奇思妙想,或者直接pr。** 36 | 37 | --- 38 | 39 | Table of Contents 40 | ================= 41 | 42 | * [Interview-Questions-Answers](#interview-questions-answers) 43 | * [Abstract](#abstract) 44 | * [Hortation](#hortation) 45 | * [Guidance](#guidance) 46 | * [Table of Contents](#table-of-contents) 47 | * [Entry](#entry) 48 | * [Naive](#naive) 49 | * [Interesting](#interesting) 50 | * [Recommend](#recommend) 51 | * [Collection](#collection) 52 | * [Basic](#basic) 53 | * [Advanced](#advanced) 54 | * [Browser](#browser) 55 | * [JavaScript](#javascript) 56 | * [Application](#application) 57 | * [HTML](#html) 58 | * [Function Program](#function-program) 59 | * [HTTP](#http) 60 | * [Optimization](#optimization) 61 | * [Products](#products) 62 | * [Whiteboard](#whiteboard) 63 | * [System Design](#system-design) 64 | * [Framework](#framework) 65 | * [React](#react) 66 | * [Vue](#vue) 67 | * [AngularJS](#angularjs) 68 | * [Wheel](#wheel) 69 | * [Nodejs](#nodejs) 70 | * [Future](#future) 71 | * [Team Management](#team-management) 72 | * [Management](#management) 73 | * [Growing](#growing) 74 | * [Foundation](#foundation) 75 | * [Operating System](#operating-system) 76 | * [Computer Organization](#computer-organization) 77 | * [Network](#network) 78 | * [Algorithm](#algorithm) 79 | * [Compliers](#compliers) 80 | 81 | --- 82 | ## Entry 83 | 84 | 我将**最基础**的前端的知识点分为三个部分: 85 | 86 | - html+css+js(闭包、作用域、异步、继承) 87 | - 网络、性能、测试、编码 88 | - 自动化、工程化的开发 89 | 90 | 这三个划分出来的只是最为基础的内容,学习这部分内容一方面需要对于书面知识的阅读,也需要在项目中加以实践。 91 | 92 | ### Naive 93 | 基础的面试问题题库已经有很多了,个人觉得这个里面的题大概是入门级别的,刚学的时候看看就可以了。 94 | >[中文前端面试大全:qiu-deqing/FE-interview](https://github.com/qiu-deqing/FE-interview) 95 | 96 | 白皮书里关于非技术的问题值得一读。 97 | >[yangshun/tech-interview-handbook](https://github.com/yangshun/tech-interview-handbook) 98 | 99 | 这本书里面梳理的非常全面,可以作为知识体系的梳理来进行学习。 100 | >[front-end-developer-handbook-2018](https://frontendmasters.gitbooks.io/front-end-developer-handbook-2018/) 101 | 102 | ### Interesting 103 | 关于一些Javascript里细节的点,可以看看这位大哥的博客,写的很清晰,代码实现很完整。 104 | >[冴羽的博客](https://github.com/mqyqingfeng/Blog) 105 | 106 | 《前端要给力之系列》是一系列非常有趣的文章,同时讲的非常深入 107 | >[前端要给力之系列](/Entry/Geili.md) 108 | 109 | 如果你喜欢看一些函数式编程、编译原理之类的东西,那么可以看看何幻大神的知乎专栏进行一些~~初步~~深入的学习。 110 | >[业余程序员的个人修养](https://zhuanlan.zhihu.com/self-discipline) 111 | 112 | 113 | ### Recommend 114 | 这本书里面涵盖的知识点非常基础,作者整理了四个月,刷完了十几本书,还有leetcode四百题,梳理了非常多的知识结构。   115 | 116 | 其中包括**计算机网络、操作系统、算法、面向对象、数据库、java、分布式、工具**等等丰富的内容,这也是我在后文里提到的内容。 117 | 118 | 我极力推崇这样的知识梳理的repo,在这个repo中扩展了我在本文最后提到的书本中的知识点。 119 | 如果你希望加强基础的学习,或者在往后端进行技术拓展,这本书可以作为大纲梳理。 120 | 121 | >[面试白皮书](https://github.com/CyC2018/Interview-Notebook)   122 | 123 | 124 | 125 | --- 126 | ## Collection 127 | 128 | 这个模块分为三个部分,即基础`Basic`,进阶`Advanced`,框架`Framework`,这是相当科学的划分。这里的内容主要是我们一起整理,以及日常讨论的一些题目,会有一些重复的内容,也可以独立作为一个基础知识体系。 129 | 130 | ### Basic 131 | 132 | - [html5新标签有哪些](docs/Collection/NewHtmlTag.md) 133 | - canvas、svg、webGL 134 | - [你是如何理解 HTML 语义化的,有什么好处](docs/Collection/semantization.md) 135 | - [前端需要注意哪些SEO?](docs/Collection/SEO.md) 136 | - manifest、worker、socket 137 | - input和textarea的区别 138 | - 用一个div模拟textarea的实现 139 | - css3有什么新特性,浏览器支持怎么样 140 | - 伪类是什么?有哪些?会有哪些兼容性问题?如何处理? 141 | - css预处理器知道吗?用过哪些?有什么优劣?后处理器知道吗? 142 | - 盒模型有哪几种?怪异模式和标准模式? 143 | - less、sass、postcss、prefix 144 | - 层叠优先级 145 | - 圣杯、双飞燕布局 146 | - float清除浮动 147 | - flex布局、 grid布局、table布局 148 | - css以及中轴旋转、动画变换 149 | - 绘制三角形、矩形、菱形、梯形(奇巧淫技,可以不问) 150 | - [sprite图(雪碧图)知道吗?svg雪碧图了解吗?](docs/Collection/sprite.md) 151 | - px、em、rem、vw、vh?rem的根节点样式在什么时候设置? 152 | - position有哪些?他们的定位原点是什么? 153 | - 媒体查询用css好还是用js好? 154 | - [link和@import的区别?](docs/Collection/LinkAndImport.md) 155 | - 响应式布局的原理 156 | - css低版本浏览器兼容问题,额外需要什么后缀来声明浏览器兼容 157 | - !important意义,是否应当规避使用? 158 | - BFC块级上下文、IFC,实现双栏高度对齐 159 | - BEM命名法,有什么优势,有什么劣势 160 | - 1px边框问题 161 | - (水平)居中有哪些实现方式、(垂直)居中有哪些实现方式 162 | - typeof以及弱类型转换规则?NaN、undefined、null 163 | - dom的节点操作?能够背api还是知道api? 164 | - ajax是什么?知道底层实现原理吗?知道fetch吗?自己封装过吗? 165 | - GET、POST意义?restful架构下还有别的什么请求?OPTION请求是什么? 166 | - 事件冒泡和事件捕获是怎样的?对应的默认方法有什么?一般在什么情况使用? 167 | - call、apply、bind 168 | - 如何判断数据类型? 169 | - hoisting是什么?具体表现是怎样的? 170 | - 匿名函数是什么?函数表达式和函数声明的区别? 171 | - let、const暂时性锁区知道吗?表现是怎样的? 172 | - 严格模式是什么?有什么好处?'use strict' 173 | - arguments是什么类型?callee和caller有什么区别? 174 | - Date.format实现过吗?思路是怎样的? 175 | - 动画:setTimeout何时执行,requestAnimationFrame的优点 176 | - 说说YSlow(可以详细一点) 177 | - 你知道new一个对象有几步吗?(参考ES6标准文档) 178 | 179 | 180 | 181 | ### Advanced 182 | 183 | 我们会尽可能地增加`Advanced`(进阶)这里面的题目的数量和难度,当然也包含很多基础知识点的详细内容。这里的知识点的区分暂时并不是特别明显,之后onion来整理这块儿内容。 184 | 185 | #### Browser 186 | 187 | - [打开一个网页经历了那些过程?](http://web.jobbole.com/94150/) 188 | - [浏览器加载白屏是什么原因?](/docs/Collection/WhiteScreen.md) 189 | - [千万访问量的项目,前端需要注意些什么?](/docs/Collection/DozensOfVisits.md) 190 | 191 | #### JavaScript 192 | 这一章我们尽量带来较深层的JavaScript语言层次的问题,我们会拿出几个JavaScript较深入的点来讲。 193 | 194 | - [表达式和语句有什么区别?如何把语句转换为表达式?](docs/Collection/ExpressionAndStatement.md) 195 | - 什么叫执行上下文栈(Execution Context Stack)? 一个函数调用会产生多少个上下文环境?如何激活一个上下文,什么叫caller(调用者),什么叫callee(被调用者)?给你一段代码能否画出执行过程中的上下文堆栈变化? 196 | - 执行上下文包括哪些结构(状态/属性),如何追踪关联代码的执行进度? 197 | - eval在调用的时候有哪些特别的地方?eval函数自身会产生上下文吗?会影响当前的调用上下文吗? 198 | - 什么叫变量对象?什么叫活动对象? 199 | - [词法作用域是什么?闭包是如何形成的?](docs/Collection/closure_moyu.md) 200 | - `var foo = function bar () {}` 命名函数表达式中(上述的foo函数)bar变量是定义在哪一层作用域的? 201 | - [`(0, 1, 2)` 的结果是什么?](docs/Collection/NumberExpression.md) 202 | - `var foo = { value: 2, bar: function () { return this.value; }` 中`(foo.bar, foo.bar)()`的`this`值是什么?`(foo.bar = foo.bar)()`、`(false || foo.bar)()`呢? 203 | 204 | #### Application 205 | 这里将JavaScript除去基本语言特性之外的东西整理出来,主要是JavaScript在工程上的应用场景,以及一些原理性问题。 206 | 207 | - [继承(重点)](/docs/Collection/Inherit.md) 208 | - [异步(重点)](https://blog.risingstack.com/writing-a-javascript-framework-execution-timing-beyond-settimeout/ ) 209 | - [new操作符做了什么](http://blog.csdn.net/aimingoo/article/details/6105048) 210 | - [JavaScript 内存管理](https://github.com/Troland/how-javascript-works/blob/master/memory-management.md) 211 | - [实现一个Promise](https://github.com/Liyuk/code-repertory/blob/master/promise/promise.js) 212 | - [js模块化现状?AMD和CMD是什么?](https://segmentfault.com/a/1190000009591055) 213 | - 如何在前端解析二进制?流媒体、图片二进制数据怎样渲染到页面上? 214 | - [函数记忆是什么?什么场景下使用?(动态规划)](docs/Collection/memorization.md) 215 | - 实现一个Lazyman [Answer 1](http://www.cnblogs.com/walls/p/6341614.html) [Answer 2](http://web.jobbole.com/89626/) 216 | - [实现throttle和debounce (必会)](https://jinlong.github.io/2016/04/24/Debouncing-and-Throttling-Explained-Through-Examples/) 217 | - require.js的实现原理,[webpack的实现原理与loader的实现](http://taobaofed.org/blog/2016/09/09/webpack-flow/) 218 | - [Babel是如何实现的](https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md) 219 | - [如何用正则表达式实现模板引擎?(正则表达式相关知识点)](http://louiszhai.github.io/2016/06/13/regexp/) 220 | 221 | #### HTML 222 | - 讲一下whatwg标准上的event loop规范。(别说你没看过 223 | - microTask的有哪些,Task的有哪些?(最好答出来所有的 224 | - 构思一下利用Task和microTask来完成框架层面的时间调度( 比如vue是如何利用microTask来实现batch update的 225 | - 讲一下你对web components的理解 226 | - web worker适合哪些场景 227 | 228 | #### Function Program 229 | - [闭包(重点)](/docs/Collection/Clojure.md) 230 | - [柯里化(Currying)](/docs/Collection/Currying.md) 231 | 232 | #### HTTP 233 | - http1.0和http1.1的区别 234 | - http请求码有哪些?206、302、303、304、307 235 | - 能说下304具体怎样实现吗? 236 | - http缓存逻辑是怎样的?协商缓存与强缓存?Last-Modified / Etag / Expires / Cache-Control ? 237 | - osi七层协议和tcp/ip四层协议 238 | - 三次握手和四次握手 239 | - 跨域是什么?http协议中如何判断跨域?如何解决跨域问题? 240 | - http2具体内容?SDPY了解么? 241 | - HTTPS如何实现?tsl/ssl是什么?对称加密、非对称加密在什么时候、对什么数据加密? 242 | - DNS劫持是什么? 243 | - [浏览器在一次 HTTP 请求中,需要传输一个 4097 字节的文本数据给服务端,可以采用那些方式?](docs/Collection/SendData.md) 244 | 245 | #### Optimization 246 | - 首屏优化 247 | - 预加载资源、预解析DNS 248 | - 懒加载图片怎么做 249 | - [iframe一般怎么使用?](docs/Collection/iframeUse.md) 250 | - window.onload、document.ready顺序?iframe会阻塞吗? 251 | - cdn是什么?如何查找最近的cdn? 252 | - gzip、chucked 253 | - 前端安全:xss攻击和防范、CSRF、CORS 254 | - 硬件加速怎样开启 255 | - 优化中会提到缓存的问题,问:静态资源或者接口等如何做缓存优化 256 | - 页面DOM节点太多,会出现什么问题?如何优化? 257 | 258 | #### Products 259 | 这里主要是一些生产中真实存在的问题。 260 | 261 | - 一个feed流,有哪些展现方式?如果当前页面可视区有5个格子,而你有20条信息需要展示,请问有哪些自动展示的算法? 262 | - [移动端的缓存机制有哪几种?](https://segmentfault.com/a/1190000004132566) 263 | - 小程序如何与native通信?react-native实现原理?jsbridge如何实现? 264 | - 过万条数据如何加载和渲染? 265 | - 如何在前端解析二进制,流媒体、图片二进制数据怎样渲染到页面上? 266 | - 如何解析二进制音频、视频? 267 | - 文件如何显示上传百分比? 268 | - 如何制作一个富文本,需要考虑哪些结构? 269 | - html5的播放器怎么做?视频直播如何在浏览器里面实现?HLS、RTMP 270 | - 如何在浏览器里面裁剪图片?如何裁剪视频,对视频做逐帧分析? 271 | - 如何实现一个具有引导功能的组件库? 272 | - 如何封装一个Form和FormItem,使其能够跟input、select、checkbox、radio等组件进行 数据存储、数据校验(自定义逻辑)、校验反馈? 273 | - echart这类图像库的实现原理? 274 | - i18n的国际化方案应该是怎样的? 275 | - 数据埋点的意义是什么?应当针对哪些数据进行埋点?如何构建一个埋点系统? 276 | - 小程序的实现原理是什么?[这【五篇】文章将带你深入了解「微信小程序」](https://github.com/phodal/articles/issues/32) 277 | - 小游戏的实现原理是什么?[Cocos知乎文章:微信小游戏上手](https://www.zhihu.com/org/cocos-3/posts)、[深入理解使用白鹭引擎开发微信小游戏的构建机制](https://zhuanlan.zhihu.com/p/32749103) 278 | - mpvue这样h5转小程序的工具的原理是什么?怎样去实现?[官方宣传文档](https://zhuanlan.zhihu.com/p/34450979)、[如何看待美团开源mpvue](https://www.zhihu.com/question/268421668) 279 | 280 | #### Whiteboard 281 | 前端所需要的白板面试题算法难度不高,主要针对JavaScript基础类型的遍历与扩展。 282 | 但是如果有喜欢考算法题的,可能会考的很难。所以还是推荐如果有时间的话,可以去把leetcode的easy和medium刷一下,hard可以跳过不看。 283 | 国内的面试难度其实很小,有兴趣的朋友看看国外的面试题就知道自己有多么菜了。 284 | 285 | - parseQuery 286 | - flatten 287 | - [乱序算法(Fisher–Yates)](https://github.com/Mountain-Buzhou/Interview-Book/issues/1) 288 | - [模版引擎](/docs/Collection/Template.md) 289 | - 反转二叉树 290 | - 将两个有序数组合并成为一个有序数组 291 | - 全选和单行选中的联动 292 | - 数组去重,考虑object、NaN、数字1,弱类型转换 293 | - 汉诺塔的实现 294 | - bind 295 | - currying 296 | - 一个无重复元素的数组,求所有两数之和为k的组合 297 | - 变体题:一个无重复元素的数组,求元素和(元素个数小于n)为k的组合 298 | - [实现events(发布订阅/观察者模式)](/docs/Collection/Events.md) 299 | - 找出数组中最大的两数之差 300 | - 棋盘最短路:动态规划、搜索+剪枝、时间优化、空间优化 301 | - [二叉树遍历:前序、后序、中序,时间复杂度,空间复杂度O(1),递归非递归](https://github.com/MrTreasure/Algorithm/blob/master/src/Tree/BinaryTree.ts) 302 | - 双向链表寻找中间的元素,单向链表寻找中间的元素 303 | - 查找数组中第k大的数 304 | 305 | 306 | 307 | #### System Design 308 | 这类题目非常繁琐以及复杂,主要出现在高级工程师的最终面试里。对于不同层级的开发人员的回答要求各不相同,但有必要全局地了解整个系统的设计结构和基本概念。 309 | 310 | - 请设计一个前端的组件库,包括组件的分类、具体的内容、API的规范、协作开发的规范。 311 | - [System Design Primer 中文](https://github.com/donnemartin/system-design-primer/blob/master/README-zh-Hans.md) 312 | - [System Design Interview](https://github.com/checkcheckzz/system-design-interview) 313 | 314 | - [面试常问问题及问答思路](docs/Collection/OftenAsked.md) 315 | 316 | 317 | ### Framework 318 | 319 | #### React 320 | - React的生命周期mount和update描述下 321 | - [React的生命周期中的isBatchingUpdates了解吗?Transaction知道吗](https://zhuanlan.zhihu.com/p/20328570) 322 | - React的vdom如何实现?jsx是怎样解析的? 323 | - React的Fiber是什么?具有什么样的特性? 324 | - React的diff/patch算法原理 325 | - React的组件逻辑(受控、非受控)?如何设计一个组件库 326 | - React的数据流,Redux、Mobx、Rxjs,发布订阅模式、观察者模式,flux和no-flux 327 | - React的事件注册和事件分发知道吗? 328 | - Redux解决了什么痛点(有什么优点),又有什么缺点 329 | - Redux的中间件有哪些?redux-actions、redux-promise、redux-thunk、redux-saga、redux-immutable了解过哪些?说说中间件的意义 330 | - Redux有什么优化方案? 331 | - SSR了解过吗?怎样做?了解Koa么? 332 | - React-Native了解过吗?JavascriptCore是什么? 333 | 334 | #### Vue 335 | - [Vue是如何设计响应式系统的?(依赖收集)](https://zhuanlan.zhihu.com/p/29318017) 336 | - 什么时候使用computed, methods, watch?之间有什么样区别? 337 | - template 和 render(jsx) 有什么的联系? 338 | - this.$nextTick是如何设计的? 339 | - Vue 组件 data 为什么必须是函数? 340 | 341 | #### AngularJS 342 | 尽管angularJS已经基本退出了历史舞台,但是相信有的同学还是做过相关的项目,并很有可能被面试官问起。 343 | 344 | - angularJS的数据绑定采用什么机制?详述原理 345 | - 如果通过angularJS的 directive/component 规划一套全组件化体系,可能遇到哪些挑战? 346 | - 一个angularJS应用应当如何良好地分层? 347 | - ng-click中写的表达式,能使用JS原生对象上的方法,比如Math.max之类的吗?为什么? 348 | 349 | #### Wheel 350 | 一系列教你如何徒手造轮子的文,翻译质量很不错。来自`@Tristan` 351 | 352 | - [项目结构](https://github.com/Troland/writing-a-javascript-framework/wiki/1.%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84) 353 | - [执行时间](https://github.com/Troland/writing-a-javascript-framework/wiki/2.%E6%89%A7%E8%A1%8C%E6%97%B6%E9%97%B4) 354 | - [代码运行沙箱](https://github.com/Troland/writing-a-javascript-framework/wiki/3.%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E6%B2%99%E7%AE%B1) 355 | - [数据绑定简介](https://github.com/Troland/writing-a-javascript-framework/wiki/4.%E6%95%B0%E6%8D%AE%E7%BB%91%E5%AE%9A%E7%AE%80%E4%BB%8B) 356 | - [基于-ES6-代理的数据绑定](https://github.com/Troland/writing-a-javascript-framework/wiki/5.%E5%9F%BA%E4%BA%8E-ES6-%E4%BB%A3%E7%90%86%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%91%E5%AE%9A) 357 | - [自定义元素](https://github.com/Troland/writing-a-javascript-framework/wiki/6.%E8%87%AA%E5%AE%9A%E4%B9%89%E5%85%83%E7%B4%A0) 358 | - [客户端路由](https://github.com/Troland/writing-a-javascript-framework/wiki/7.%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%B7%AF%E7%94%B1) 359 | 360 | #### Nodejs 361 | 362 | - [node各种模块](https://github.com/parro-it/awesome-micro-npm-packages) 363 | - [如何~~通过饿了么 Node.js 面试~~进入阿里](https://elemefe.github.io/node-interview/#/sections/zh-cn/) 364 | 365 | #### Future 366 | 一些关于未来的GUI编程以及可能存在的变化 367 | 368 | - web-assembly 369 | - pwa的优劣 370 | - new ui:VR、AR、speech 371 | - learning to learn 372 | - web operating system (web 3.0) 373 | - new html spec. 374 | 375 | --- 376 | 377 | ## Team Management 378 | 这部分内容更多是非技术方向上的一些杂谈,看看就好。 379 | 380 | ### Management 381 | - [给你一个二十人的新团队,你作为前端负责人你怎样去做?](docs/team/Team.md) 382 | ### Growing 383 | - [工程师的阶段是怎样的?不同阶段应该具备怎样的技能?](docs/team/Stages.md) 384 | 385 | --- 386 | ## Foundation 387 | 我非常希望看到这里的同学能够认认真真去系统性的学习整个计算机体系结构。因此我将各个模块中偏向应用的东西都梳理了出来。这些梳理出来的点比较偏工程,稍做迁移就可以应用在我们工作当中。学习的时候可以暂时根据这些梳理出来的关键字去过一下知识点。 388 | 389 | 我省略了《软件工程》与《数据库系统》的内容,因为前者方法论适合实践总结,后者我还不太熟悉。我推荐一本《计算机程序的构造和解释(SICP)》,是MIT本科的第一门课,讲述如何构造和分析复杂系统(程序)。这些书我自己也定期的回顾,之前与大佬讨论,不论科班还是非科班出身,不断回顾并思考计算机基础的东西,是非常重要的。 390 | 391 | ![基础书籍](docs/assets/imgs/books.jpeg) 392 | 393 | ### Operating System 394 | - 进程与线程 395 | - 虚拟地址,物理地址 396 | - 进程间通信:临界区、忙等待互斥、睡眠与唤醒、信号量、互斥量、管程、消息传递、屏障、避免锁 397 | - 进程调度策略:批处理、交互式、实时; 398 | - 批处理调度:FCFS、SJF、SRTF 399 | - 交互式调度:轮转、优先级、多级队列、最短进程优先、保证调度、彩票调度、公平分享调度 400 | - 实时调度:硬实时、软实时、周期性 401 | - [IPC问题:读者-写者、生产者-消费者、哲学家进餐、银行家算法](https://www.zybuluo.com/zhengbuqian/note/243560) 402 | - 页面置换算法:最优页面置换算法、最近未使用页面置换算法(NRU)、先进先出页面置换算法(FIFO)、第二次机会页面置换算法、时钟页面置换算法(clock)、最近最少使用页面置换算法(LRU)、软件模拟LRU、工作集页面置换算法、工作集时钟页面置换算法 403 | 404 | ### Computer Organization 405 | - 缺页中断——FIFO、LRU、OPT三种置换算法 406 | - 流水线、指令集 407 | 408 | ### Network 409 | - [帧、报文、报文段、分组、包、数据报的概念](http://www.cnblogs.com/sddai/p/5649939.html) 410 | - DNS原理 411 | - UDP和TCP 412 | - 可靠性数据传输原理、拥塞控制原理 413 | - 路由选择:RIP、OSPF、BGP 414 | - 差错检验和纠正技术 415 | - 计算机网络安全 416 | 417 | ### Algorithm 418 | - 递归与非递归 419 | - 排序算法(8种) 420 | - 栈、队列、散列表、二叉树、红黑树 421 | - 动态规划、贪心、平摊分析 422 | - B树、二项堆、斐波那契堆、不相交集合 423 | - 最小生成树Kruskal和Prim,最短路Dijstra和Bellman-Ford 424 | - 最短路Floyd-Warshall和Johnson,最大流Ford-Fulkerson 425 | - 排序网络、矩阵运算、线性规划、多项式与快速傅立叶变换 426 | - 有限数论,字符串匹配Rabin-Karp和KMP 427 | - 计算几何学、NP完全性、近似算法 428 | 429 | ### Compliers 430 | - 词法分析、自动机、DFA 431 | - 语法分析、语法制导 432 | - 中间代码、AST树、类型检查 433 | - 堆、栈管理,垃圾回收机制 434 | - 目标代码生成、代码优化 435 | - 指令集并行性 436 | - 并行性与局部性优化 437 | - 过程间分析 -------------------------------------------------------------------------------- /docs/assets/css/github-markdown.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: octicons-link; 3 | src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff'); 4 | } 5 | 6 | .markdown-body { 7 | -ms-text-size-adjust: 100%; 8 | -webkit-text-size-adjust: 100%; 9 | line-height: 1.5; 10 | color: #24292e; 11 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 12 | font-size: 16px; 13 | line-height: 1.5; 14 | word-wrap: break-word; 15 | } 16 | 17 | .markdown-body .pl-c { 18 | color: #6a737d; 19 | } 20 | 21 | .markdown-body .pl-c1, 22 | .markdown-body .pl-s .pl-v { 23 | color: #005cc5; 24 | } 25 | 26 | .markdown-body .pl-e, 27 | .markdown-body .pl-en { 28 | color: #6f42c1; 29 | } 30 | 31 | .markdown-body .pl-smi, 32 | .markdown-body .pl-s .pl-s1 { 33 | color: #24292e; 34 | } 35 | 36 | .markdown-body .pl-ent { 37 | color: #22863a; 38 | } 39 | 40 | .markdown-body .pl-k { 41 | color: #d73a49; 42 | } 43 | 44 | .markdown-body .pl-s, 45 | .markdown-body .pl-pds, 46 | .markdown-body .pl-s .pl-pse .pl-s1, 47 | .markdown-body .pl-sr, 48 | .markdown-body .pl-sr .pl-cce, 49 | .markdown-body .pl-sr .pl-sre, 50 | .markdown-body .pl-sr .pl-sra { 51 | color: #032f62; 52 | } 53 | 54 | .markdown-body .pl-v, 55 | .markdown-body .pl-smw { 56 | color: #e36209; 57 | } 58 | 59 | .markdown-body .pl-bu { 60 | color: #b31d28; 61 | } 62 | 63 | .markdown-body .pl-ii { 64 | color: #fafbfc; 65 | background-color: #b31d28; 66 | } 67 | 68 | .markdown-body .pl-c2 { 69 | color: #fafbfc; 70 | background-color: #d73a49; 71 | } 72 | 73 | .markdown-body .pl-c2::before { 74 | content: "^M"; 75 | } 76 | 77 | .markdown-body .pl-sr .pl-cce { 78 | font-weight: bold; 79 | color: #22863a; 80 | } 81 | 82 | .markdown-body .pl-ml { 83 | color: #735c0f; 84 | } 85 | 86 | .markdown-body .pl-mh, 87 | .markdown-body .pl-mh .pl-en, 88 | .markdown-body .pl-ms { 89 | font-weight: bold; 90 | color: #005cc5; 91 | } 92 | 93 | .markdown-body .pl-mi { 94 | font-style: italic; 95 | color: #24292e; 96 | } 97 | 98 | .markdown-body .pl-mb { 99 | font-weight: bold; 100 | color: #24292e; 101 | } 102 | 103 | .markdown-body .pl-md { 104 | color: #b31d28; 105 | background-color: #ffeef0; 106 | } 107 | 108 | .markdown-body .pl-mi1 { 109 | color: #22863a; 110 | background-color: #f0fff4; 111 | } 112 | 113 | .markdown-body .pl-mc { 114 | color: #e36209; 115 | background-color: #ffebda; 116 | } 117 | 118 | .markdown-body .pl-mi2 { 119 | color: #f6f8fa; 120 | background-color: #005cc5; 121 | } 122 | 123 | .markdown-body .pl-mdr { 124 | font-weight: bold; 125 | color: #6f42c1; 126 | } 127 | 128 | .markdown-body .pl-ba { 129 | color: #586069; 130 | } 131 | 132 | .markdown-body .pl-sg { 133 | color: #959da5; 134 | } 135 | 136 | .markdown-body .pl-corl { 137 | text-decoration: underline; 138 | color: #032f62; 139 | } 140 | 141 | .markdown-body .octicon { 142 | display: inline-block; 143 | vertical-align: text-top; 144 | fill: currentColor; 145 | } 146 | 147 | .markdown-body a { 148 | background-color: transparent; 149 | } 150 | 151 | .markdown-body a:active, 152 | .markdown-body a:hover { 153 | outline-width: 0; 154 | } 155 | 156 | .markdown-body strong { 157 | font-weight: inherit; 158 | } 159 | 160 | .markdown-body strong { 161 | font-weight: bolder; 162 | } 163 | 164 | .markdown-body h1 { 165 | font-size: 2em; 166 | margin: 0.67em 0; 167 | } 168 | 169 | .markdown-body img { 170 | border-style: none; 171 | } 172 | 173 | .markdown-body code, 174 | .markdown-body kbd, 175 | .markdown-body pre { 176 | font-family: monospace, monospace; 177 | font-size: 1em; 178 | } 179 | 180 | .markdown-body hr { 181 | box-sizing: content-box; 182 | height: 0; 183 | overflow: visible; 184 | } 185 | 186 | .markdown-body input { 187 | font: inherit; 188 | margin: 0; 189 | } 190 | 191 | .markdown-body input { 192 | overflow: visible; 193 | } 194 | 195 | .markdown-body [type="checkbox"] { 196 | box-sizing: border-box; 197 | padding: 0; 198 | } 199 | 200 | .markdown-body * { 201 | box-sizing: border-box; 202 | } 203 | 204 | .markdown-body input { 205 | font-family: inherit; 206 | font-size: inherit; 207 | line-height: inherit; 208 | } 209 | 210 | .markdown-body a { 211 | color: #0366d6; 212 | text-decoration: none; 213 | } 214 | 215 | .markdown-body a:hover { 216 | text-decoration: underline; 217 | } 218 | 219 | .markdown-body strong { 220 | font-weight: 600; 221 | } 222 | 223 | .markdown-body hr { 224 | height: 0; 225 | margin: 15px 0; 226 | overflow: hidden; 227 | background: transparent; 228 | border: 0; 229 | border-bottom: 1px solid #dfe2e5; 230 | } 231 | 232 | .markdown-body hr::before { 233 | display: table; 234 | content: ""; 235 | } 236 | 237 | .markdown-body hr::after { 238 | display: table; 239 | clear: both; 240 | content: ""; 241 | } 242 | 243 | .markdown-body table { 244 | border-spacing: 0; 245 | border-collapse: collapse; 246 | } 247 | 248 | .markdown-body td, 249 | .markdown-body th { 250 | padding: 0; 251 | } 252 | 253 | .markdown-body h1, 254 | .markdown-body h2, 255 | .markdown-body h3, 256 | .markdown-body h4, 257 | .markdown-body h5, 258 | .markdown-body h6 { 259 | margin-top: 0; 260 | margin-bottom: 0; 261 | } 262 | 263 | .markdown-body h1 { 264 | font-size: 32px; 265 | font-weight: 600; 266 | } 267 | 268 | .markdown-body h2 { 269 | font-size: 24px; 270 | font-weight: 600; 271 | } 272 | 273 | .markdown-body h3 { 274 | font-size: 20px; 275 | font-weight: 600; 276 | } 277 | 278 | .markdown-body h4 { 279 | font-size: 16px; 280 | font-weight: 600; 281 | } 282 | 283 | .markdown-body h5 { 284 | font-size: 14px; 285 | font-weight: 600; 286 | } 287 | 288 | .markdown-body h6 { 289 | font-size: 12px; 290 | font-weight: 600; 291 | } 292 | 293 | .markdown-body p { 294 | margin-top: 0; 295 | margin-bottom: 10px; 296 | } 297 | 298 | .markdown-body blockquote { 299 | margin: 0; 300 | } 301 | 302 | .markdown-body ul, 303 | .markdown-body ol { 304 | padding-left: 0; 305 | margin-top: 0; 306 | margin-bottom: 0; 307 | } 308 | 309 | .markdown-body ol ol, 310 | .markdown-body ul ol { 311 | list-style-type: lower-roman; 312 | } 313 | 314 | .markdown-body ul ul ol, 315 | .markdown-body ul ol ol, 316 | .markdown-body ol ul ol, 317 | .markdown-body ol ol ol { 318 | list-style-type: lower-alpha; 319 | } 320 | 321 | .markdown-body dd { 322 | margin-left: 0; 323 | } 324 | 325 | .markdown-body code { 326 | font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 327 | font-size: 12px; 328 | } 329 | 330 | .markdown-body pre { 331 | margin-top: 0; 332 | margin-bottom: 0; 333 | font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 334 | font-size: 12px; 335 | } 336 | 337 | .markdown-body .octicon { 338 | vertical-align: text-bottom; 339 | } 340 | 341 | .markdown-body .pl-0 { 342 | padding-left: 0 !important; 343 | } 344 | 345 | .markdown-body .pl-1 { 346 | padding-left: 4px !important; 347 | } 348 | 349 | .markdown-body .pl-2 { 350 | padding-left: 8px !important; 351 | } 352 | 353 | .markdown-body .pl-3 { 354 | padding-left: 16px !important; 355 | } 356 | 357 | .markdown-body .pl-4 { 358 | padding-left: 24px !important; 359 | } 360 | 361 | .markdown-body .pl-5 { 362 | padding-left: 32px !important; 363 | } 364 | 365 | .markdown-body .pl-6 { 366 | padding-left: 40px !important; 367 | } 368 | 369 | .markdown-body::before { 370 | display: table; 371 | content: ""; 372 | } 373 | 374 | .markdown-body::after { 375 | display: table; 376 | clear: both; 377 | content: ""; 378 | } 379 | 380 | .markdown-body>*:first-child { 381 | margin-top: 0 !important; 382 | } 383 | 384 | .markdown-body>*:last-child { 385 | margin-bottom: 0 !important; 386 | } 387 | 388 | .markdown-body a:not([href]) { 389 | color: inherit; 390 | text-decoration: none; 391 | } 392 | 393 | .markdown-body .anchor { 394 | float: left; 395 | padding-right: 4px; 396 | margin-left: -20px; 397 | line-height: 1; 398 | } 399 | 400 | .markdown-body .anchor:focus { 401 | outline: none; 402 | } 403 | 404 | .markdown-body p, 405 | .markdown-body blockquote, 406 | .markdown-body ul, 407 | .markdown-body ol, 408 | .markdown-body dl, 409 | .markdown-body table, 410 | .markdown-body pre { 411 | margin-top: 0; 412 | margin-bottom: 16px; 413 | } 414 | 415 | .markdown-body hr { 416 | height: 0.25em; 417 | padding: 0; 418 | margin: 24px 0; 419 | background-color: #e1e4e8; 420 | border: 0; 421 | } 422 | 423 | .markdown-body blockquote { 424 | padding: 0 1em; 425 | color: #6a737d; 426 | border-left: 0.25em solid #dfe2e5; 427 | } 428 | 429 | .markdown-body blockquote>:first-child { 430 | margin-top: 0; 431 | } 432 | 433 | .markdown-body blockquote>:last-child { 434 | margin-bottom: 0; 435 | } 436 | 437 | .markdown-body kbd { 438 | display: inline-block; 439 | padding: 3px 5px; 440 | font-size: 11px; 441 | line-height: 10px; 442 | color: #444d56; 443 | vertical-align: middle; 444 | background-color: #fafbfc; 445 | border: solid 1px #c6cbd1; 446 | border-bottom-color: #959da5; 447 | border-radius: 3px; 448 | box-shadow: inset 0 -1px 0 #959da5; 449 | } 450 | 451 | .markdown-body h1, 452 | .markdown-body h2, 453 | .markdown-body h3, 454 | .markdown-body h4, 455 | .markdown-body h5, 456 | .markdown-body h6 { 457 | margin-top: 24px; 458 | margin-bottom: 16px; 459 | font-weight: 600; 460 | line-height: 1.25; 461 | } 462 | 463 | .markdown-body h1 .octicon-link, 464 | .markdown-body h2 .octicon-link, 465 | .markdown-body h3 .octicon-link, 466 | .markdown-body h4 .octicon-link, 467 | .markdown-body h5 .octicon-link, 468 | .markdown-body h6 .octicon-link { 469 | color: #1b1f23; 470 | vertical-align: middle; 471 | visibility: hidden; 472 | } 473 | 474 | .markdown-body h1:hover .anchor, 475 | .markdown-body h2:hover .anchor, 476 | .markdown-body h3:hover .anchor, 477 | .markdown-body h4:hover .anchor, 478 | .markdown-body h5:hover .anchor, 479 | .markdown-body h6:hover .anchor { 480 | text-decoration: none; 481 | } 482 | 483 | .markdown-body h1:hover .anchor .octicon-link, 484 | .markdown-body h2:hover .anchor .octicon-link, 485 | .markdown-body h3:hover .anchor .octicon-link, 486 | .markdown-body h4:hover .anchor .octicon-link, 487 | .markdown-body h5:hover .anchor .octicon-link, 488 | .markdown-body h6:hover .anchor .octicon-link { 489 | visibility: visible; 490 | } 491 | 492 | .markdown-body h1 { 493 | padding-bottom: 0.3em; 494 | font-size: 2em; 495 | border-bottom: 1px solid #eaecef; 496 | } 497 | 498 | .markdown-body h2 { 499 | padding-bottom: 0.3em; 500 | font-size: 1.5em; 501 | border-bottom: 1px solid #eaecef; 502 | } 503 | 504 | .markdown-body h3 { 505 | font-size: 1.25em; 506 | } 507 | 508 | .markdown-body h4 { 509 | font-size: 1em; 510 | } 511 | 512 | .markdown-body h5 { 513 | font-size: 0.875em; 514 | } 515 | 516 | .markdown-body h6 { 517 | font-size: 0.85em; 518 | color: #6a737d; 519 | } 520 | 521 | .markdown-body ul, 522 | .markdown-body ol { 523 | padding-left: 2em; 524 | } 525 | 526 | .markdown-body ul ul, 527 | .markdown-body ul ol, 528 | .markdown-body ol ol, 529 | .markdown-body ol ul { 530 | margin-top: 0; 531 | margin-bottom: 0; 532 | } 533 | 534 | .markdown-body li { 535 | word-wrap: break-all; 536 | } 537 | 538 | .markdown-body li>p { 539 | margin-top: 16px; 540 | } 541 | 542 | .markdown-body li+li { 543 | margin-top: 0.25em; 544 | } 545 | 546 | .markdown-body dl { 547 | padding: 0; 548 | } 549 | 550 | .markdown-body dl dt { 551 | padding: 0; 552 | margin-top: 16px; 553 | font-size: 1em; 554 | font-style: italic; 555 | font-weight: 600; 556 | } 557 | 558 | .markdown-body dl dd { 559 | padding: 0 16px; 560 | margin-bottom: 16px; 561 | } 562 | 563 | .markdown-body table { 564 | display: block; 565 | width: 100%; 566 | overflow: auto; 567 | } 568 | 569 | .markdown-body table th { 570 | font-weight: 600; 571 | } 572 | 573 | .markdown-body table th, 574 | .markdown-body table td { 575 | padding: 6px 13px; 576 | border: 1px solid #dfe2e5; 577 | } 578 | 579 | .markdown-body table tr { 580 | background-color: #fff; 581 | border-top: 1px solid #c6cbd1; 582 | } 583 | 584 | .markdown-body table tr:nth-child(2n) { 585 | background-color: #f6f8fa; 586 | } 587 | 588 | .markdown-body img { 589 | max-width: 100%; 590 | box-sizing: content-box; 591 | background-color: #fff; 592 | } 593 | 594 | .markdown-body img[align=right] { 595 | padding-left: 20px; 596 | } 597 | 598 | .markdown-body img[align=left] { 599 | padding-right: 20px; 600 | } 601 | 602 | .markdown-body code { 603 | padding: 0.2em 0.4em; 604 | margin: 0; 605 | font-size: 85%; 606 | background-color: rgba(27,31,35,0.05); 607 | border-radius: 3px; 608 | } 609 | 610 | .markdown-body pre { 611 | word-wrap: normal; 612 | } 613 | 614 | .markdown-body pre>code { 615 | padding: 0; 616 | margin: 0; 617 | font-size: 100%; 618 | word-break: normal; 619 | white-space: pre; 620 | background: transparent; 621 | border: 0; 622 | } 623 | 624 | .markdown-body .highlight { 625 | margin-bottom: 16px; 626 | } 627 | 628 | .markdown-body .highlight pre { 629 | margin-bottom: 0; 630 | word-break: normal; 631 | } 632 | 633 | .markdown-body .highlight pre, 634 | .markdown-body pre { 635 | padding: 16px; 636 | overflow: auto; 637 | font-size: 85%; 638 | line-height: 1.45; 639 | background-color: #f6f8fa; 640 | border-radius: 3px; 641 | } 642 | 643 | .markdown-body pre code { 644 | display: inline; 645 | max-width: auto; 646 | padding: 0; 647 | margin: 0; 648 | overflow: visible; 649 | line-height: inherit; 650 | word-wrap: normal; 651 | background-color: transparent; 652 | border: 0; 653 | } 654 | 655 | .markdown-body .full-commit .btn-outline:not(:disabled):hover { 656 | color: #005cc5; 657 | border-color: #005cc5; 658 | } 659 | 660 | .markdown-body kbd { 661 | display: inline-block; 662 | padding: 3px 5px; 663 | font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 664 | line-height: 10px; 665 | color: #444d56; 666 | vertical-align: middle; 667 | background-color: #fafbfc; 668 | border: solid 1px #d1d5da; 669 | border-bottom-color: #c6cbd1; 670 | border-radius: 3px; 671 | box-shadow: inset 0 -1px 0 #c6cbd1; 672 | } 673 | 674 | .markdown-body :checked+.radio-label { 675 | position: relative; 676 | z-index: 1; 677 | border-color: #0366d6; 678 | } 679 | 680 | .markdown-body .task-list-item { 681 | list-style-type: none; 682 | } 683 | 684 | .markdown-body .task-list-item+.task-list-item { 685 | margin-top: 3px; 686 | } 687 | 688 | .markdown-body .task-list-item input { 689 | margin: 0 0.2em 0.25em -1.6em; 690 | vertical-align: middle; 691 | } 692 | 693 | .markdown-body hr { 694 | border-bottom-color: #eee; 695 | } 696 | --------------------------------------------------------------------------------