哈士奇的一周面经:360前端实习

哈士奇回来更新上个星期的面经了,上个星期哈士奇先面的大厂是360,这也是哈士奇第一次面试大厂(反正大厂面试哈士奇都紧张),360的这位面试官挺和蔼的,也一直引导哈士奇回答提出的问题。总而言之,面试体验非常好。

话不多说,先给大家分享分享哈士奇的面试问题。

面试问题

自我介绍

聊项目

登录功能怎么实现的

JWT的加密泄露怎么办?

JWT有哪些信息

签名加密的算法

Vue-router 里面的hash模式和history router模式的区别

项目用的是什么模式

使用history模式时直接刷新带有路径的界面会发生什么?

项目编译完了以后怎么部署的

Vite和webpack的区别

聊一聊let、const、var 的区别

如何做到项目保证在不同手机上的一致性的体验

快速排序的实现

回答

1.自我介绍

这个比较建议大家提前写好自己的自我介绍,一般来说碰到了面试官问不太会卡壳

比如说:

我来自哪 平常对哪个内容很感兴趣 喜欢探索新技术 为什么选这个岗位 等等

一般来说,哈士奇建议大家在面试之前提前做好功课,比如说这家公司干什么的,这个岗位在这家公司要做什么,这样子提前准备会让面试官有个好的印象。

2.聊项目

项目这块哈士奇还是建议大家写点难点的项目,最好多写点复杂的组件,就好比方哈士奇后面说的登录注册这个功能,面试官会挖的非常深。从基础的前端连后端,到考虑存储位置,是否加密,加密用的方法,优缺点,全部都会问的清清楚楚。在项目这块面试官更注重你的深度,而不是广度。(哈士奇个人认为)

3.登陆注册功能的实现

这里略,相信大家的功能比哈士奇的更好。

4.JWT的加密泄露怎么办?

如果出现加密泄露的话基本上已经是很严重的问题了,因为哈士奇项目有说到jwt进行加密,因此问到了这个问题。

  1. 重新生成密钥:立即生成一个新的加密密钥,并将其用于签署新的JWT。这将使以前的JWT失效,并防止攻击者使用已泄露的密钥生成有效的JWT。

  2. 吊销已发出的JWT:如果可能的话,您可能需要在服务器端实施一种机制,使得已经发出的JWT失效。这可以通过在JWT中添加一个唯一的标识符(例如,UUID),并在服务器端跟踪这些标识符的列表来实现。

  3. 增加监控和审计:加强对JWT的监控和审计,以便及时发现任何异常活动。

5.JWT有哪些信息

是什么

说到JWT通常我们需要从概念了解清楚它究竟是什么,它的全名叫做JSON Web Token,它其实就是一串字符串,帮助我们加密在前后端传递信息。由于http的特性,服务器在接收请求的时候是无法分辨请求来源的,因此我们通常在第一次发送请求信息以后,服务器会返回给我们一个特定信息,证明这个请求是由这个用户发出的。

举个例子,甲乙同时给商城服务器发送登录请求,两个人都需要看看自己购物车有什么东西,但是服务器不知道到底该给谁的购物车信息,因此必须在两个人第一次登录以后返回一个信息,在后续两个人请求的时候辨明他们的身份。(这个就涉及到cookie这些东西,以后哈士奇专门出一期聊聊。)

那么对于登录返回的信息,服务器也不知道是不是用户自己发的,如果这个信息被黑客截取的的话就会导致用户信息泄露,那么我们就需要对它进行加密,防止被黑客拿走信息,这时候jwt就应运而生了。它可以对用户的专属信息进行加密。

包含内容

JWT(JSON Web Token)由三部分组成,它们用点号(.)分隔开来。这三部分分别是:

  1. Header(头部):包含了JWT的元数据信息,例如类型(typ)和所使用的算法(alg)。通常是一个JSON对象。

  2. Payload(载荷):包含了JWT的主要内容,例如用户的身份信息或其他数据。通常也是一个JSON对象。

  3. Signature(签名):由前两部分使用指定的算法进行签名生成的,用来验证JWT的真实性和完整性。签名是Base64编码后的字符串。

这三部分通过点号连接在一起就构成了一个完整的JWT。例如,一个JWT可能看起来像这样:

复制代码
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

其中,第一部分是头部,第二部分是载荷,第三部分是签名。

6.签名加密的算法

大家可以看到,面试官的问题非常精准,看到我们聊到了头部的加密以后,就开始聊它怎么加密的。

