百度-面试题

65 阅读17分钟

1.在html中有哪些标签利于seo的优化?

<title> 标签:定义网页的标题,是搜索引擎结果页面(SERP)中显示的主要内容之一。

<meta> 标签:特别是 <meta name="description"> 和 <meta name="keywords"> 标签,可以提供网页的描述和关键词信息,有助于搜索引擎了解网页内容。

<header> 和 <footer> 标签:这些标签可以帮助搜索引擎更好地理解网页的结构和内容布局。

<h1> - <h6> 标签:使用适当的标题标签来标记页面中的主要标题和子标题,以便搜索引擎识别关键内容。

<img> 标签:在图片的 “alt” 属性中使用描述性文字,这有助于搜索引擎理解图片内容,同时也有助于在图像搜索结果中排名。

<a> 标签:使用适当的锚文本(anchor text)来创建内部和外部链接,以便搜索引擎了解链接的目标页面的主题。

<strong> 和 <em> 标签:使用这些标签来强调重要的关键词和短语,有助于搜索引擎理解内容的重要性。

<canonical> 标签:用于指定主要页面的规范 URL,以避免搜索引擎因为重复内容而降低排名。

通过合理地利用这些 HTML 标签,可以提高网页在搜索引擎结果中的可见性和排名。

2.html中哪些元素本身就是行内块元素?

行内块元素(inline-block elements):
     `<img>`:图片元素
     `<input>`:输入框元素
     `<button>`:按钮元素
     `<textarea>`:文本域元素
     `<select>`:选择框元素
     `<label>`:标签元素


块元素(block elements):
    `<div>`:通用块级容器
    `<p>`:段落元素
    `<h1>` - `<h6>`:标题元素
    `<ul>` 和 `<ol>`:无序列表和有序列表
    `<li>`:列表项元素
    `<table>`:表格元素

行内元素(inline elements):
    `<span>`:通用行内容器
    `<a>`:超链接元素
    `<strong>` 和 `<em>`:强调元素
    `<img>`:图片元素(可以在某些情况下表现为行内元素)
    `<input>`:输入框元素(可以在某些情况下表现为行内元素)
    `<button>`:按钮元素(可以在某些情况下表现为行内元素)

3.css弹性布局和网格布局的了解与应用?了解

  1. Flexbox:

    • Flexbox 是一种用于布局的一维布局模型,适用于在一个方向上排列元素(水平或垂直)。
    • 它通过 display: flex 属性将容器元素设置为弹性布局容器,然后使用各种属性控制子元素的布局。
    • Flexbox 提供了灵活的布局方式,使得元素可以轻松地在容器中对齐、排列和分布空间。
  2. Grid:

    • 网格布局是一种用于布局的二维布局模型,适用于在两个方向上排列元素(行和列)。
    • 它通过 display: grid 属性将容器元素设置为网格容器,然后使用网格线和单元格来定义布局。
    • 网格布局提供了更强大的布局能力,可以创建复杂的布局结构,并且具有对齐、间距和大小等方面的精确控制。

在实际应用中,可以根据布局需求选择适合的技术。一般来说,Flexbox 更适合处理一维布局,如导航菜单、排列项目等;而 Grid 更适合处理二维布局,如整体页面布局、定位项目等。常常也会将它们结合使用,以便更灵活地实现复杂的布局需求。

4.Promise有哪些属性?基本正确

  1. Promise.prototype:表示Promise构造函数的原型,允许向所有Promise对象添加新的属性和方法。
  2. Promise.all() :返回一个Promise实例,该实例在所有给定的promise已被解决或参数中不包含任何promise时解决,否则拒绝。
  3. Promise.race() :返回一个Promise实例,一旦其中的一个promise被解决或拒绝,返回的promise就会解决或拒绝。
  4. Promise.resolve() :返回一个以给定值解析后的Promise对象。如果该值为Promise对象,则直接返回该对象;否则,返回一个新的Promise对象,状态为resolved。 5 . Promise.reject() :返回一个状态为rejected的Promise实例,带有拒绝的原因。

