一灯
字节一面
CSS 左边定宽右边自适应,写出所有能想到的代码
CSS 垂直居中,写出能想到的代码
手写原生 ajax
[] == (![]) 结果是什么,为什么
[] == false
true
手写 Promise.all
302 跳转时原生 ajax 和服务端分别作了什么工作
CORS 的常见攻防,cookie 有哪些常用属性
www.baidu.com已经登录,如何让tieba.baidu.com直接登录
当用户访问公司某系统(如 product.html)时,在 product 中会首先加载一个 iframe,iframe 中可以获取存储在 localStorage 中的 token,如果没有取到或 token 过期,iframe 中内部将把用户将重定向到登录页,用户在此页面登录,仍将去认证系统取得 token 并保存在 iframe 页面的 localStorage
聊过去的项目
算法题:两个有序数组合并成 1 个有序数组
字节二面:
聊项目和过去的经历
扫码登录的基本原理
1.网页端与服务器的配合逻辑:
首先用户打开网站的登录页面的时候,向浏览器的服务器发送获取登录二维码的请求。服务器收到请求后,随机生成一个 uuid,将这个 id 作为 key 值存入 redis 服务器,同时设置一个过期时间,在过期后,用户登录二维码需要进行刷新重新获取。
同时,将这个 key 值和本公司的验证字符串合在一起,通过二维码生成接口,生成一个二维码的图标,然后,将二维码图片和 uuid 一起返回给用户浏览器
浏览器拿到二维码和 uuid 后,会每隔一秒向浏览器发送一次,登录是否成功的请求。请求中携带有 uuid 作为当前页面的标识符。
2.手机端与服务器的配合逻辑: 浏览器拿到二维码之后,将二维码展示到页面,并给用户提示:请掏出您的手机,进行扫码登录 用户拿出手机扫描二维码,就可以得到一个验证信息和一个 uuid(扫描二维码获取字符串的)
由于手机端已经进行过登录,在访问手机端的服务器的时候,参数中都会携带一个用户的 token,手机端服务器可以从中解析到用户的 userId(这里从 token 中取值而不是手机端直接传 userid 是为了安全,直接传 userid 可能会被截获和修改,token 是加密的,被修改的风险会小很多).手机端将解析到的数据和用户 token 一起作为参数,向服务器发送验证登录请求(这里的服务器是手机服务器,手机端的服务器跟网页端服务器不是同一台服务器).
服务端收到请求后,首先对比参数中的验证信息,确定是否为用户登录请求接口。如果是,返回一个确认信息给手机端。
手机端收到返回后,将登录确认框显示给用户(防止用户误操作,同时使登录更加人性化),用户确认是进行的登录操作后,手机在发送请求。服务端拿到 uuId 和 userId 后,将用户的 userId 作为 value 值存入 redis 中以 uuid 为 key 的键值对中。
3.登录成功时的逻辑 然后,浏览器再次发送请求的时候,浏览器端的服务器就可以得到一个用户 Id,并调用登录的方法,声成一个浏览器端的 token,再浏览器再次发送请求的时候,将用户信息返回给浏览器,登录成功。这里存储用户 id 而不是直接存储用户信息是因为,手机端的用户信息,不一定是和浏览器端的用户信息完全一致。
一大堆数中取第 K 大的有哪些方法
https 的详细过程
canvas 常见的性能优化方法
使用缓存
利用 canvas 进行预渲染, 先绘制到一个离屏 canvas 中,然后再通过 drawImage 把离屏 canvas 画到主 canvas 中。离屏 canvas 还有一个注意事项,如果你做的效果是会将对象不停地创建和销毁,请慎重使用离屏 canvas,至少不要给每个对象的属性绑定离屏 canvas。 save 和 restore 影响的不是 canvas 的状态,而是 context 的状态(比如:fillStyle、transform 等),canvas 上的内容是不会更改的
当对象被销毁时,离屏 canvas 也会被销毁,而大量的离屏 canvas 不停地被创建和销毁,会导致 canvas buffer 耗费大量 GPU 资源,容易造成浏览器崩溃或者严重卡帧现象。解决办法就是弄一个离屏 canvas 数组,预先装进足够数量的离屏 canvas,仅将仍然存活的对象缓存起来,当对象被销毁时,再解除缓存。这样就不会导致离屏 canvas 被销毁了。
避免浮点运算
rounded = (0.5 + somenum) | 0; rounded = ~~ (0.5 + somenum); rounded = (0.5 + somenum) << 0;
尽量减少 canvas api 的调用
例如: 作粒子效果时,尽量少使用圆,最好使用方形,因为粒子太小,所以方形看上去也跟圆差不多。至于原因,很容易理解,我们画一个圆需要三个步骤:先 beginPath,然后用 arc 画弧,再用 fill 进行填充才能产生一个圆。但是画方形,只需要一个 fillRect 就可以了。虽然只是差了两个调用,当粒子对象数量达到一定时,这性能差距就会显示出来了。
使用 requestNextAnimationFrame 进行动画循环
setTimeout 和 setInterval 并非是专为连续循环产生得 API, 所以无法达到流畅得动画表现, 顾用 requestNextAnimationFrame , 可能需要 polyfill
关闭透明度
创建 canvas 上下文得 api 存在第二个参数: contextAttribute 是上下文属性, 用于初始化上下文得一些属性, 对于不同得 contextType, contextAttributes 的可取值
alpha boolean类型值,表明 canvas 包含一个 alpha 通道. 默认为 true,如果设置为 false, 浏览器将认为 canvas 背景总是不透明的, 这样可以加速绘制透明的内容和图片
尽量不要频繁得调用比较耗时得 API
shadow 和 绘图相关得 API, 例如: shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, drawImage, putImageData. 在进行绘制时也会增加耗时时间
避免堵塞
web worker 最常用得场景就是大量得频繁计算, 减轻主线程压力, 如果遇到大规模的计算, 可以通过此 API 分担主线程压力.可以配合上文的离屏 canvas
利用剪辑区域来处理动画背景或其他不变得图像 只聚焦在我们 clip 的区域. _ 利用剪辑区域技术来恢复上一帧动画所占背景图得执行步骤: _ 调用 context.save(),保存屏幕 canvas 的状态 _ 通过调用 beginPath 来开始一段新的路径 _ 在 context 对象上调用 arc()、rect()等方法来设置路径 _ 调用 context.clip()方法,将当前路径设置为屏幕 canvas 的剪辑区域 _ 擦除屏幕 canvas 中的图像(实际上只会擦除剪辑区域所在的这一块范围) _ 将背景图像绘制到屏幕 canvas 上(绘制操作实际上只会影响剪辑区域所在的范围,所以每帧绘制图像像素数更少) _ 恢复屏幕 canvas 的状态参数,重置剪辑区域
使用多层画布去画一个复杂得场景 吐过某些对象需要经常移动或更改,而其他对象则保持相对静态.在这种情况下,可能得优化是使用多个元素对您的项目进行分层.
用 css 设置大的背景图 如果像大多数游戏那样,你有一张静态的背景图,用一个静态的
元素,结合 background 特性,以及将它置于画布元素之后。这么做可以避免在每一帧在画布上绘制大图。
一个无侵入式的 PV 上报 sdk 怎么实现 需要统一多个渠道的 JS SDK,最精简的首先是 模块 + 通信 两个部分,首先 JS 模块化可以采用 ES6 module,实现一套插件拓展机制,另外一块是 JS 与 native 通信的 API,类似于 JSBridge。
类型检查和智能提示
泛型
构建
单元测试
草原上有 100 只狮子和 1 只羊,它们遵从如下基本法则:a 狮子可以吃草也可以吃羊,但更想吃掉羊;b 狮子吃掉羊后自己就会变成羊;c 生存是第一要义。问:这只羊是否会被吃?
最后更新于
这有帮助吗?