2025年最新面试跟练(一)

146 阅读10分钟

1.没有IP地址只有mac地址会有什么问题

1.1. 网络范围受限

mac是物理地址,通常用于局域网内的设备识别和通信。不具备层次结构,无法跨网络路由数据

1.2. 地址冲突和唯一性问题

  1. mac地址是由制造商分配的,有重复的可能性
  2. IP地址由协议管理,更加灵活

1.3. 缺乏逻辑寻址能力

  1. IP是逻辑寻址,考虑了网络分段和子网划分,能够通过子网掩码和路由表高效转发
  2. mac地址是扁平的,网络设备无法判断数据包该发到哪里

1.4. 网路风暴和拥堵

  1. mac地址依赖arp广播来找到设备

1.5. 应用层协议无法正常工作

许多高层协议(如HTTP、TCP、UDP)依赖IP地址来建立连接和传输数据。例如,域名系统(DNS)将域名解析为IP地址,而不是MAC地址

1.6. 总结

没有IP地址,只有MAC地址,网络将局限于小型局域网,无法实现大规模、跨地域的通信,现代互联网将不复存在。IP地址和MAC地址各司其职,前者负责逻辑寻址和跨网络路由,后者负责物理设备标识,两者缺一不可

2.vite预构建是什么

是vite开发时的重要特性,使用esbuild对第三方依赖扫描转换和打包为浏览器可直接使用的esm格式,一般在开发时使用,用于提高服务器启动速度和页面加载性能,生产模式下vite会使用rollup进行完整的打包,不依赖预构建机制

2.1 预构建的实现方式

  1. 依赖扫描
  2. 依赖转换和打包(针对碎片化的依赖包和umd和commonjs的包)
  3. 重写源代码导入路径

2.2 触发时机

  1. 初次启动
  2. 依赖更新
  3. 动态导入
  4. 强制重新构建

2.3优势与局限

优势

  1. 启动速度快
  2. 减少请求
  3. 兼容性强

局限

  1. 只适用于开发模式
  2. 对于某些复杂依赖,需要手动调整

3.react hooks的设计理念是什么

react hooks是16.8版本引入的,设计理念是为了解决函数组件在状态管理、生命周期逻辑复用等方面的局限性,同时保持 React 的简洁性和声明式编程风格。

  • 增强函数组件:让函数组件具备状态管理和副作用处理能力,取代类组件。
  • 逻辑复用:通过自定义 Hooks 实现模块化、可组合的逻辑复用。
  • 简化代码:按功能组织代码,避免生命周期割裂和嵌套地狱。
  • 声明式与函数式:保持 React 的声明式风格,结合函数式编程的优点

3.1. 解决类组件的痛点

类组件虽然功能强大,但存在一些问题,Hooks 的设计直接针对这些痛点:

  • 复杂性:类组件需要理解 this 的绑定(如 this.handleClick = this.handleClick.bind(this)),容易出错。
  • 逻辑复用困难:在类组件中,复用状态逻辑通常依赖高阶组件(HOC)或 Render Props,这些模式会导致“嵌套地狱”(Wrapper Hell),代码结构复杂且难以维护。
  • 生命周期割裂:相关逻辑(如订阅事件和清理)常被分散在 componentDidMount、componentDidUpdate 和 componentWillUnmount 等生命周期方法中,难以统一管理。

Hooks 通过函数式编程的方式,让开发者以更直观、模块化的方式组织代码

3.2. 函数组件的增强

React 最初将函数组件设计为无状态的“纯渲染”组件,但随着应用复杂性增加,函数组件缺乏状态管理和副作用处理能力。Hooks 的引入让函数组件具备了以下能力:

  • 状态管理:通过 useState,函数组件可以拥有局部状态。
  • 副作用处理:通过 useEffect,函数组件可以处理生命周期相关的副作用(如数据获取、订阅事件)。
  • 逻辑复用:通过自定义 Hooks,开发者可以提取和共享状态逻辑,而无需改变组件层级结构。

这使得函数组件成为类组件的完全替代品,同时保持了轻量和简洁的特点。

3.3. 按功能组织代码

Hooks 鼓励开发者按功能而非生命周期阶段组织代码。在类组件中,同一功能的逻辑可能分散在多个生命周期方法中,而 Hooks 允许将相关逻辑集中在一起。例如:

// 类组件:逻辑分散
class Example extends React.Component {
  componentDidMount() {
    document.title = "Loaded";
    this.fetchData();
  }
  componentDidUpdate() {
    document.title = "Updated";
  }
  render() {
    return <div>{this.state.data}</div>;
  }
}

// Hooks:逻辑集中
function Example() {
  const [data, setData] = useState(null);

  useEffect(() => {
    document.title = "Loaded";
    fetchData().then(setData);
  }, []); // 依赖数组控制执行时机

  return <div>{data}</div>;
}

3.4. 逻辑复用的模块化

Hooks 的一个核心设计理念是可组合性和复用性。通过自定义 Hooks,开发者可以将状态逻辑封装成独立的可复用单元。例如:

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);
  return width;
}

// 在多个组件中使用
function Component1() {
  const width = useWindowWidth();
  return <div>Width: {width}</div>;
}

3.5. 设计原则与约束

React Hooks 的设计遵循了一些规则(如“只在顶层调用 Hooks”和“只在函数组件中调用 Hooks”),这些约束是为了:

  • 确保一致性:Hooks 的执行顺序必须固定,避免条件语句或循环中调用导致状态混乱。
  • 便于调试:通过 ESLint 插件(如 eslint-plugin-react-hooks)强制执行规则,减少开发者出错的可能性

4. 如何判断用户设备?

4.1. 通过navigator.userAgent

  • navigator.userAgent 返回浏览器发送的 User-Agent 字符串,其中包含设备、操作系统和浏览器信息。
  • 通过正则表达式匹配特定关键字(如 mobile、iphone、android)来判断设备类型。
const userAgent = navigator.userAgent.toLowerCase();
const isMobile = /mobile|iphone|ipad|android|blackberry|windows phone/i.test(userAgent);
const isTablet = /tablet|ipad/i.test(userAgent);
const isDesktop = !isMobile && !isTablet;

console.log('Mobile:', isMobile);
console.log('Tablet:', isTablet);
console.log('Desktop:', isDesktop);

4.1.1. 优点

  1. 简单易用,兼容性好
  2. 可以获取相信的信息

4.1.2. 局限性

  1. 用户可以伪造userAgent
  2. 字符串格式不统一
  3. 设备种类增加,正则表达式维护复杂

4.2. 通过屏幕尺寸和分辨率

function getDeviceType() {
  const width = window.innerWidth;
  if (width <= 768) {
    return 'Mobile';
  } else if (width <= 1024) {
    return 'Tablet';
  } else {
    return 'Desktop';
  }
}

window.addEventListener('resize', () => {
  console.log(getDeviceType());
});

根据屏幕尺寸进行判断,无法区分设备具体类型

4.3. 第三方库

  • Mobile-Detect:解析 User-Agent 并提供丰富的设备检测方法。
  • ua-parser-js:解析 User-Agent,返回设备类型、浏览器、操作系统等详细信息。

4.4. 通过触摸事件

移动设备有ontouchstart事件,pc端一般没有

5.如何实现低代码的多层渲染?

低代码平台中的多层渲染(Multi-layer Rendering)通常指的是在界面设计和开发中,通过分层的方式处理 UI 组件、数据绑定、逻辑处理和样式渲染,以实现高效、可视化的开发体验。这种方法在低代码平台(如OutSystems、Mendix 或国内的阿里云低代码平台)中非常常见,旨在降低开发复杂度,同时保持灵活性和可扩展性。以下是低代码多层渲染的实现原理和步骤:


5.1. 多层渲染的核心概念

多层渲染将界面生成过程分解为多个独立但相互协作的层,每层负责特定的功能:

  • 数据层:管理数据源、API 调用和状态。
  • 逻辑层:处理业务逻辑、事件触发和交互。
  • 组件层:定义可复用的 UI 组件及其结构。
  • 样式层:控制组件的视觉表现(CSS 或主题)。
  • 渲染层:将上述层整合并输出到目标环境(如 Web、移动端)。

通过分层,低代码平台可以在可视化编辑器中实现“所见即所得”,同时支持代码级别的扩展。


5.2. 实现多层渲染的步骤

以下是低代码平台实现多层渲染的典型流程:

5.2.1. 数据层设计

  • 功能:提供数据源(如数据库、API、静态数据)并绑定到界面。
  • 实现
    • 数据模型:定义数据结构(如 JSON Schema 或数据库表)。
    • 数据绑定:通过拖拽或配置,将数据字段映射到 UI 组件。例如,一个表格组件绑定到后端 API 返回的列表数据。
    • 动态更新:使用观察者模式或响应式框架(如 Vue 的 reactive 或 React 的 useState)监听数据变化,触发渲染更新。

5.2.2. 逻辑层处理

  • 功能:定义交互逻辑和事件处理。
  • 实现
    • 可视化逻辑编辑器:提供流程图或节点编辑器(如类似 Node-RED 的工具),用户通过拖拽节点定义逻辑。例如,“点击按钮 -> 调用 API -> 更新表格”。
    • 事件绑定:将组件的事件(如 onClick)与逻辑块关联。
    • 代码扩展:允许插入自定义 JavaScript/TypeScript 代码,处理复杂逻辑。

5.2.3. 组件层构建

  • 功能:提供可复用的 UI 组件库。
  • 实现
    • 组件定义:基于现有框架(如 React、Vue)封装组件,支持属性配置(如文本、颜色、大小)。
    • 层级结构:支持组件嵌套,形成多层结构。例如,一个表单组件包含输入框和按钮。
    • 预览与配置:在编辑器中实时预览组件效果,用户通过属性面板调整参数。

5.2.4. 样式层管理

  • 功能:控制组件的视觉表现。
  • 实现
    • 主题系统:提供全局主题(如颜色、字体),支持一键切换。
    • CSS 生成:根据用户在编辑器中的配置(如拖动调整大小),动态生成 CSS。
    • 响应式设计:内置媒体查询,支持多设备适配。

5.2.5. 渲染层整合

  • 功能:将各层整合并输出到目标环境。
  • 实现
    • 中间表示:将编辑器中的配置转换为中间数据结构(如 JSON),描述组件树、数据绑定和逻辑。
    • 代码生成:根据中间表示生成目标代码(如 HTML/CSS/JS 或 React/Vue 组件)。
    • 运行时引擎:提供一个运行时环境,解析中间表示并动态渲染。例如,OutSystems 使用服务器端渲染结合客户端 JS。

5.3. 技术实现的关键点

5.3.1. 分层解耦

  • 各层通过明确接口通信(如数据层通过事件通知渲染层),确保独立性和可维护性。
  • 使用发布-订阅模式或状态管理(如 Redux、Vuex)协调层间交互。

5.3.2. 动态渲染

  • 客户端渲染:基于前端框架(如 React、Vue)实时渲染,用户操作立即反映到界面。
  • 服务端渲染:部分低代码平台(如 OutSystems)在服务器端生成页面,客户端仅处理交互。

5.3.3. 性能优化

  • 懒加载:只渲染当前可见的组件层,延迟加载其他部分。
  • 缓存:缓存生成的样式和组件定义,减少重复计算。
  • 增量更新:使用虚拟 DOM 或类似技术,仅更新变化的部分。

5.3.4. 多端适配

  • 通过条件渲染和设备检测(如 navigator.userAgent 或媒体查询),生成适配 Web、iOS、Android 的界面。

5.4. 低代码多层渲染的优势与挑战

  • 优势
    • 高效开发:非技术人员也能通过拖拽完成复杂界面。
    • 一致性:分层设计保证了代码和样式的统一性。
    • 扩展性:支持自定义代码,满足复杂需求。
  • 挑战
    • 灵活性有限:过于依赖平台生成的代码,可能难以实现非常规需求。
    • 性能开销:多层抽象可能导致运行时效率低于手写代码。
    • 学习曲线:理解平台的分层逻辑需要一定时间。

5.5. 技术选型建议

  • 前端框架:React(组件化强)、Vue(轻量易集成)。
  • 构建工具:Vite(快速预览)、Webpack(生产优化)。
  • 状态管理:Zustand(轻量)、Redux(复杂场景)。
  • 后端支持:Node.js(API 服务)、GraphQL(灵活数据查询)。

5.6. 总结

低代码多层渲染通过数据、逻辑、组件、样式和渲染的分层设计,将复杂的开发过程抽象为可视化操作。其核心在于解耦各层职责,利用中间表示和运行时引擎动态生成目标代码。这种方法在快速原型开发和企业应用中尤为强大,但需要平衡灵活性与性能。