5.map和set? 了解

Map 和 Set 是 ES6 中引入的两种新的数据结构,它们都提供了存储数据的集合,但有一些区别:

  1. Map:

    • Map 是键值对的集合,其中每个键唯一对应一个值。
    • 键可以是任意数据类型,包括基本类型和对象引用等。
    • Map 中的键值对是有序的,可以通过迭代器按插入顺序进行遍历。
    • 与对象不同,Map 的键不会自动转换为字符串,因此可以使用任意类型的值作为键。
  2. Set:

    • Set 是一组唯一值的集合,其中每个值只能出现一次。
    • Set 中的值是无序的,不能通过索引访问,但可以通过迭代器进行遍历。
    • Set 可以包含任意数据类型的值,且会自动去重,确保每个值只出现一次。

使用场景:

  • 使用 Map 当需要存储键值对,并且需要保持插入顺序或使用非字符串键时。
  • 使用 Set 当需要存储唯一值集合,且不关心顺序。
// 示例代码:

// 创建一个 Map
    let map = new Map();
    map.set('key1', 'value1');
    map.set('key2', 'value2');

// 创建一个 Set
    let set = new Set();
    set.add('value1');
    set.add('value2');
    set.add('value1'); // 这个值不会被添加,因为 Set 中的值是唯一的

6.vue3和vue2对比的提升?了解

  1. 性能提升

    • Vue 3 使用了更快的虚拟 DOM 和渲染优化,使得性能得到了显著提升。
    • 静态树提升(Static Tree Hoisting)和源码体积优化等技术进一步提高了性能和加载速度。
  2. 体积优化

    • Vue 3 的核心代码更加精简,包含更少的代码,减小了项目的体积。
    • 使用了 Tree-Shaking 技术,可以在构建时移除未使用的代码,进一步减小包大小。
  3. Composition API

    • Vue 3 引入了 Composition API,提供了更灵活和组合性的组件逻辑复用方式,取代了 Vue 2 的 Options API。
    • Composition API 更容易组织和重用逻辑代码,使得组件更易于维护和理解。
  4. TypeScript 支持

    • Vue 3 更好地支持 TypeScript,提供了完整的类型定义,使得开发更加健壮和可靠。
  5. 更好的 TypeScript 集成

    • Vue 3 通过重写了内部代码,使得 TypeScript 的类型推断更加准确,开发体验更好。
  6. 更好的响应式系统

    • Vue 3 的响应式系统经过重构,性能得到了提升,同时支持更多的响应式数据结构。
    • vue3 使用proxy 对处理对象时在数组的处理中没有重写数组方法进行劫持,对新添加的数据是具有响应式的(vue2 使用 $set 添加响应式数据)。

总体而言,Vue 3 在性能、体积、开发体验和功能上都有显著提升,是值得升级的版本。

7.Object.defineProperty的应用?

在 Vue.js 和其他一些框架中,常用 Object.defineProperty 来实现数据的响应式监听。通过在对象上定义 getter 和 setter 方法,在属性被访问或修改时执行相应的操作,从而实现数据的动态更新和响应。

8.vue3中的组件渲染过程与vue2有何不同?

  1. 编译器优化

    • Vue 3 使用了更加优化的编译器,生成的渲染函数效率更高。
    • 编译器会生成更少、更简洁的代码,减少了不必要的运行时开销。
  2. 虚拟 DOM 优化

    • Vue 3 的虚拟 DOM 实现进行了优化,比 Vue 2 更高效。
    • 在更新过程中,Vue 3 使用了静态树提升(Static Tree Hoisting)等技术,进一步减少了 DOM 操作次数,提高了性能。
  3. 响应式系统的改进

    • Vue 3 的响应式系统经过重构,性能得到了提升,比 Vue 2 更高效。
    • Vue 3 使用了 Proxy 来实现响应式,相比 Vue 2 的 Object.defineProperty,Proxy 具有更好的性能和扩展性。
  4. 组件实例的创建和销毁

    • Vue 3 在组件实例的创建和销毁过程中进行了一些优化,提高了性能和内存利用率。
    • 使用了更快的组件实例创建算法,并对组件销毁过程进行了更有效的内存回收。

