
第二次面试(前后端 java8与vue2)
周日也是面了第二次面试,先说个人感觉(感觉可能面试后端成功率比前端大...原本这个面试是面前端的),我感觉后端面试我很多理解面试官的意思,前端的话,主要是底层那一块,以及vue2那一块以及移动端确实存在很大的缺陷。废话不说了,下面是这次面试题的反思回顾。
1.后端(公司以SpringBoot以及java8为主)
1.java8的新特性
这个确实平时自学时没注意(因为平时为了方便都是用最新的jdk,但是公司为求稳用java8,平时没注重这方面java8的新特性,平时可能用到了但没注意)
AI:Java 8引入了许多重要的新特性,以下是其中一些主要的:
Lambda表达式:
Lambda表达式允许你以一种更简洁的方式编写代码,特别是对于集合和数组的操作。它们使得Java支持函数式编程风格。(用过)
函数式接口:
函数式接口是只包含一个抽象方法的接口,并可以使用
@FunctionalInterface
注解来标记。这些接口可以与Lambda表达式一起使用。
方法引用:
方法引用提供了非常简洁的方式来直接引用已有的方法或构造器。它可以使你的代码更加清晰和易读。
Stream API:
Stream API提供了一种高效且易于使用的方法来处理集合数据。它支持链式调用和并行处理。(我经常拿他处理集合与数组)
默认方法和静态方法:
接口中可以定义带有实现的默认方法和静态方法,这为接口添加了更多的灵活性。
Optional类:
Optional<T>
是一个容器类,它可以包含也可能不包含非null值。它的目的是减少代码中对null的检查,并防止NullPointerException。
新的日期/时间API (java.time):
新的日期和时间API解决了旧版Date和Calendar类的一些设计缺陷,提供了更好的日期和时间处理能力。
Nashorn JavaScript引擎:
Java 8包含了Nashorn,这是一个轻量级高性能的JavaScript引擎,替代了较慢的Rhino。
Base64支持:
Java 8内置了Base64编码和解码的支持,不再需要依赖第三方库。
并行数组排序:
Arrays类新增了并行排序方法,可以在多核处理器上更有效地工作。
类型注解和重复注解:
注解现在可以用于几乎任何地方(例如,变量类型、方法参数等),并且可以多次使用相同的注解。
2.HashMap的底层实现原理
AI:
1. 基本概念
数组 + 链表/红黑树:HashMap 底层是通过一个数组实现的,数组中的每一项称为一个“桶”(bucket),每个桶可以存储一个元素或者是一个链表的头节点,或者是红黑树的根节点。
哈希冲突:当两个不同的键产生相同的哈希值时,就会发生哈希冲突。HashMap 使用链地址法来解决哈希冲突,即在同一个桶位置上形成一个链表。如果链表长度超过一定阈值(默认为8),则会转换成红黑树以提高查找效率。
2. 存储过程
当你尝试将键值对放入 HashMap 时,首先计算键的哈希值。
根据哈希值找到对应的桶位置。具体是通过
(n - 1) & hash
来确定,这里的n
是桶数组的长度。如果该位置为空,则直接放置新创建的节点;如果不为空,则需要根据键是否相同来决定更新旧值还是添加到链表或红黑树中。
3. 扩容机制
默认情况下,HashMap 的初始容量为 16,负载因子为 0.75。这意味着当 HashMap 中的键值对数量超过了容量乘以负载因子的结果时,HashMap 会自动扩容。
扩容操作涉及重新计算所有现有键值对的新位置,并可能将某些链表转换为红黑树或将红黑树还原为链表。
4. 性能特点
在理想情况下(几乎没有哈希冲突),插入、删除和查找操作的时间复杂度都是 O(1)。
发生哈希冲突时,对于链表形式,最坏情况下的时间复杂度为 O(n),而在转换为红黑树后,最坏情况下的时间复杂度降为 O(log n)。
5. 其他特性
线程不安全:HashMap 不是线程安全的。如果你需要在多线程环境中使用,考虑使用
ConcurrentHashMap
。序列化:仅序列化实际包含的键值对,而不是整个桶数组。
简单回答了一下差不多吧,只讲了原理...
3.SpringBoot ioc aop那部分
控制反转 (IoC)
AI:IoC 是一种设计思想,用来减少代码之间的耦合度。通过 IoC 容器管理对象的创建和依赖注入(Dependency Injection, DI),可以使得对象之间松散耦合,便于测试和维护。
Bean: 在 Spring 中,被 IoC 容器管理的对象称为 Bean。
Bean 的作用域: 可以通过配置来定义 Bean 的作用范围,如单例(Singleton)、原型(Prototype)、请求(Request)等。
自动装配: Spring 能够自动检测并注入依赖项,减少了手动配置的工作量。
@Autowired 注解: 用于自动装配依赖,它可以应用于构造函数、字段或 setter 方法上。
面向切面编程 (AOP)
AOP 是一种编程范式,旨在通过分离横切关注点(cross-cutting concerns)来提高模块性。横切关注点是指影响多个模块的功能,比如日志记录、事务管理和安全性等。
切面 (Aspect): 切面包含了通知(Advice)和切入点(Pointcut)。通知是你想要执行的代码逻辑,而切入点则是你想要应用这些逻辑的位置。
通知 (Advice): 包括前置通知(Before)、后置通知(After)、返回之后通知(After-returning)、异常通知(After-throwing)和环绕通知(Around)等类型。
连接点 (Join Point): 应用程序执行过程中能够插入切面的一个点。这可以是一个方法的调用、异常抛出或者其他特定的执行点。
切入点 (Pointcut): 定义了何处(即哪些连接点)应用切面。通常通过表达式或者模式匹配来指定。
织入 (Weaving): 将切面与其他应用程序类型或对象连接起来形成代理对象的过程。
只回答了ioc感觉时间不够了,表达有待增强
4.Mybatis几级缓存
这个我熟悉
一级缓存
会话(SqlSession)级别:一级缓存是默认开启的,并且作用范围是同一个
SqlSession
。这意味着在同一个SqlSession
中执行相同的查询语句时,第二次查询会直接从缓存中获取数据,而不会再次访问数据库。生命周期:一级缓存的生命周期与
SqlSession
相同,当SqlSession
被关闭或提交时,一级缓存中的数据会被清空。注意事项:由于一级缓存存在于
SqlSession
级别,所以在分布式系统或多SqlSession
场景下,无法通过一级缓存共享数据。
二级缓存
命名空间级别:二级缓存的作用范围超越了
SqlSession
,它是基于 Mapper 命名空间的。因此,在不同SqlSession
之间也可以共享缓存的数据。要使用二级缓存,首先需要在 MyBatis 配置文件中启用它,并在对应的 Mapper XML 文件中添加<cache/>
标签或通过注解的方式进行配置。实现方式:MyBatis 允许你指定使用何种缓存实现,默认使用的是 PerpetualCache(内存缓存),但是可以通过实现 Cache 接口来自定义缓存策略,比如集成 Ehcache 或者其他高级缓存解决方案。
生命周期:二级缓存的数据在没有被显式清除之前会一直存在,直到触发了某些操作如更新、删除等才会失效相应的缓存条目。
2.前端(主要面我vue2与移动端那方面,有点细感觉,有些东西网上也找不到,还是项目敲少了)
1.vue生命周期
vue2
vue3
Vue 3 在 Composition API 中使用了不同的命名方式,与 Vue 2 的选项式 API 类似,但写法不同(使用 setup()
或 script setup
语法)
我只说了简单的创建,挂载,销毁(英文函数没说..更新忘说了...有点寄)
2.让元素垂直与水平居中
我第一想到最常用的justify-content与align-items,还有margin auto(下意识认为padding也可以了),还有个野法子不敢说,就是外面套一层div,将width变为0,写weight,但这样麻烦又啰嗦...更多方法我还不太了解
一、Flexbox 布局(最常用)
.parent { display: flex; justify-content: center; /* 水平居中 */ align-items: center; /* 垂直居中 */ height: 100vh; /* 父容器高度 */ }
<div class="parent"> <div class="child">居中内容</div> </div>
✅ 优点:简洁高效,响应式友好
🚫 注意:只对 Flex 容器的直接子元素生效
✅ 二、Grid 布局(CSS Grid)
.parent { display: grid; place-items: center; /* 同时设置水平与垂直居中 */ height: 100vh; }
<div class="parent"> <div class="child">居中内容</div> </div>
✅ 优点:一行代码搞定,兼容性良好(现代浏览器支持好)
✅ 三、绝对定位 + transform(适合固定大小或未知大小)
.parent { position: relative; height: 100vh; } .child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
<div class="parent"> <div class="child">居中内容</div> </div>
✅ 优点:适合未知宽高内容,如图标、文本等
🚫 缺点:需要父级有position: relative
或非 static 定位
✅ 四、table-cell + text-align(传统方法)
.parent { display: table-cell; vertical-align: middle; text-align: center; height: 100vh; }
<div class="parent"> <div class="child">居中内容</div> </div>
✅ 优点:适用于老版本浏览器
🚫 缺点:display: table-cell
不支持margin: auto
,且布局灵活性较低
✅ 五、line-height + text-align(仅限单行文本)
.parent { height: 100vh; line-height: 100vh; /* 与容器高度一致 */ text-align: center; }
<div class="parent"> 居中文本 </div>
✅ 优点:简单快速,适合文字
🚫 缺点:只能用于单行文本,多行会失效
✅ 六、绝对定位 + margin auto(需指定宽高)
.parent { position: relative; height: 100vh; } .child { position: absolute; width: 200px; height: 100px; top: 0; bottom: 0; left: 0; right: 0; margin: auto; }
<div class="parent"> <div class="child">居中内容</div> </div>
✅ 优点:兼容性较好
🚫 缺点:必须指定子元素宽高
✅ 七、transform + 绝对定位(更灵活)
.parent { position: relative; height: 100vh; } .child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
✅ 优点:无需知道子元素尺寸
🚫 缺点:可能会导致 GPU 加速渲染问题(罕见)
✅ 八、使用 JavaScript 动态计算位置(不推荐,仅了解)
const parent = document.querySelector('.parent'); const child = document.querySelector('.child'); function centerElement() { const parentRect = parent.getBoundingClientRect(); const childRect = child.getBoundingClientRect(); child.style.position = 'absolute'; child.style.left = (parentRect.width / 2 - childRect.width / 2) + 'px'; child.style.top = (parentRect.height / 2 - childRect.height / 2) + 'px'; } window.addEventListener('resize', centerElement); centerElement();
⚠️ 不推荐:性能差、维护麻烦,除非动态需求强烈否则不用
✅ 九、Vue + CSS 结合(示例)
<template> <div class="parent"> <div class="child">居中内容</div> </div> </template> <style scoped> .parent { display: flex; justify-content: center; align-items: center; height: 100vh; } .child { background: #eee; padding: 20px; } </style>
✅ 十、响应式设计中的注意事项
使用
height: 100vh
可能会导致移动端软键盘弹出时布局错乱,建议使用min-height
配合flex-grow
对于图片、视频等内容,考虑使用
object-fit
或aspect-ratio
来保持比例多层嵌套时要确保祖先元素没有限制定位流
📋 总结对比表:
好多啊...头痛
3.跨平台协调样式
🧩 一、什么是“跨平台协调样式”?
跨平台协调样式指的是:在多个平台上(如 Web 浏览器、React Native、Vue Native、Uniapp、Taro、Flutter Web/Android/iOS 等),让页面的外观和交互保持一致的视觉效果和行为表现。
这不仅包括颜色、字体、间距等样式,还包括:
布局结构
组件形态
动画过渡
默认样式处理
🎯 二、为什么需要协调样式?
🛠 三、如何协调样式?常见方法与技巧
✅ 1. 使用 CSS Reset 或 Normalize
/* 最简重置 */ * { margin: 0; padding: 0; box-sizing: border-box; }
或引入 Normalize.css 来统一浏览器默认样式。
✅ 2. 使用 CSS-in-JS 或 CSS Modules
CSS Modules:防止样式冲突,适用于 React/Vue。
CSS-in-JS(如 styled-components、emotion):动态生成样式,更灵活地控制样式作用域。
示例(styled-components):
import styled from 'styled-components'; const Button = styled.button` background-color: #4caf50; color: white; padding: 10px 20px; `;
✅ 3. 使用 PostCSS + Autoprefixer 自动兼容前缀
postcss.config.js: module.exports = { plugins: { autoprefixer: {}, cssnano: {} // 压缩 } }
✅ 4. 使用响应式单位:vw / rem / em / %
rem
:相对根字体大小,适合响应式布局(配合 JS 动态设置<html>
字体大小)vw
/vh
:视口单位,适合全屏元素flex
/grid
:现代布局方式,适配性强
✅ 5. 使用跨平台 UI 框架 / 统一组件库
✅ 6. 条件判断加载平台专属样式
// Vue 中示例 if (process.env.VUE_APP_PLATFORM === 'h5') { import('@/assets/css/h5.css') } else if (process.env.VUE_APP_PLATFORM === 'mp-weixin') { import('@/assets/css/weapp.css') }
✅ 7. 使用媒体查询与断点适配
@media screen and (max-width: 768px) { .container { flex-direction: column; } }
✅ 8. 统一设计系统(Design System)
建立统一的设计语言、组件库、颜色变量、字体系统等,确保所有平台遵循同一套 UI 规范。
例如:
// variables.less @primary-color: #4caf50; @font-size-base: 14px;
✅ 9. 使用 SCSS / LESS / Stylus 等预处理器
优势:
变量管理
Mixin / Extend
嵌套语法
函数封装
✅ 10. 使用跨平台工具链(Build Tools)
Webpack / Vite / Rspack:构建工具,统一打包流程
PostCSS / Babel:自动兼容旧版浏览器
Prettier / Stylelint:统一代码风格
📦 四、具体平台建议
4.uniapp底层转换原理
UniApp 的底层原理主要围绕如何将使用 Vue.js 编写的代码转换为可以在多个平台上运行的应用程序。这涉及到编译、运行时机制以及与各平台特性的对接。以下是 UniApp 底层转换和运行的详细原理:
1. 编译阶段
a. 源码到中间表示
开发者使用 Vue.js 和 HBuilderX(或其他IDE)编写应用代码,包括
.vue
文件、样式文件、脚本等。UniApp 使用自定义的编译器将这些代码转换成一种中间表示形式,该过程类似于 Vue CLI 的工作流,但会针对不同目标平台进行特定优化。
b. 条件编译支持
UniApp 支持基于平台的条件编译,允许开发者为不同的平台编写特定代码块。例如:
// #ifdef MP-WEIXIN console.log('This is WeChat Mini Program'); // #endif
这使得同一个项目可以根据构建的目标平台选择性地包含或排除代码。
c. 编译为目标平台代码
对于 Web 平台,直接编译为标准的 HTML/CSS/JavaScript 文件。
对于小程序平台(如微信小程序、支付宝小程序等),编译为符合各自规范的小程序代码包。
对于 iOS 和 Android 平台,编译为原生工程,其中包含了 WebView 容器以加载你的 Vue 应用,并通过桥接技术实现与原生功能的交互。
2. 运行时机制
a. WebView容器
在移动端(iOS 和 Android),应用通常运行在一个或多个 WebView 容器中。WebView 是一个可以嵌入在原生应用中的浏览器组件,它允许你在本地应用中展示网页内容。
这种方式让 UniApp 能够利用现有的 Web 技术栈,同时保持一定程度上的性能优化。
b. JSBridge
为了使 JavaScript 能够调用原生功能(如摄像头、地理位置等),UniApp 实现了 JSBridge。这是一个桥梁,允许前端代码与移动操作系统的原生API进行通信。
当你需要访问设备功能时,可以通过 JSBridge 发送请求到原生端,然后由原生代码执行相应的操作并返回结果给前端。
c. 性能优化策略
分包加载:对于大型应用,可以将其拆分为多个子包,在用户需要时按需加载。
预加载:某些页面或资源可以在后台预先加载,以减少用户的等待时间。
其他优化措施还包括缓存策略、懒加载图片等,旨在提升用户体验。
3. 跨平台适配
a. 统一的API接口
UniApp 提供了一套统一的 API 接口,用于处理不同平台间的差异。这意味着你可以编写一次代码,在多个平台上运行而无需担心底层实现细节的不同。
b. 组件兼容性
UniApp 包含了一系列内置组件,它们在各个平台上都有相似的表现形式,尽管具体实现可能有所不同。这有助于确保你的应用在不同设备上具有一致的外观和行为。
总结
UniApp 的底层转换原理主要是通过定制化的编译工具链,将Vue.js代码转化为适用于多种平台的应用程序。它不仅解决了多平台开发的复杂性问题,还提供了良好的性能和用户体验。通过使用 WebView 容器、JSBridge 等技术,实现了Web技术与原生功能的无缝集成,使得开发者能够专注于业务逻辑而非平台差异。此外,UniApp 还提供了一系列优化措施来提高应用性能,确保在各种设备上都能流畅运行。
--我不知道,脑瓜子痛搜也搜不到估计要爬源码和官方文档看了
5.css编译器(我只用过sass,但他们主流好像用less和stylus...完美错过...寄了)
6.pinia或vuex底层实现原理
AI:
无论是 Pinia 还是 Vuex,它们都是为 Vue.js 应用程序设计的状态管理库。尽管它们在使用上有一些差异,但从根本上来说,它们的实现原理围绕着几个核心概念:响应式系统、状态存储、mutation(变更)/action(动作)、getter(获取器)。下面分别介绍这两个库的底层实现原理。
Pinia 实现原理
1. 响应式基础
Pinia 建立在 Vue 3 的响应式系统之上,利用了
reactive
和computed
函数来创建响应式状态和计算属性。当状态发生变化时,Vue 的响应式系统会自动追踪这些变化,并更新相关的视图组件。
2. Store 定义
在 Pinia 中,通过
defineStore()
方法定义一个 Store。每个 Store 包含状态(state)、getters 和 actions。状态是响应式的对象,getters 类似于 Vue 组件中的 computed 属性,actions 则用于封装业务逻辑,可以同步或异步执行。
3. 插件支持
Pinia 支持插件扩展其功能,允许开发者在不修改核心代码的情况下添加自定义行为。
插件可以通过监听特定事件或者直接操作 Store 来实现增强功能。
4. 模块化与解耦
Pinia 提供了模块化的状态管理方案,允许应用有多个独立的 Store,每个 Store 可以有自己的状态、getters 和 actions。
不同 Store 之间可以通过注入依赖的方式进行交互,保持了良好的解耦性。
Vuex 实现原理
1. 响应式基础
Vuex 同样基于 Vue 的响应式系统,但在 Vue 2 中它依赖于 Vue 实例的
$data
来实现状态的响应式。Vuex 3.x 开始逐步迁移到 Vue 3 的 Composition API,从而更好地利用 Vue 3 的响应式特性。
2. Store 定义
Vuex 使用
new Vuex.Store()
创建 Store 实例。每个 Store 包括 state、mutations、actions 和 getters。State 是单一的数据源,mutations 用于同步地更改状态,actions 处理复杂的异步操作,getters 用于从 state 中派生出一些状态。
3. 严格模式
Vuex 提供了严格模式,在开发环境中开启后,如果尝试在 mutation 之外的地方直接修改 state,将会抛出错误,帮助开发者避免意外的状态变更。
4. 模块化结构
Vuex 允许将 store 分割成模块,每个模块拥有自己的 state、mutation、action 和 getter。这有助于大型项目的组织和维护。
总结
Pinia 更加现代化,充分利用了 Vue 3 的 Composition API,提供了更灵活、更简洁的 API 设计,同时减少了样板代码。
Vuex 是 Vue 生态系统中较早出现的状态管理解决方案,虽然它的 API 相对繁琐,但它有着丰富的社区资源和支持,特别是在 Vue 2 项目中被广泛采用。
两者的核心目标都是为了提供一种可预测的状态管理模式,使得状态的变化更加透明和可控,便于调试和维护。选择哪一个取决于你的具体需求以及你所使用的 Vue 版本。对于新的 Vue 3 项目,Pinia 因其简洁性和强大的功能通常是一个更好的选择。而对于已有的 Vue 2 项目,继续使用 Vuex 可能更为合适。
vuex 仅仅是作为 vue 的一个插件而存在,不像 Redux,MobX 等库可以应用于所有框架,vuex 只能使用在 vue 上,很大的程度是因为其高度依赖于 vue 的 computed 依赖检测系统以及其插件系统,
vuex 整体思想诞生于 flux,可其的实现方式完完全全的使用了 vue 自身的响应式设计,依赖监听、依赖收集都属于 vue 对对象 Property set get 方法的代理劫持。最后一句话结束 vuex 工作原理,vuex 中的 store 本质就是没有 template 的隐藏着的 vue 组件;
具体可看「经典题」Vuex常见面试题大全汇总--史上最全【vuex面试题】_vuex面试题必问-CSDN博客
最近先歇一会消化一下知识,明天再面试几次。