JWT的签名算法通常是使用HMAC(Hash-based Message Authentication Code)或RSA(Rivest-Shamir-Adleman)进行加密的。常见的算法包括:

  1. HMAC with SHA-256:使用SHA-256哈希函数和一个密钥对JWT进行签名。

  2. HMAC with SHA-384:使用SHA-384哈希函数和一个密钥对JWT进行签名。

  3. HMAC with SHA-512:使用SHA-512哈希函数和一个密钥对JWT进行签名。

  4. RSA with SHA-256:使用RSA算法和SHA-256哈希函数对JWT进行签名。

  5. RSA with SHA-384:使用RSA算法和SHA-384哈希函数对JWT进行签名。

  6. RSA with SHA-512:使用RSA算法和SHA-512哈希函数对JWT进行签名。

HMAC通常比RSA更快速,但RSA提供了更好的密钥管理和非对称加密的特性。

Vue-router 里面的hash模式和history router模式的区别

由于哈士奇在上面的算法里面卡壳比较严重,而且也没说出来很多算法,因此面试官转到了跳转方式的问题上面。

Vue Router 支持两种路由模式:hash 模式和 history 模式。它们的主要区别在于 URL 的表现形式和对浏览器特性的依赖。

  1. Hash 模式 :在 URL 中使用 # 来表示路由,如 http://example.com/#/path/to/route。在 hash 模式下,路由的改变不会引起浏览器向服务器发送请求,所有的路由都是在客户端进行处理的。这种模式的优点是兼容性好,支持老版本浏览器,并且部署简单。缺点是 URL 中会出现 #,看起来不够美观。

  2. History 模式 :利用了 HTML5 History API 来实现路由,去掉了 URL 中的 #,如 http://example.com/path/to/route。在 history 模式下,路由的改变会向服务器发送请求,因此需要服务器端的支持。这种模式的优点是 URL 较美观,不带 #,更符合传统 URL 的形式。缺点是需要服务器端支持,并且在一些特殊情况下可能会导致404错误。

因此,如果需要兼容老版本浏览器或部署简单,可以选择 hash 模式;如果需要更美观的 URL 或更接近传统 URL 的形式,可以选择 history 模式。

7.项目用的是什么模式

略过,通常大家默认都使用history模式,哈士奇也是这个

8.使用history模式时直接刷新带有路径的界面会发生什么?

在使用 Vue Router 的 history 模式时,当直接刷新带有路径的界面时,服务器会尝试去匹配相应的路由。如果服务器配置正确,能够处理这些路由,那么页面会正常加载。但是如果服务器没有正确配置,可能会导致404错误或者其他错误。

这是因为 history 模式使用了 HTML5 History API 来管理路由,它会将路由添加到浏览器的历史记录中,并且不会像 hash 模式那样在 URL 中包含 #。因此,当直接刷新带有路径的界面时,浏览器会向服务器发送请求,服务器需要能够正确地处理这些请求并返回对应的页面内容。

为了避免这种问题,通常需要在服务器端配置,确保所有的路由都指向同一个 HTML 文件,以便 Vue 应用程序能够正确地处理这些路由。这通常称为单页应用程序(SPA)的服务器配置。

9.项目编译完了以后怎么部署的

由于哈士奇的项目没有部署到云服务上面,所以这方面没有答得很深入。哈士奇猜测如果答上来了会问些云服务器相关的问题。

10.Vite和webpack的区别

Vite 和 Webpack 都是现代 JavaScript 应用程序的构建工具,但它们在实现方式和目标方面有一些区别。

  1. 实时开发服务器(Development Server)

    • Vite:Vite 内置了一个基于原生 ES 模块的开发服务器,利用浏览器原生支持的 ES 模块特性,在开发过程中能够实现快速的热更新,使得开发过程更加流畅。
    • Webpack:Webpack 也有自己的开发服务器 webpack-dev-server,但相比 Vite,它的热更新速度可能会稍慢一些,因为它是基于传统的模块热替换(HMR)技术实现的。
  2. 构建速度(Build Speed)

    • Vite:由于 Vite 在开发模式下利用了浏览器的原生 ES 模块特性,可以实现更快的构建速度。在生产模式下,Vite 会使用 Rollup 进行打包,进一步提高了构建速度。
    • Webpack:Webpack 的构建速度可能会比 Vite 慢一些,尤其是在大型项目中,因为它需要对所有模块进行分析和打包。
  3. 打包方式(Bundle)

    • Vite:在生产环境下,Vite 会使用 Rollup 进行打包,利用 Rollup 的 Tree Shaking 特性来实现更小的包大小。
    • Webpack:Webpack 也支持 Tree Shaking,但需要通过配置来实现。同时,Webpack 还支持更多的高级特性和插件,使得它在一些复杂的场景下更具灵活性。
  4. 配置方式(Configuration)

    • Vite:Vite 的配置相对简单,大部分情况下只需要一个简单的配置文件即可。Vite 的配置文件使用了 ES Module 的语法,更加清晰和直观。
    • Webpack:Webpack 的配置相对复杂,需要理解更多的概念和配置项。Webpack 的配置文件是一个 CommonJS 模块,需要使用 Node.js 的语法。