总的来说,Vue 3 在渲染过程中进行了多方面的优化,提升了性能和开发体验。

~~> ~~~~

1.import 和 require 区别-了解

import 和 require 是 JavaScript 中用于导入模块的两种不同语法,它们之间的主要区别包括:

  1. 语法

    • import 是 ES6 中的语法,用于导入模块。
    • require 是 Node.js 中的语法,用于导入模块。
  2. 加载时机

    • import 是静态导入,会在代码解析阶段就加载模块,因此不能在代码的任意位置使用,只能在模块的顶层使用。
    • require 是动态导入,可以在代码的任意位置使用,并且在运行时根据条件加载模块。
  3. 返回值

    • import 返回一个 Promise 对象,当模块加载完成后,Promise 被解析为模块的命名空间对象。
    • require 直接返回导入的模块对象,可以直接使用导入的模块内容。
  4. 模块类型

    • import 主要用于 ES6 模块系统中导入 ES6 模块。
    • require 主要用于 CommonJS 模块系统中导入 CommonJS 模块。

总的来说,import 更加现代化、静态化,适用于 ES6 模块化开发;而 require 是 Node.js 中的模块导入方式,适用于 CommonJS 模块化开发。

2.vue3性能优化体现在哪些方面-了解

  1. 编译器优化:Vue 3 使用了更加优化的编译器,生成的渲染函数效率更高,生成更少、更简洁的代码,减少了不必要的运行时开销。
  2. 虚拟 DOM 优化:Vue 3 的虚拟 DOM 实现进行了优化,采用了静态树提升等技术,减少了 DOM 操作次数,提高了性能。
  3. 响应式系统改进:Vue 3 的响应式系统经过重构,采用了 Proxy 来实现响应式,相比 Vue 2 的 Object.defineProperty,性能得到了提升。
  4. 组件实例优化:Vue 3 在组件实例的创建和销毁过程中进行了优化,使用了更快的创建算法,并对组件销毁过程进行了更有效的内存回收。
  5. Tree shaking 支持:Vue 3 支持 tree shaking,可以消除生产环境中未使用的代码,减小打包体积,提高加载速度。

3.发布订阅模式

发布订阅模式(Publish-Subscribe Pattern)是一种软件设计模式,通常用于实现异步通信。它包含两个主要角色:

  1. 发布者(Publisher) :负责发布消息或事件。
  2. 订阅者(Subscriber) :通过订阅发布者的消息或事件来做出响应。

这种模式的基本原理是,发布者和订阅者之间存在一个消息通道,发布者将消息发送到通道上,订阅者从通道上接收消息。

特点和优势

  • 解耦性:发布者和订阅者之间松耦合,它们并不直接依赖于彼此,只依赖于消息通道。
  • 扩展性:可以轻松地增加新的发布者和订阅者,扩展系统功能。
  • 灵活性:发布者和订阅者可以在系统的不同部分进行通信,从而提高系统的灵活性和可维护性。
  • 异步性:发布者和订阅者可以在时间和空间上解耦,让异步操作更加容易。

使用场景

  • 事件驱动:如 DOM 事件、浏览器中的自定义事件。
  • 消息队列:用于处理异步任务,如在 Node.js 中的事件驱动架构。
  • 跨组件通信:用于解耦组件间的通信,如在前端框架中实现组件间的消息传递。

实现方式

