> 2021年11月28日信息消化 ### 怎样判断面试者是否有扎实的前端基础 origin: [怎样判断面试者是否有扎实的前端基础?](https://juejin.cn/post/7033615049721806879#heading-0) #### JD > **业务背景** 淘宝内部最大创新项目之一,大团队已有百人规模,大部分项目处于保密阶段,前景远大 > > **职位描述** 1.负责组件库与业务页面开发。 2.带领团队完成技术产品实现。 3.负责大型多应用架构设计。 4.利用前端技术与服务端协同完成团队业务目标。 > > **职位要求** 0.掌握图形学,webgl或熟练使用threejs框架,熟练canvas相关渲染及动画操作的优先。 1.熟练掌握JavaScript。 2.熟悉常用工程化工具,掌握模块化思想和技术实现方案。 3.熟练掌握React前端框架,了解技术底层。同时了解vue以及angular等其他框架者优先。 4.熟练掌握react生态常用工具,redux/react-router等。 5.熟悉各种Web前端技术,包括HTML/XML/CSS等,有基于Ajax的前端应用开发经验。 6.有良好的编码习惯,对前端技术有持续的热情,个性乐观开朗,逻辑性强,善于和各种背景的人合作。 7.具有TS/移动设备上前端开发/NodeJS/服务端开发等经验者优先。 什么叫读懂职位描述呢?从我个人的理解,读懂职位描述,应该是读懂这个职位**需要哪些基础能力**,以及**可能遇到哪些挑战**。我们写自己简历的时候,“精通react”和“熟练使用react”,相信大家不会随意去写。同样的,JD里面的:掌握、熟练掌握、了解、熟悉,也不是随意写的,这代表了团队对新同学的能力要求。 ```p 掌握图形学,webgl或熟练使用threejs框架,熟练canvas相关渲染及动画操作的优先。 ``` 初级: - 学习过**图形学**相关知识,知道矩阵等数学原理在动画中的作用,知道三维场景需要的最基础的构成,能用threejs**搭3d场景**,知道webgl和threejs的关系。 - 知道canvas是干嘛的,聊到旋转能说出**canvas的api**。 - 知道css动画,css动画属性知道**关键字**和**用法**(换句话说,电话面试会当场出题要求口喷css动画,至少能说对大概,而不是回答百度一下就会用)。 - 知道js动画,能说出1~2个社区js动画库,知道js动画和css动画优缺点以及适用场景。 - 知道raf和其他达到60fps的方法。 中级: - 如果没有threejs,你也能基于webgl**自己封装**一个简单的threejs出来。 - 聊到原理能说出四元数,聊到鼠标操作能提到节流,聊到性能能提到restore,聊到帧说出raf和timeout的区别,以及各自在优化时候的作用。 - 知道怎样在移动端处理加载问题,渲染性能问题。 - 知道如何结合native能力优化性能。 - 知道如何排查性能问题。对chrome动画、3d、传感器调试十分了解。 高级: - 搭建过整套**资源加载优化方案**,能说明白整体方案的各个细节,包括前端、客户端、服务端分别需要实现哪些功能点、依赖哪些基础能力,以及如何配合。 - 设计并实现过前端**动画引擎**,能说明白一个复杂互动项目的**技术架构**,知道需要哪些核心模块,以及这些模块间如何配合。 - 有自己实现的动画相关技术方案产出,这套技术方案必须是解决明确的业务或技术难点问题的。为了业务快速落地而封装一个库,不算这里的技术方案。如果有类似社区方案,必须能从原理上说明白和竞品的差异,各自优劣,以及技术选型的原因。 ```p 熟练掌握JavaScript。 ``` 初级: - JavaScript**各种概念**都得了解,《JavaScript语言精粹》这本书的目录都得有概念,并且这些核心点都能脱口而出是什么。这里列举一些做参考: - 知道组合寄生继承,知道class继承。 - 知道怎么创建类function + class。 - 知道闭包在实际场景中怎么用,常见的坑。 - 知道模块是什么,怎么用。 - 知道event loop是什么,能举例说明event loop怎么影响平时的编码。 - 掌握基础数据结构,比如堆、栈、树,并了解这些数据结构计算机基础中的作用。 - 知道ES6数组相关方法,比如forEach,map,reduce。 中级: - 知道class继承与组合寄生继承的差别,并能举例说明。 - 知道event loop原理,知道宏微任务,并且能从个人理解层面说出为什么要区分。知道node和浏览器在实现loop时候的差别。 - 能将继承、作用域、闭包、模块这些概念融汇贯通,并且结合实际例子说明这几个概念怎样结合在一起。 - 能脱口而出2种以上**设计模式**的核心思想,并结合js语言特性举例或口喷基础实现。 - 掌握一些**基础算法核心思想**或简单算法问题,比如排序,大数相加。 ```p 熟悉常用工程化工具,掌握模块化思想和技术实现方案。 ``` 初级: - 知道webpack,rollup以及他们适用的场景。 - 知道webpack v4和v3的区别。 - 脱口而出webpack基础配置。 - 知道webpack打包结果的**代码结构**和**执行流程**,知道index.js,runtime.js是干嘛的。 - 知道amd,cmd,commonjs,es module分别是什么。 - 知道所有模块化标准定义一个模块怎么写。给出2个文件,能口喷一段代码完成模块打包和执行的核心逻辑。 中级: - 知道webpack**打包链路**,知道plugin**生命周期**,知道怎么写一个plugin和loader。 - 知道常见loader做了什么事情,能几句话说明白,比如babel-loader,vue-loader。 - 能结合**性能优化**聊webpack配置怎么做,能清楚说明白核心要点有哪些,并说明解决什么问题,需要哪些外部依赖,比如cdn,接入层等。 - 了解异步模块加载的实现原理,能口喷代码实现核心逻辑。 高级: - 能设计出或具体说明白团队研发**基础设施**。具体包括但不限于: - **项目脚手架搭建**,及如何以工具形态共享。 - 团队eslint规范如何设计,及如何统一更新。 - **工具化打包发布流程**,包括本地调试、云构建、线上发布体系、一键部署能力。同时,方案不仅限于前端工程部分,包含相关服务端基础设施,比如cdn服务搭建,接入层缓存方案设计,域名管控等。 - 客户端缓存及预加载方案。 ```p 熟悉各种Web前端技术,包括HTML/XML/CSS等,有基于Ajax的前端应用开发经验。 ``` 初级: - HTML方面包括但不限于:语义化标签,history api,storage,ajax2.0等。 - CSS方面包括但不限于:文档流,重绘重排,flex,BFC,IFC,before/after,动画,keyframe,画三角,优先级矩阵等。 - 知道axios或同级别网络请求库,知道axios的核心功能。 - 能口喷xhr用法,知道网络请求相关技术和技术底层,包括但不限于:content-type,不同type的作用;restful设计理念;cors处理方案,以及浏览器和服务端执行流程;口喷文件上传实现; - 知道如何完成登陆模块,包括但不限于:登陆表单如何实现;cookie登录态维护方案;token base登录态方案;session概念; 中级: - HTML方面能够结合各个**浏览器api**描述**常用类库的实现**。 - css方面能够结合各个概念,说明白网上那些hack方案或优化方案的原理。 - 能说明白接口请求的前后端整体架构和流程,包括:业务代码,浏览器原理,http协议,服务端接入层,rpc服务调用,负载均衡。 - 知道**websocket**用法,包括但不限于:鉴权,房间分配,心跳机制,重连方案等。 - 知道pc端与移动端登录态维护方案,知道token base登录态实现细节,知道服务端session控制实现,关键字:refresh token。 - 知道**oauth2.0**轻量与完整实现原理。 - 知道移动端api请求与socket如何通过native发送,知道如何与native进行数据交互,知道ios与安卓jsbridge实现原理。 高级: - 知道**移动端webview**和基础能力,包括但不限于:iOS端uiwebview与wkwebview差异;webview资源加载优化方案;webview池管理方案;native路由等。 - **登陆抽象层**,能够给出完整的前后端对用户体系的整体技术架构设计,满足多业务形态用户体系统一。考虑跨域名、多组织架构、跨端、用户态开放等场景。 - **mock方案**,能够设计出满足各种场景需要的mock数据方案,同时能说出对前后端分离的理解。考虑mock方案的通用性、场景覆盖度,以及代码或工程侵入程度。 - **埋点方案**,能够说明白前端埋点方案技术底层实现,以及技术选型原理。能够设计出基于埋点的数据采集和分析方案,关键字包括:分桶策略,采样率,时序性,数据仓库,数据清洗等 ### Witness Numbers (and the truthful 1,662,803) origin: [Witness Numbers (and the truthful 1,662,803) - Numberphile](https://www.youtube.com/watch?v=_MscGSN5J6o) > MEMO > 看了半天,才发现模算数 `a≡b (mod n)` 和模运算 `a≡b mod n`是不同的东西..带括号与不带括号。 > > 油管的评论很有趣: > > > I first learned about this when I took a class taught by **Prof. Rabin**, who called it the "randomized primality test" because he was too humble to tell us it was named after him, which made it a bit hard to find references to what he was talking about in our textbook or online > > [Miller–Rabin primality test](https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test) #### Modular arithmetic In [mathematics](https://en.wikipedia.org/wiki/Mathematics), **modular arithmetic** is a system of [arithmetic](https://en.wikipedia.org/wiki/Arithmetic) for [integers](https://en.wikipedia.org/wiki/Integer), where numbers "wrap around" when reaching a certain value, called the **modulus**. The modern approach to modular arithmetic was developed by [Carl Friedrich Gauss](https://en.wikipedia.org/wiki/Carl_Friedrich_Gauss) in his book *[Disquisitiones Arithmeticae](https://en.wikipedia.org/wiki/Disquisitiones_Arithmeticae)*, published in 1801. 在数学中,模算术是一种整数算术系统,其中数字在达到某个值时“环绕”,称为模数。现代模算术方法是由卡尔·弗里德里希·高斯 (Carl Friedrich Gauss) 在 1801 年出版的著作 Disquisitiones Arithmeticae 中提出的。 A familiar use of modular arithmetic is in the [12-hour clock](https://en.wikipedia.org/wiki/12-hour_clock), in which the day is divided into two 12-hour periods. If the time is 7:00 now, then 8 hours later it will be 3:00. Simple addition would result in 7 + 8 = 15, but clocks "wrap around" every 12 hours. Because the hour number starts over after it reaches 12, this is arithmetic *modulo* 12. In terms of the definition below, 15 is *congruent* to 3 modulo 12, so "15:00" on a [24-hour clock](https://en.wikipedia.org/wiki/24-hour_clock) is displayed "3:00" on a 12-hour clock. 模算术的常见用法是在 12 小时制中,其中一天被分为两个 12 小时周期。如果现在是 7:00,那么 8 小时后就是 3:00。简单的加法将导致 7 + 8 = 15,但时钟每 12 小时“环绕”一次。因为小时数到达12后重新开始,这是算术模12。 根据下面的定义,15等于3模12,所以24小时制的“15:00”显示为“3:00” " 12 小时制。 ##### Congruence Given an [integer](https://en.wikipedia.org/wiki/Integer) *n* > 1, called a **modulus**, two integers *a* and *b* are said to be **congruent** modulo *n*, if *n* is a [divisor](https://en.wikipedia.org/wiki/Divisor) of their difference (i.e., if there is an integer *k* such that *a* − *b* = *kn*). 给定一个整数 n > 1,称为模数,如果 n 是它们差的除数(即,如果存在整数 k 使得 `a − b = kn`),则两个整数 a 和 b 被称为模 n 全等。 Congruence modulo *n* is a [congruence relation](https://en.wikipedia.org/wiki/Congruence_relation), meaning that it is an [equivalence relation](https://en.wikipedia.org/wiki/Equivalence_relation) that is compatible with the operations of [addition](https://en.wikipedia.org/wiki/Addition), [subtraction](https://en.wikipedia.org/wiki/Subtraction), and [multiplication](https://en.wikipedia.org/wiki/Multiplication). Congruence modulo *n* is denoted: Congruence modulo n 是同余关系,意思是它是一种等价关系,兼容加、减、乘等运算。同余模 n 表示为: `a ≡ b (mod n)` The parentheses mean that (mod *n*) applies to the entire equation, not just to the right-hand side (here *b*). This notation is not to be confused with the notation *b* mod *n* (without parentheses), which refers to the [modulo operation](https://en.wikipedia.org/wiki/Modulo_operation). Indeed, *b* mod *n* denotes the unique integer *a* such that 0 ≤ *a* < *n* and `a ≡ b (mod n)` (i.e., the remainder of ![b](https://wikimedia.org/api/rest_v1/media/math/render/svg/f11423fbb2e967f986e36804a8ae4271734917c3) when divided by ![n](https://wikimedia.org/api/rest_v1/media/math/render/svg/a601995d55609f2d9f5e233e36fbe9ea26011b3b)). 括号表示 (mod *n*) 适用于整个等式,而不仅仅是右侧(此处为 *b*)。不要将此表示法与表示法 *b* mod *n*(**不带括号**)混淆,后者指的是 [模运算](https://en.wikipedia.org/wiki/Modulo_operation)。实际上,*b* mod *n* 表示唯一的整数 *a* 使得 0 ≤ *a* < *n* 和 `a ≡ b (mod n)` #### Modulo operation In [computing](https://en.wikipedia.org/wiki/Computing), the **modulo operation** returns the [remainder](https://en.wikipedia.org/wiki/Remainder) or signed remainder of a [division](https://en.wikipedia.org/wiki/Division_(mathematics)), after one number is divided by another (called the *[modulus](https://en.wikipedia.org/wiki/Modular_arithmetic)* of the operation). 在计算中,模运算返回除法的余数或带符号余数,在一个数除以另一个数后(称为运算的模数)。 #### Witness 给一个随机数(e.g. n=747), 利用一个质数(e.g. a=23)去判断是否是质数 。 $n=2^m\times d+1$ $747=2^1\times 373 + 1$ 判断是否是质数的条件是mod n为1。 $a^d=1\ mod \ n$ Online Calculating: [wolframalpha.com](https://www.wolframalpha.com/) ```mathematica 23^373 mod 747 Result 131 ``` 证人23给出了false的结果。 ### What to Learn origin: [What to learn](https://news.ycombinator.com/item?id=28904021) It's common to see people advocate for learning skills that they have or using processes that they use. For example, Steve Yegge has a set of blog posts where he recommends reading compiler books and learning about compilers. His reasoning is basically that, if you understand compilers, you'll see compiler problems everywhere and will recognize all of the cases where people are solving a compiler problem without using compiler knowledge. Instead of hacking together some half-baked solution that will never work, you can apply a bit of computer science knowledge to solve the problem in a better way with less effort. That's not untrue, but it's also not a reason to study compilers in particular because you can say that about many different areas of computer science and math. Queuing theory, computer architecture, mathematical optimization, operations research, etc. One response to that kind of objection is to say that [one should study everything](https://twitter.com/danluu/status/899141882760110081). While being an extremely broad generalist can work, it's gotten much harder to "know a bit of everything" and be effective because there's more of everything over time (in terms of both breadth and depth). And even if that weren't the case, I think saying “should” is too strong; whether or not someone enjoys having that kind of breadth is a matter of taste. Another approach that can also work, one that's more to my taste, is to, [as Gian Carlo Rota put it](https://alumni.media.mit.edu/~cahn/life/gian-carlo-rota-10-lessons.html), learn a few tricks: > A long time ago an older and well known number theorist made some disparaging remarks about Paul Erdos' work. You admire contributions to mathematics as much as I do, and I felt annoyed when the older mathematician flatly and definitively stated that all of Erdos' work could be reduced to a few tricks which Erdos repeatedly relied on in his proofs. What the number theorist did not realize is that other mathematicians, even the very best, also rely on a few tricks which they use over and over. Take Hilbert. The second volume of Hilbert's collected papers contains Hilbert's papers in invariant theory. I have made a point of reading some of these papers with care. It is sad to note that some of Hilbert's beautiful results have been completely forgotten. But on reading the proofs of Hilbert's striking and deep theorems in invariant theory, it was surprising to verify that Hilbert's proofs relied on the same few tricks. Even Hilbert had only a few tricks! For me, two ingredients for figuring out what to spend time learning are having a relative aptitude for something (relative to other things I might do, not relative to other people) and also having a good environment in which to learn. To say that someone should look for those things is so vague that's it's nearly useless, but it's still better than the usual advice, which boils down to "learn what I learned", which results in advice like "Career pro tip: if you want to get good, REALLY good, at designing complex and stateful distributed systems at scale in real-world environments, learn functional programming. It is an almost perfectly identical skillset." or the even more extreme claims from some language communities, like Chuck Moore's claim that Forth is at least 100x as productive as boring languages. Moreover, I don't think I could've learned as quickly on my own or by trying to follow advice from books or the internet. I think that [people who are really good at something have too many bits of information in their head about how to do it for that information to really be compressible into a book, let alone a blog post](https://danluu.com/hardware-unforgiving/). In sports, good coaches are able to convey that kind of information over time, but I don't know of anything similar for programming, so I think the best thing available for learning rate is to **find an environment that's full of experts**[3](https://danluu.com/learn-what/#fn:M). > HN Comment > > **I believe the thing we often need to learn is the thing we're afraid of learning**. We often (always?) have weaknesses that can/do jeopardize our strength and closing those weaknesses is crucial. > > The famous Scott Galloway (whom I had as a b-school professor) made this point like this: if you are a great guy, great father, great boss, etc, but once in a while you get violently drunk and hurt people in your life - THAT thing offsets everything else. You won't become better by "doubling down" on what you're already good at, but by fixing this flaw. > > The thing is - we all have glaring things like this - obstacles in our own trajectory that if we fix, our existing strength would really shine. > > --- > > So the Manager Tools podcast had a discussion about this I can't be bothered to find. Their advice, as best I recall it, was that you should focus on two things: **fixing absolute deal breakers**, and **honing your strengths**. Imagine you come up with N dimensions you want to rate yourself across on a 1 to 5 scale from worst to best. If you have any 1 out of 5's that are clearly blocking career progress, you should focus on that. If you're sitting at 2s and 3's, you should work on getting a 4 or 5, rather than leveling up across the board. > > --- > > even though **a small improvement in the weakness is worth more than an improvement in the strength.** ### Tasking developers with creating detailed estimates is a waste of time (2020) origin: [Tasking developers with creating detailed estimates is a waste of time (2020)](https://iism.org/article/is-tasking-developers-with-creating-detailed-estimates-a-waste-of-company-money-42) > MEMO > > 使用历史数据去做估计,使用4X法则: `every $1 spent on engineering must necessarily result in $4 of revenue.` Many of us have been here, our company is spinning up the next software project and in an effort to predict the future, requests for estimates rain down. Throughout the process, your Project Management Institute trained project manager (PMP) uses a variety of techniques on the data we provide to back into the **The Date™**: - Total hours and divide by number of engineers - Plug summary of detailed hour estimates into a Gantt chart - Create a spreadsheet with a total # of hours for the project and burn those hours down week by week - Use the latest flavor of off-the-shelf tools that will burn down hours as developers complete tasks **There is back-and-forth as the estimates are questioned for being too high, almost never for being too low.** Historical actual times for similar projects are never consulted because, as Jack Nicholson exclaimed, "**You can't handle the truth!**" Finally an agreed upon estimate is provided with much grumbling. Most of the time nobody is happy, everybody feels compromised. The most important stakeholder, the business, is especially compromised as a bad expectation was set on when the software will be delivered to the customer. So why don't Project Management techniques work for software development? The reason is quite simple, **software development involves messy discovery of new tasks in the complex and abstract environment of code**, which results in software development task durations being a "**?**". And Project Management techniques are designed to be applied to tasks with a known duration, an example of known duration tasks is [folding textiles for delivery to customers](https://iism.org/material/software-management-essentials-intro-management-systems/dimension-1-implementation-management-gantt). If you are working with a set of tasks with a well known duration, it would be a mistake to not apply Project Management techniques to complete those tasks as efficiently as possible. > Interested in the history of Scientific Management, the art of organizing well known duration tasks? See [Manufacturing Management History](https://iism.org/material-player/my-deck?materialSlideDeckId=26) Now there are a limited number of software tasks that do work well with Project Management. Let's take a set of 100 well known reports that need some simple variations applied to them for 10 customers. In addition, after a typical software project starts, there is messy discovery of new work that results in additional tasks being added by the team. This means that the duration for many software engineering tasks is really represented by a **?**, and the duration for a normal software engineering project is simply computed as **?+?+?...=The Date™** (at this point a project manager naively thinks, "how many of these **?** can be done in parallel?"). Which is of course nonsense, and brings us the current state of the industry where Software Projects are notorious for "missing the date" and software engineers are cranky about being asked all about the value of **?**. A few projects and missed dates under their belt and Project Managers start talking about adding **Contingency™**, which is just a hope that **?+?+?+Contingency™=The Date™**. > Note: Agile really does require iteration with a savvy customer, which is why [Agile Scrum is only effective 15% of the time](https://iism.org/article/agile-scrum-is-not-working-51). As it turns out, **working on the right thing is critically important**, and if the customer can't consistently tell the team what right looks like, then Agile Scrum is dead in the water. So, is tasking developers with creating detailed estimates a waste of company money? Yes, it is because software engineering involves messy discovery of a solution in the complex, abstract environment of code and changing requirements. Those detailed estimates are difficult to come up with and are mostly wrong because there is discovery of both coding constructs and requirements that needs to be done throughout the project. Instead of spending time on questionable estimates, Software Engineers should be focused on creating valuable software that supports a sustainable business! 那么,让开发人员创建详细的估算是在浪费公司资金吗?是的,这是因为软件工程涉及在复杂、抽象的代码环境和不断变化的需求中发现解决方案。这些详细的估计很难提出,而且大多是错误的,因为在整个项目中都需要发现编码结构和需求。软件工程师不应将时间花在有问题的估计上,而应专注于创建支持可持续业务的有价值的软件! > How much money does a software project need to make to be a sustainable business? Use the 4X rule! The 4X Rule is a generally accepted key performance index (KPI) and rule of thumb used by stock analyst to determine if the R&D engine of a technical company is healthy. The rule basically states that, in order to be an investment grade company, every $1 spent on engineering must necessarily result in $4 of revenue. See the [4X Rule](https://iism.org/post/glossary-the-4x-rule-and-the-40x-rule-66) for more details. > > 软件项目需要赚多少钱才能成为可持续发展的业务?使用4X规则! 4X 规则是股票分析师普遍接受的关键绩效指数 (KPI) 和经验法则,用于确定技术公司的研发引擎是否健康。该规则基本上规定,为了成为一家投资级公司,在工程上每花 1 美元就必须产生 4 美元的收入。有关详细信息,请参阅 4X 规则。 So what is a good way to estimate how long software engineering projects will take? **Simply put, use historical information to guide your high level estimates for future projects**. You've got a set of historical data on how many engineers you had working on various completed projects, right? Good! If not, spend some time and gather that information. Then sit down with your [relevant](https://iism.org/material-player/my-deck?materialSlideDeckId=25) Dev Managers and figure out what work in the upcoming project is similar to work completed in the past and use that as a guideline for predicting the future. This is a much better use of company money and way more accurate. In closing, **having an accurate plan for delivering working software is really important for the business**, and right now businesses are wary of software projects because they keep getting burned by bad expectations. So **use historicals to set good expectations** and let engineers focus on creating amazing software that your customers really want! ### Misc - [jack](https://twitter.com/jack/status/1465347002426867720) not sure anyone has heard but, I resigned from Twitter > I'm really sad ...yet really happy. There aren't companies that get to this level. And there aren't many founders that choose their company over their own ego. I know we'll prove this was the right move. - [Haskell in 100 Seconds](https://www.youtube.com/watch?v=Qa8IfEeBJqk) - > Comments: For the little more advanced users, here is an interpretation of the IO monad that I really liked: If you imagine that you put the state of our entire universe in a record World, then IO could be seen as a **World Transformer.** Thus, a function with side effects simply maps a state of the World to a new one. For example, putStrLn "Hello World!" takes a World where the screen is blank, and returns a World where "Hello World!" is on the screen :) I find this interpretation beautiful, and it doesn't violate immutability nor does it need side effects