哈喽哈喽,大家好,我是你们的金樽清酒。在一个平常的一天,我上着班,突然接到一个电话。您好,我是字节跳动的hr,我们这边是抖音电商部门,请问您还在考虑找工作嘛。yes,yse,I do。ofcase。好的,那我这边给您发个邮件。中间有点小插曲,我戴着耳机多次误碰把电话挂了。哈哈哈哈哈。
每次面试的时候,我都习惯提前进入会议。在等了面试官五分钟的时候。hr打电话过来了。同学,你还记得今天的面试嘛。我说,啊,我不是在会议嘛。好家伙我跟面试官进的不是同一个会议。可能是个实习生小姐姐,哈哈哈哈哈,蛮可爱的。
自我介绍要说些什么呢?自我介绍的时间一般不能很长。要言简意赅的表达。主要表达清楚三个东西。我是谁?我会什么?我有什么经历或优势。
这个问题,一般是问你在公司处理过什么有难度的事情。比如性能优化呀。封装过什么有意义的组件。做过什么有意义的项目。肯定是挑最有技术难度的,而不是记流水账,一股脑没有重点。条理不清。
前期呢,我是在公司用echarts做一些数据可视化,完善后台的功能。后面呢,是重构后台,将原本主排期的后台变成排期开发部署一套流程。由于人手不够,不可能重开开发。这个时候我们可以用微前端技术将其他后台接入我们的后台,大大节省开发时间。
那什么是微前端? 微前端是一种将Web应用由单一的单体应用转变为多个小型前端应用聚合为一的手段。它借鉴了微服务的架构理念,将微服务的概念扩展到了前端。具体来说,微前端将一个大型的前端应用拆分成多个模块,每个模块可以由不同的团队进行管理,并可以自主选择框架,同时每个模块有自己的仓库,可以独立部署上线。也就是说,没有技术栈的限制。比如一个后台用的react技术栈,一个用的是vue技术栈。两个项目呢也可以很好的嵌套。这也是微前端的优势。独立部署,可以将一个巨石应用分成多个模块。
为什么选用MicroApp?其实选用MicroApp是因为MicroApp相对比较简单一点,它基于类WebComponent渲染,从组件化的思维实现微前端,低成本接入,不需要像其他一些框架(如single-spa和qiankun)要求子应用修改渲染逻辑并暴露出方法,也不需要修改webpack配置。在人手不够的情况下,容易上手,节省了学习的成本。当然还有很多微前端框架。如qiankun和single-spa,它们各自有自己适合的场景。
为什么会谈到跨域问题呢?因为用的MicroApp,将已有的项目嵌套。请求其他项目的页面,必然会发生跨域,不然的话就无法获取到资源。那为什么会跨域呢?是受浏览器同源策略的影响。
什么是同源策略? 同源策略(Same-Origin Policy,SOP)是浏览器为了保障用户信息安全而实施的一种安全策略。它限制了一个源(即协议、域名和端口的组合)的文档或脚本如何与另一个源的资源进行交互。
什么是同源? 同源是协议名相同如http与https就不同源。域名相同和端口号相同,这三者都相同说明是同源。
怎么解决跨域问题?
<script>
标签来实现跨域请求。面试官让我说出几种方法即可。但是大家还是需要自己去查找一下解决方案,如何去实施。
这题问到我心趴上了。因为前两天我的mentor就教了我这个东西。因为碰到过这个问题,我在请求其他端的接口的时候,请求体里面没有拿到东西。经过mentor一顿研究发现,在我发送post请求之前,还发生了一个option请求,option请求没有通过。
什么是option请求?option请求也叫预检请求。通常发生在跨域的时候。当浏览器需要发送一个非简单请求(complex request)时,会在实际请求之前发送一个OPTIONS
请求,以确认服务器是否允许该请求。这种机制有助于防止潜在的安全风险和意外的数据修改。
什么时候会发生预检请求呢? 首先肯定是需要跨域。PTIONS
预检请求是CORS机制的一部分,用于确保跨域请求的安全性和有效性。其次在浏览器发生非简单请求的时候。什么是非简单请求呢?
根据CORS规范,非简单请求是指那些不符合以下条件的请求:
GET
、HEAD
或POST
。Accept
、Accept-Language
、Content-Language
、Content-Type
(仅限于application/x-www-form-urlencoded
、multipart/form-data
、text/plain
)。ReadableStream
对象。当时是因为修改了请求头里面的内容,两个服务器协定好了一个字段用于登陆的验证,所以发生了预检,且预检不通过,因为请求头和响应头里面的字段没有完全对上。
强缓存是指浏览器在缓存有效期内直接使用缓存,而不向服务器发送请求。
启用强缓存可以在相应头设置Cache-Control: max-age=3600,这里是设置3600s,以s为单位
或者设置相应头Expires: Sat, 21 Dec 2024 23:12:28 GMT,给一个过期的时间。
不发生强缓存则可以设置为Cache-Control: no-store,或者Expires设置为一个过期时间。
协商缓存是指浏览器在缓存过期后,会向服务器发送请求,验证缓存数据是否过期。
启动协商缓存则设置Last-Modefied一个文件最后的修改时间,和ETag设置资源的唯一标识符。
不发生协商缓存则可以设置Cache-Control: no-store,或者将Last-Modified, ETag这俩响应头设置为无效值或者不设置。
为什么面试官这么问。现在才发现他是在引导我。Cache-Control
响应头用于控制浏览器和其他中间缓存如何缓存和重新使用已缓存的响应。 它有这些属性
public | |
---|---|
private | |
no-cache | |
no-store | |
max-age=<seconds> | |
must-revalidate | |
proxy-revalidate | must-revalidate ,但仅适用于共享缓存(如代理服务器)。 |
webpack和vite的区别主要体现在以下几个方面:
「构建速度」:
「开发模式」:
「生产构建」:
「插件生态系统」:
只能说webpack和vite很重要,但是小编我还没有深入的去了解过。得花时间去了解一下。
为什么谈到这个呢?他又想引导我。在问到webpack和vite的区别的时候,vite不是用ES模块原生的开发模式嘛,那肯定得了解ESMOdule。
CommonJS和ES模块是JavaScript中两种不同的模块系统,它们在语法、执行时机、动态导入等方面存在显著差异。
「CommonJS」:
require()
同步加载模块。module.exports
或 exports
导出模块成员。「ES模块」:
import
语句导入模块。export
语句导出模块成员。「CommonJS」:
require()
「ES模块」:
import
「CommonJS」:
require()
,并且是同步的。「ES模块」
支持动态导入,使用 import() 函数,并且是异步的,返回一个 Promise。
「CommonJS」:
「ES模块」:
export
和 import
来管理模块之间的依赖关系,而不是依赖共享的顶层作用域。「CommonJS」:
「ES模块」:
如何配置webpack
现代前端开发通常采用模块化的方式,将代码拆分成多个独立的模块。每个模块负责特定的功能,这样可以提高代码的可维护性和复用性。然而,浏览器并不直接支持模块化开发,因此需要打包工具将这些模块合并成一个或多个浏览器可以识别的静态文件。
打包工具可以对代码进行各种优化,以提高页面加载速度和用户体验。例如:
前端项目不仅包含 JavaScript 文件,还可能包含 CSS、图片、字体等多种类型的文件。打包工具可以处理这些不同类型的文件,并将它们合并成一个或多个浏览器可以识别的静态文件。
打包工具通常集成了各种开发工具和插件,可以帮助开发者提高开发效率。例如:
不同的浏览器对 JavaScript 和 CSS 的支持程度不同。打包工具可以通过转译(transpiling)等方式,将现代 JavaScript 和 CSS 转换为兼容性更好的版本,确保在各种浏览器中都能正常运行。
现代前端开发通常依赖于各种第三方库和框架。打包工具可以自动下载和管理这些依赖,并将它们合并到最终的打包文件中,简化了项目的依赖管理。
CDN(Content Delivery Network),即内容分发网络,是一种通过在全球范围内部署数据中心,利用内容缓存、内容分发、内容管理等技术,实现内容的快速、稳定传输的网络技术1。其目的是通过在现有的Internet中增加一层新的CACHE(缓存)层,将网站的内容发布到最接近用户的网络边缘的节点,使用户可以就近取得所需的内容,提高用户访问网站的响应速度2。
对于前端开发来说,CDN最重要的作用就是加速静态资源的加载。比如,你的网站有很多图片、CSS、JavaScript文件,这些文件都可以通过CDN来加速加载1。
使用CDN后,大部分的用户请求都会被CDN的数据中心处理,只有少部分请求会回源到原始服务器,因此可以大大减轻服务器的压力1。
通过减少数据传输的距离和时间,CDN可以显著提高网站的加载速度,从而提高网站的性能和用户体验1。
CDN还可以提供一些安全功能,如DDoS防护、SSL加密等,提高网站的安全性1。
CDN通过对网络的优化,解决了由于网络带宽小、用户访问量大、网点分布不均等原因导致的访问速度慢的问题2。
CDN可以缓解服务器端的第一公里问题,消除不同运营商之间互联的瓶颈,减轻各省的出口带宽压力,缓解骨干网的压力2。
get请求和post请求的区别。这是一个老生常谈的问题了。
首先看语义哦。get就是获取,post就是发送。get就是获取资源的请求,post就是设计来发送资源的请求,当然这只是语义方面。实际上是都可以用的。
其次,看传递的参数。get通过url携带参数,url?后面带参数&连接参数如:request.get('https:xxxx?name=xiaomin&age=18'),post请求是通过请求体携带参数。所以get请求的参数受url地址栏的限制,而post请求则没有。且参数直接在地址栏不安全,所以相对来说post请求会安全一点。
从跨域上说,部分get是不会发生跨域的,如script标签的src发送get请求不会发生跨域,所以可以用jsonp来解决跨域问题,但是这需要前后端沟通。
其实这道题是问你ajax请求的方式有哪些?
XMLHttpRequest(简称XHR)是JavaScript中的一个内置对象,用于在后台与服务器交换数据。以下是一个使用XMLHttpRequest发送GET请求的示例2:
function sendGetRequest(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
callback(xhr.responseText);
}
};
xhr.send();
}
Fetch API是现代浏览器提供的一种更现代化的、基于Promise的HTTP请求方式。以下是一个使用Fetch API发送GET请求的示例2:
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
这个在平常项目当中用的最多了。
在某些情况下,你可以使用Location对象来发送GET请求。这种方式通常用于页面跳转。以下是一个使用Location对象发送GET请求的示例1:
function pageGo() {
var tp = ${pb.tp}; // 获取总页数
var page = document.getElementById('page').value; // 获取页码
if (Number(page) > 0 && Number(page) <= tp) {
var path = location.pathname + '?pc=' + page;
location.assign(path); // 提交URL
}
}
这道题是这样的给你一个数组,要你写一个函数,使得数组的排列顺序随机。这一道题要用到洗牌算法,其实也不复杂,就是之前没有见到过,这下长见识了。
let arr = [1, 2, 3, 4, 5]
function shuffleAlgorithm(arr) {
for (let i = 0; i < arr.length; i++) {
let j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
shuffleAlgorithm(arr)
console.log(arr);
分析一下,每个数组的位置都要发生变化,那就循环遍历每个位置,然后每次生成一个随机数作为另一个交换位置的下标。进行交换,这样就可以保证每次生成的数组都能随机。注意要取整哦,随机数生成的是0-1的小数。
function MysetInterVal(fn, time) {
const tool = () => {
setTimeout(() => {
fn()
tool()
}, time)
}
tool()
}
function test(){
console.log('定时器触发');]
}
MysetInterVal(test,1000)
递归调用的时候,应该放在定时器里面再执行,我直接放在定时器外面了,可惜了,失之交臂。这一题其实就是考验对递归及函数功能的理解。
想更加详细了解的友友们,可以点击下方链接。setTimeout模拟setInterval
这一面,我清楚的认识到自己的不足。在对一些打包工具没有清晰的认识,因为没有自己去使用过,平常开发还达不到那个层面。再一个就是算法,有些人认为前端学算法有什么用,在平常开发的时候又用不到,可以用gpt查一下怎么写就够了。对,平常开发用不上,但这也是锻炼自己的逻辑思维能力和学习能力吧。到最后,我问了下面试官就是算法怎么去学,得到的答案是刷题。对,学习没有捷径。日拱一卒终到远方。不管怎么也要秉持一颗对编程的热爱,才能走的更加的长远。
其实吧,学习就是看透背后的逻辑,然后日复一日的进行总结归纳。万不可走捷径,贪图舒服。
还没有使用过我们刷题网站(https://fe.ecool.fun/)或者刷题小程序的同学,如果近期准备或者正在找工作,千万不要错过,题库主打题全和更新快哦~。
有会员购买、辅导咨询的小伙伴,可以通过下面的二维码,联系我们的小助手。
原文链接:
https://juejin.cn/post/7450822537560358931