笔者虽然曾经也面试过很多求职者,但是对于前端的笔试和面试,我觉得并不能体现一个人的真实能力,所以建议大家多修炼前端真正的技术.对于前端面试题,之前也承诺过读者要出一篇,笔者大致总结一下曾今面试的题目.后续不会再出面试题,而是聚焦于一些真正的,有利于成长性的技术文章和思维方式,来帮助大家提高解决问题的能力.
首先总结一下笔者对于前端领域学习的一些成长模型和学习路线,来给大家提供一些参考.
下面推荐一些不同技术选型的优秀组件和库,也是笔者曾今使用过的.接下来言归正传,开始进入正文.
[参考答案]
0b
或者0B
)[参考答案]
介绍: Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。 状态: pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
[参考答案]
闭包就是能够读取其他函数内部变量的函数. 本质上,闭包是将函数内部和函数外部连接起来的桥梁.
[参考答案]
[参考答案] componentWillReceiveProps会在接收到新的props的时候调用
[参考答案]
[参考答案] 小程序原生页面存在层级限制,超过一定层数就会无法打开新页面。一开始这个限制为不超过5层,目前是不超过10层。
[参考答案]
// es5 Math.max.apply(null, arr); // es6 Math.max(...arr); 复制代码
[参考答案] HTTP客户端一般对同一个服务器的并发连接个数都是有限制的, 最大为6条
[参考答案]
[参考答案]
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
[参考答案] rest请求方法有4种,包括get,post,put,delete.分别对应获取资源,添加资源,更新资源及删除资源.
[参考答案] React16.3+废弃的三个生命周期函数
取而代之的是两个新的生命周期函数
class ScrollingList extends React.Component { constructor(props) { super(props); this.listRef = React.createRef(); } getSnapshotBeforeUpdate(prevProps, prevState) { // 返回的数据将作为componentDidUpdate第三个参数 return { stateA: 'xxx' }; } componentDidUpdate(prevProps, prevState, snapshot) { if (snapshot !== null) { console.log(snapshot.stateA) } } render() {} } 复制代码
高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。具体而言,高阶组件是参数为组件,返回值为新组件的函数.其本身是纯函数,没有副作用。
function logProps(WrappedComponent) { return class extends React.Component { componentWillReceiveProps(nextProps) { console.log('Current props: ', this.props); console.log('Next props: ', nextProps); } render() { // 将 input 组件包装在容器中,而不对其进行修改。Good! return <WrappedComponent {...this.props} />; } } } 复制代码
[参考答案]
headers字段 | 解释 | 案例 |
---|---|---|
Expires | 服务端告诉浏览器,先把这个文件缓存起来,在这个过期时间之前,该文件都不会变化 | Expires: Mon, 1 Aug 2016 22:43:02 GMT |
Cache-Control | 由于Expires给定的是绝对时间,而客户端的系统时间可以由用户任意修改, Cache-Control为相对时间 | Cache-Control: max-age=80 |
Last-Modified(response header) / If-Modified-Since (request header) | 服务端收到请求后会对比目前文件的最后修改时间和该请求头的信息,如果没有修改,那就直接返回304给浏览器,而不返回实际资源。如果有变化了,就返回200,并且带上新的资源内容 | If-Modified-Since:Mon, 01 Aug 2016 13:48:44 GMT |
Etag / If-None-Match | 第一次请求后响应头中包含了Etag,作为时间标签,下一次请求时会把原来的Etag标签带上(在请求头中变成了If-None-Match)作为校验标准,若这个文件如果发生了改变,则Etag也会改变。服务器对比浏览器请求头中的的If-None-Match:如果相同就返回304,而不返回实际资源如果不同,就返回200和新的资源。 |
[参考答案]
[参考答案]
progressive web app: 渐进式网页应用.可以将 Web 和 App 各自的优势融合在一起:渐进式、可响应、可离线、实现类似 App 的交互、即时更新、安全、可以被搜索引擎检索、可推送、可安装、可链接。其核心技术包括 App Manifest、Service Worker、Web Push,等等。
[参考答案]
同源策略/SOP(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击, 同源策略要求两个通讯地址的协议、域名、端口号必须相同,否则两个地址的通讯将被浏览器视为不安全的,并被阻挡下来. 要突破SOP的限制,我们可以使用如下方式:
res.setHeader("Access-Control-Allow-Origin","*"); // 不过CORS默认只支持GET/POST这两种http请求类型,如果要开启PUT/DELETE之类的方式,需要在服务端在添加一个"Access-Control-Allow-Methods"报头标签: res.setHeader( "Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, HEAD, PATCH" ) 复制代码
HTML5 postMessage 可以使用 postMessage 方法和 onmessage 事件来实现不同域之间的通信,其中postMessage用于实时向接收信息的页面发送消息
HTML5 WebSocket WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很棒的实现
JSONP 是JSON的一种“使用模式”,主要是利用script标签不受同源策略限制的特性,向跨域的服务器请求并返回一段JSON数据
iframe形式 通过设置相同的document.domain, 或者不同域通过window.name传递数据
服务器代理
[参考答案] response header响应头
[参考答案]
CSRF, 跨站请求伪造,它可以在用户毫不知情的情况下以用户名义伪造请求发送给受攻击站点,从而对用户或者网站造成攻击. 预防措施如下:
[参考答案]
// reduce function flatten(arr = []) { return arr.reduce((result, item) => { return result.concat(Array.isArray(item) ? flatten(item) : item) }, []) } // (toString | join) & split(利用数组的toString或者join,将数组转化为字符串) function flatten(arr = []) { return arr.toString().split(',').map(item => Number(item)) } 复制代码
[参考答案]
相比于callback,Promise 具有更易读的代码组织形式(链式结构调用),更好的异常处理方式(在调用 Promise 的末尾添加上一个catch方法捕获异常即可),以及异步操作并行处理的能力(Promise.all()Promise.race()等)。callback最大的问题就是我们通常说的回调地狱,一旦业务逻辑复杂了,我们不得不使用大量的嵌套回调代码,可维护性很低.
[参考答案]
[参考答案]
[参考答案] 参考<趣谈前端>周二打卡答案
[参考答案]
跨站请求伪造,可以理解为攻击者盗用了用户的身份,以用户的名义发送恶意请求,造成用户隐私及财产损失 过程: 1.登录受信任网站并在本地生成cookie; 2.在不登出 网站 的情况下访问危险网站 防范: 关键操作只接受POST请求, 使用验证码, 检测Referer, 使用token(或者JWT)
全称Cross-site script,跨站脚本攻击,是Web程序中常见的漏洞。原理是攻击者向有XSS漏洞的网站中输入恶意的脚本,当其它用户浏览该网站时候,该脚本会自动执行,从而达到攻击的目的(盗取Cookie,破坏页面结构,重定向到钓鱼网站等)。 区分: 分为持久型XSS和非持久性XSS. 持久型XSS是将攻击的脚本植入到服务器,从而导致每个访问的用户都会遭到此XSS脚本的攻击。非持久型XSS是将恶意脚本包装在页面的URL参数中,通过URL链接骗取用户访问,从而进行攻击. 防范: 对用户输入进行HTML转义, 对敏感信息进行过滤
通过把SQL命令插入到表单中并提交或页面请求的参数中,最终使得服务器执行恶意的SQL命令. 防范: 对用户的输入进行校验或限制长度;对特殊字符进行转换, 不要使用动态拼装SQL,为每个应用使用单独的权限有限的数据库连接。对隐私信息进行加密
分布式拒绝服务(DDoS:Distributed Denial of Service)攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力。
[参考答案]
function getUniqueItems(arr, num) { let temp = []; for (let index in arr) { temp.push(arr[index]); } let res = []; for (let i = 0; i<num; i++) { if (temp.length>0) { let arrIndex = Math.floor(Math.random()*temp.length); res[i] = temp[arrIndex]; temp.splice(arrIndex, 1); } else { break; } } return res; } 复制代码
[参考答案] 事件委托, 冒泡触发
[参考答案] 优点:
[参考答案]
WebP是一种支持有损压缩和无损压缩的图片文件格式,根据Google的测试,无损压缩后的WebP比PNG 文件少了45%的文件大小,即使这些PNG文件经过其他压缩工具压缩之后,WebP 还是可以减少28%的文件大小。
[参考答案]
从渲染的DOM来看,这两者都是链接,都是a标签,区别是: Link是react-router里实现路由跳转的链接,配合Route使用,react-router拦截了其默认的链接跳转行为,区别于传统的页面跳转,Link 的“跳转”行为只会触发相匹配的Route对应的页面内容更新,而不会刷新整个页面。 a标签是html原生的超链接,用于跳转到href指向的另一个页面或者锚点元素,跳转新页面会刷新页面。
[参考答案]
柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。柯里化函数能够让我们:
[参考答案]
[参考答案]
[参考答案]
object和Map存储的都是键值对组合。区别:object的键的类型是字符串;map的键的类型可以是任意类型;另外,object获取键值使用Object.keys(返回数组)Map获取键值使用map变量.keys() (返回迭代器)。
[参考答案]
(function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function () { var clientWidth = docEl.clientWidth; var fontSize = 20; docEl.style.fontSize = fontSize + 'px'; var docStyles = getComputedStyle(docEl); var realFontSize = parseFloat(docStyles.fontSize); var scale = realFontSize / fontSize; console.log("realFontSize: " + realFontSize + ", scale: " + scale); fontSize = clientWidth / 750 * 20; if(isIphoneX()) fontSize = 19; fontSize = fontSize / scale; docEl.style.fontSize = fontSize + 'px'; }; // Abort if browser does not support addEventListener if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', recalc, false); // iphoneX判断 function isIphoneX(){ return /iphone/gi.test(navigator.userAgent) && (screen.height == 812 && screen.width == 375) } })(document, window); 复制代码
[参考答案]
function dropHash(url) { let i = url.indexOf('#') return i > -1 ? url.replace(/#/g, '') : url } 复制代码
[参考答案] redux通过制定一套严格的规范,提供一种规范式的api和使用方式来处理状态, 适合大型项目和多人协同开发的项目,虽然代码编写有些繁复,但整体数据流向清楚,便于问题跟踪和后期维护,并且支持状态回溯.而window的变量管理比较混乱,维护不当还会造成变量污染,不适合中大型项目的开发.
[参考答案]
gulp | webpack | |
---|---|---|
定位 | 基于任务流的自动化打包工具 | 模块化打包工具 |
优点 | 易于学习和理解, 适合多页面应用开发 | 可以模块化的打包任何资源,适配任何模块系统,适合SPA单页应用的开发 |
缺点 | 不太适合单页或者自定义模块的开发 | 学习成本低,配置复杂,通过babel编译后的js代码打包后体积过大 |
[参考答案]
浏览器的同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互,jsonp跨域本质上是通过动态script标签, 本质上也是对静态资源的访问,所以只能是get请求
[参考答案]
栈内存中存放的是对象的访问地址,在堆内存中为这个值分配空间。这个值大小不固定,因此不能把它们保存到栈内存中。但内存地址大小的固定的,因此可以将内存地址保存在栈内存中。这样,当查询引用类型的变量时,先从栈中读取内存地址,然后再通过地址找到堆中的值。
[参考答案]
可以通过闭包自执行函数实现块作用域
[参考答案]
排序算法有:冒泡排序, 希尔排序, 快速排序, 插入排序, 归并排序, 堆排序, 桶排序等.
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
[参考答案] 从文件模块缓存中加载 > 从原生模块加载 > 从文件加载
[参考答案]
[参考答案]
[参考答案] vue中的数组的监听不是通过Object.defineProperty来实现的,是通过对'push', 'pop','shift','unshift','splice', 'sort','reverse'等改变数组本身的方法来通知监听的,所以直接给数组某一项赋值无法监听到变化,解决方案如下:
面试只是进入公司的第一步,如何走好它,需要自身的不断努力和学习,所以不要沉迷于走捷径,踏踏实实的学技术吧. 年前笔者会总结一下笔者2019年的技术成长与规划, 希望能和大家继续分享真正的前端技术.
如果想了解更多H5游戏, webpack,node,gulp,css3,javascript,nodeJS,canvas数据可视化等前端知识和实战,欢迎在公众号《趣谈前端》加入我们一起学习讨论,共同探索前端的边界。
年后公司因扩招需要2-3名熟悉react的工程师,坐标上海, 有意者请联系我哈~