随笔(三)
随笔(三)
这两天刚结束完美团三面与腾讯三面,明天要开始阿里的面试,面试过程好煎熬,等待结果的过程很痛苦,写点东西平缓一下心情吧。
这个月,我寻求了现在工作的本科舍友的帮助,进行模拟问答。目的是想知道目前一线大厂对某些领域或者某些功能问题,是如何解决的(包括想法、技术、成本等)。这篇文章就是对某些问题的记录吧,可能今天写不完,后面会进行补充更新。
一、耗资源的任务处理
我们在实际开发中,一定会遇到非常耗资源的任务,会阻塞页面渲染,面对这种情况,如何进行处理。有两种解决方案,第一种是webworker,第二种是webassembly。
web worker
这里可能有人会疑问,JS虽然是单线程的,但不是有事件循环嘛。我们要知道,这是将耗时任务挂起,等到任务队列空闲下来,再去执行该任务,如果遇到非常耗时的任务,可以使用时间切片的方法进行优化,但这种优化,杯水车薪罢了。
web worker本质就是运行在浏览器背后独立的线程,将任务在此上进行执行,再返回给主线程。
具体实现过程如下,注意的是执行的任务也就是js文件,不能使用本地文件,必须是网络上的同源文件。实际开发可以放在public下面,当然到时候项目真正上线,可以让后端或者运维直接将文件丢在静态资源下面就行。
1 | <script setup> |
1 | ... //相关任务计算 |
这里还会遇到一个情况,就是模块导入问题,如果执行的任务文件需要引入第三方库或者其他资源文件,就需要此概念。
1 | importScripts("xxx.js") //这个网络地址可以跨域 |
webassembly
这个我还没具体用过,只能说一下思路。将任务执行代码用C、C++编写,然后转换成webassembly,导入到项目js文件中执行,webassembly是个二级制的格式,所以能被直接执行处理,又因为使用比较高效的语言,所以也能极大缩短执行时间。
二、requestAnimationFrame
我们在做倒计时秒杀活动的时候,会遇到两个问题,一个是当前时间获取不准确问题,另一个是实现如果用setTimeout/setInterval是不精确的。
这里可能有人会有第一个疑问,不是直接Data.now()或者getTime()不就可以了,但是这个获取的时间是用户设备的时间,而用户设备的时间会存在不精准的情况,我们应该要获取服务端的本地时间。那我们如何获取服务端的时间呢,在发送请求得到响应报文的时候,可以发现header中存在一个字段Date,这个就是服务端时间。接着又会存在一个疑问,我在倒计时的时候,如果不断发起请求获取时间,再完成差值计算,一方面过多的请求次数会耗费服务端性能,另一个方面请求也耗时。面对这种情况,其实我们只需完成一次请求,然后与本地设备时间进行插值比较即可,相当于去了解本地设备时间的误差。
针对第二个问题,因为定时器会受到事件循环宏微任务的影响,计算不精准,所以可以使用requestAnimationFrame去解决。它本质就是告诉浏览器在下一次页面重绘前,需要执行它里面的回调函数。因为页面刷新频率是固定的,所以不存在上述问题,其次requestAnimationFrame还有CPU节能、减少DOM操作的优点。
1 | function countDown(serverTime){ |
三、正则表达式
3.1 限定符
| 符号 | 意义 |
|---|---|
| ? | 0个或1个 |
| * | 0个或多个 |
| + | 1个或多个 |
| {2} | 出现2次 |
| {2, 6} | 出现2~6次 |
| {2, } | 出现次数不少于2次 |
| {ab}+ | ab出现次数>=1 |
3.2 运算符
| 符号 | 意义 |
|---|---|
| (a|b) | a或者b |
| [abc] [a-z] | |
| [^0-9] | 非数字 |
3.3 元字符
| 符号 | 意义 |
|---|---|
| \d | 数字字符 |
| \w | 单词(英文、数字、下划线) |
| \s | 空白符(空格、换行符) |
| \D | 非数字字符 |
| \W | 非单词字符 |
| \S | 非空白符 |
| . | 任意字符,但不包括换行符 |
| ^ | 匹配行首 |
| $ | 匹配行尾 |
| 样例 | 作用 |
|---|---|
| /#[a-fA-F0-9]{6}/g | RGB匹配 |
| /\b(25[0-5]|2[0-4\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)\b/g | ip |
3.4 方法
| 方法 | 返回值 | 作用 |
|---|---|---|
| 正则.test(字符串) | boolean | 检测字符串是否符合正则的标准 |
| 正则.exec(字符串) | [字符串中符合正则的第一项, 一些其他信息] | 捕获字符串中符合条件的内容 |
| 字符串.search(正则) | 有的话返回开始索引,没有返回 -1 | 查找字符串中是否有满足条件的内容 |
| 字符串.match(正则) | 有g => [匹配到的每一项] | 返回字符串中符合正则条件的内容 |
| 字符串.replace(正则,要替换的字符串) | 替换后的字符串 | 将字符串中满足正则条件的字符串替换掉 |
| eval(正则字符串) | 正则表达式 | 将字符串形式转为标准正则形式 |