相对来说,Vite 更适合用于快速原型开发和小型项目,因为它具有快速的构建速度和简单的配置方式。而 Webpack 则更适合于大型项目和复杂的应用场景,因为它具有更多的高级特性和灵活的配置方式。

11.聊一聊let、const、var 的区别

聊到这个哈士奇就来劲了,之前写过文章嘛,大家可以参照哈士奇之前的文章

let 、const、var的区别

浅谈ES6部分新特性之let、const与解构

12.如何做到项目保证在不同手机上的一致性的体验

因为哈士奇主要是前端方向,所以从前端聊聊

前端主要使用响应式设计 包括:

  1. 弹性网格布局(Flexible Grid Layout):使用相对单位(如百分比、em 或 rem)而不是固定单位(如像素),使网页元素能够根据屏幕大小自动调整布局。

  2. 弹性图片和媒体(Flexible Images and Media) :使用 CSS 中的 max-width: 100%; 属性来确保图片和媒体元素在不同屏幕大小下能够自动缩放,避免图片溢出或失真。

  3. 媒体查询(Media Queries):使用 CSS3 中的媒体查询功能,根据设备的屏幕大小和特性应用不同的样式,以适应不同的设备和分辨率。

  4. 断点设计(Breakpoint Design):定义一些关键的断点(breakpoint),在这些断点上应用不同的样式,以实现在不同屏幕大小下的布局调整。

  5. 流式布局(Fluid Layout):使用相对单位和百分比来定义页面元素的宽度,使页面能够随着屏幕大小的变化而自动调整布局。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Layout Example</title>
<style>
/* 基础样式 */
body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

.container {
  padding: 20px;
  text-align: center;
}

/* 响应式布局 */
@media screen and (min-width: 768px) {
  .container {
    width: 50%;
    margin: 0 auto;
  }
}

@media screen and (min-width: 1024px) {
  .container {
    width: 30%;
  }
}
</style>
</head>
<body>
<div class="container">
  <h1>Responsive Layout Example</h1>
  <p>This is a responsive layout example with different widths for different screen sizes.</p>
</div>
</body>
</html>

13.快速排序的实现

快速排序(Quick Sort)是一种常用的排序算法,它的基本原理是选择一个基准元素,然后将数组中小于基准元素的元素移到基准元素的左边,大于基准元素的元素移到基准元素的右边,最终将数组分成两个子数组,然后递归地对这两个子数组进行排序,直到整个数组有序。

下面是快速排序的实现代码(使用 JavaScript):

javascript 复制代码
function quickSort(arr) {
    if (arr.length <= 1) {
        return arr;
    }

    const pivot = arr[0]; // 选择第一个元素作为基准元素
    const left = [];
    const right = [];

    for (let i = 1; i < arr.length; i++) {
        if (arr[i] < pivot) {
            left.push(arr[i]); // 小于基准元素的放在左边数组
        } else {
            right.push(arr[i]); // 大于等于基准元素的放在右边数组
        }
    }

    return [...quickSort(left), pivot, ...quickSort(right)]; // 递归地对左右子数组进行排序并合并
}

// 示例
const array = [4, 2, 7, 1, 9, 5, 3, 8, 6];
const sortedArray = quickSort(array);
console.log(sortedArray); // 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]

快速排序的时间复杂度为 O(n log n)(平均情况和最好情况),最坏情况下为 O(n^2),空间复杂度为 O(log n)(递归调用栈的大小)。快速排序是一种原地排序算法,不需要额外的空间来存储临时数据,因此它的空间复杂度相对较低。

这也是面试官最常考的排序算法,当然,还有其他算法,可以参照哈士奇的文章

排序算法有多少种?史上最全排序算法在这里!!

总结

基本上说到这里,哈士奇和面试官已经聊了四十多分钟了,面试官对于哈士奇的评价是基础还可以,但是面试经验相对不足。虽然哈士奇最后没有通过初试,但是整个人的体验非常不错!!在这里给哈士奇暴露出的问题还是面试技巧的问题,因此,在后面的学习和面试中,哈士奇也会加强这方面的学习,希望这篇面经能够对大家有所帮助!!!

相关推荐
uhakadotcom3 小时前
视频直播与视频点播:基础知识与应用场景
后端·面试·架构
范文杰3 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪3 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪3 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy4 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom4 小时前
快速开始使用 n8n
后端·面试·github
uhakadotcom4 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom4 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom5 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom5 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试