在 JavaScript 中,可以通过原生的事件机制或第三方库来实现发布订阅模式,例如:

  1. 使用 DOM 事件

    // 发布者
    document.dispatchEvent(new CustomEvent('event-name', { detail: { data: 'some data' } }));
    
    // 订阅者
    document.addEventListener('event-name', (event) => {
        console.log(event.detail.data); // 输出 'some data'
    });
    

    **

  2. 使用第三方库,如 EventEmitter:

    // 引入 EventEmitter
    const EventEmitter = require('events');
    
    // 创建发布者
    const emitter = new EventEmitter();
    
    // 发布者发布事件
    emitter.emit('event-name', 'some data');
    
    // 订阅者订阅事件
    emitter.on('event-name', (data) => {
        console.log(data); // 输出 'some data'
    });
    

发布订阅模式在实际开发中广泛应用,能有效提升程序的灵活性和可维护性,尤其在需要解耦异步任务的场景中表现尤为突出。

4.大屏适配方案-了解

  1. 响应式设计(Responsive Design)

    • 使用 CSS 媒体查询(Media Queries)来根据屏幕尺寸调整布局和样式。
    • 通过设置不同的CSS样式,使页面可以在不同大小的屏幕上自适应,提供更好的用户体验。
  2. 流式布局(Fluid Layout)

    • 使用百分比(%)或者相对单位(em、rem)来定义容器和元素的宽度,使其能够根据视口大小自动调整。
    • 相比固定像素宽度,流式布局可以更灵活地适应不同尺寸的大屏幕。
  3. CSS Grid 和 Flexbox 布局

    • 使用 CSS Grid 和 Flexbox 布局可以更精确地控制页面中各个元素的排列和尺寸,适应不同的屏幕大小和比例。
  4. 视口单位(Viewport Units)

    • 使用视口单位(如vw、vh)来设置字体大小、容器宽度等,使其相对于视口尺寸而非固定像素大小变化。
  5. 断点策略(Breakpoint Strategy)

    • 在响应式设计中定义多个断点(breakpoints),根据不同的屏幕尺寸应用不同的布局和样式。
    • 这种策略可以确保在大屏幕上显示更多内容或调整布局以利用更大的空间。
  6. 图像和多媒体资源优化

    • 使用高分辨率的图像或矢量图标,以保证在大屏幕上显示清晰度和质量。
    • 对于多媒体资源,使用适当的技术确保视频或音频内容在各种屏幕大小上都能够正确播放和呈现。
  7. 测试和调试

    • 在开发过程中,通过模拟不同的大屏幕分辨率和使用浏览器的开发者工具来测试和调试适配效果。
    • 确保在各种大屏设备上都能够正常显示和良好工作。

5.vite和webpack的区别-了解

Vite 和 Webpack 是两种现代前端构建工具,在某些方面有着一些明显的区别。以下是它们之间的一些主要区别:

Vite

  1. 快速冷启动

    • Vite 使用 ES Module 的原生 ESM 支持和服务端渲染,可以实现极快的冷启动速度,特别适用于开发阶段的快速热更新。
  2. 按需编译

    • Vite 可以按需编译,即每个模块的更改都独立触发重新编译,提高了开发时的效率。
  3. 基于浏览器原生 ES 模块

    • Vite 基于浏览器原生的 ES 模块导入,避免了传统构建工具中繁重的打包过程。
  4. 插件化的构建

    • Vite 使用插件来扩展构建过程,使得配置更加灵活和模块化。

Webpack

  1. 强大的功能

    • Webpack 是一个功能强大且灵活的构建工具,适用于处理各种复杂的前端项目需求。
  2. 成熟的生态系统

    • Webpack 有着丰富的社区支持和强大的生态系统,有大量的插件和loader可以满足各种需求。
  3. Code Splitting

    • Webpack 提供了强大的 Code Splitting 功能,可帮助将代码拆分成较小的块,以实现按需加载,从而提高性能。
  4. 资源处理

    • Webpack 在处理各种资源类型(如样式、图片、字体等)时有着丰富的loader,能够处理更多不同类型的文件。

共同点

  1. 模块化

    • 两者都支持模块化开发,可以使用 ES Module、CommonJS 等模块规范进行开发。
  2. 构建优化

    • 两者都可以进行代码压缩、混淆、代码拆分等优化操作,以提高前端项目的性能和效率。
  3. 社区支持

    • Webpack 和 Vite 都拥有活跃的社区支持,可以获取到丰富的文档和解决方案。

选择使用 Vite 还是 Webpack 取决于具体项目需求和开发场景,对于简单、轻量级的项目,Vite 可能会更适合;而对于复杂、大型的项目,Webpack 可能更合适。建议根据实际情况选择合适的构建工具,以确保项目能够高效进行开发和部署。

6.vite和webpack实现过插件吗??-写过一个

Vite 插件

  1. Rollup 插件

    • Vite 是基于 Rollup 构建的,因此可以直接使用 Rollup 插件,或者编写专门为 Vite 设计的插件。
    • Vite 的插件可以使用 JavaScript 编写,并且可以通过一个简单的 API 与 Vite 的构建过程进行交互。
  2. Vite 自定义插件

    • Vite 提供了一些特定于 Vite 的插件接口,允许开发者编写针对 Vite 构建过程的自定义插件。
    • 开发者可以通过编写 JavaScript 或 TypeScript 插件来扩展 Vite 的功能,如处理特定类型的文件、优化构建输出等。

Webpack 插件

  1. Tapable 钩子系统

    • Webpack 使用 Tapable 实现插件系统,开发者可以通过 Tapable 提供的各种钩子(hooks)来编写自定义插件。
    • 插件可以在 Webpack 的不同构建阶段注入自定义逻辑,如在编译、打包、优化等阶段进行操作。
  2. Compiler 和 Compilation 对象

    • Webpack 插件通过 Compiler 和 Compilation 对象与 Webpack 构建过程进行交互,可以访问构建过程中的各种信息和数据。
    • 开发者可以编写 JavaScript 或 TypeScript 插件来修改编译配置、处理模块、生成资源文件等。

无论是在 Vite 还是 Webpack 中,编写插件都是扩展构建工具功能的常用方式。开发者可以根据项目需求编写定制化的插件,以实现特定的功能或优化构建过程。

7.介绍下rem-了解

rem 是一种相对长度单位,它代表的是相对于根元素(即 <html> 元素)的字体大小。相比于其他单位如像素(px)或百分比(%),rem 的特点是相对于根元素的字体大小进行计算,这使得在响应式设计中更方便地调整布局和尺寸。

在使用 rem 单位时,如果根元素的字体大小为 16px,那么 1rem 就等于 16px2rem 就等于 32px,依此类推。通过设置根元素的字体大小,可以方便地控制整个页面中其他元素的尺寸。

rem 单位在响应式设计中特别有用,因为它可以根据用户设备或浏览器的字体大小做出相应调整,确保页面在不同设备上有良好的可读性和可访问性

8.给定一个字符串数组统计每个字符出现的次数按最大值排序

function countCharacters(arr) {
  let charCount = {}; // 遍历字符串数组,统计每个字符出现的次数 
  arr.forEach(str => { str.split('').forEach(char => { 
  if (charCount[char]) {
    charCount[char]++; } 
  else { charCount[char] = 1; } }); }); // 将字符出现次数转换成数组,并按照出现次数最大值降序排序 
  let sortedChars = Object.keys(charCount).sort((a, b) => charCount[b] - charCount[a]); return sortedChars; } 
  
  // 示例用法 
  let strings = ["hello", "world", "hi", "there"]; 
  let sortedCharacters = countCharacters(strings); 
  console.log(sortedCharacters); // 输出按出现次数最大值排序的字符数组

9.给定数组 找到和为目标的值

function twoSum(nums, target) { 
let map = new Map();
for (let i = 0; i < nums.length; i++) {
let complement = target - nums[i]; 
if (map.has(complement)) { return [map.get(complement), i]; } map.set(nums[i], i); } return null; } 

let nums = [2, 7, 11, 15]; 
let target = 9; 
console.log(twoSum(nums, target));