前端面试2024总结

八股文篇

一、css

1、移动端如何实现自适应

  • 媒体查询:‌使用CSS3的媒体查询功能,‌根据不同的屏幕尺寸和方向应用不同的样式规则。‌这种方法可以根据设备屏幕尺寸的不同,‌灵活调整页面的布局和样式,‌以适应不同的移动设备
  • 弹性盒子布局:‌利用CSS3弹性盒子布局模型,‌通过设置弹性容器和弹性项目的属性,‌实现灵活的布局。‌弹性盒子布局可以根据容器的尺寸和内容的大小,‌自动调整项目的布局和排列
  • rpx单位配合动态的font-size调整:‌使用rpx(‌根元素字体大小的倍数)‌作为单位来设置元素的尺寸,‌通过动态调整根元素的字体大小,‌可以控制整个页面的缩放比例,‌从而实现不同设备的适配。‌
  • Viewport单位:‌使用viewport单位(‌如vw、‌vh、‌vmin、‌vmax)‌来设置元素的尺寸,‌这些单位是相对于视口(‌浏览器窗口)‌的尺寸来计算的,‌可以根据视口的大小进行自适应布局。‌Viewport单位提供了一种直观且响应式的方式来设置元素尺寸

2、标准盒模型和怪异盒模型

  • 标准盒模型

默认情况下,浏览器使用标准盒模型。如果你希望明确指定使用标准盒模型,可以设置box-sizing: content-box

标准盒模型是 CSS 的默认盒模型,遵循 W3C 的规范。在这种模型中,元素的总宽度和总高度由以下部分组成:

总宽度=内容宽度+内边距宽度+边框宽度+外边距宽度,

总高度=内容高度+内边距高度+边框高度+外边距高度

  •  怪异盒模型

如果你想使用怪异盒模型,可以通过设置 box-sizing 属性为 border-box

  异盒模型是早期浏览器(如 IE6)中使用的盒模型。元素的宽度和高度计算方式包括内容(content)、内边距(padding)和边框(border),但不包括外边距(margin)

总宽度=内容宽度+内边距宽度+边框宽度

总高度=内容高度+内边距高度+边框高度

3、页面实现居中

利用flex弹性布局: 

/* html 实现son居中*/
<div class="box">
    <div class="son">111</div>
</div>

/* style */
.box {
    width: 100px;
    height: 100px;
    display: flex;
    justify-content: center;
    align-items: center
}

利用position定位(需要宽高):

/* html 实现son居中*/
<div class="box">
    <div class="son">111</div>
</div>

/* style */
.box {
    position: relative;
    .son {
        width: 100px;
        height: 100px;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
    }
}
/* html 实现son居中*/
<div class="box">
    <div class="son">111</div>
</div>

/* style */
.box {
    position: relative;
    width: 500px;
    height: 500px;
    .son {
        width: 100px;
        height: 100px;
        top: 50%;
        left: 50%;
        margin-left: -50px;
        margin-top: -50px;
    }
}

二、js

1、原型和原型链

  • 原型:js给每个函数分配的公共空间,减少内存占用
  • 原型链:多个原型的集合,当调用对象的属性或方法时,先自身找,找不到去原型链上找,一直找到Object构造函数得原型链

2、闭包是什么,在哪使用过

一个函数包含着另一个函数,这个函数能访问另一个函数里面的变量

3、谈谈深拷贝和浅拷贝

  • 浅拷贝:变量赋值,新值和旧值都指向同一个地址,改变新值旧值也会改变
  • 深拷贝:变量赋值,开辟新的地址,新数据赋值不会影响旧数据
  • 实现浅拷贝的方法:
const originalObj = {name: "gao", age: 20}
Object.assign({}, originalObj);

Array.concat() 方法:使用 Array.concat() 方法也可以在数组中创建一个浅拷贝

Array.slice() 方法:对于数组,可以使用 Array.slice() 方法来创建一个浅拷贝的副本。

  • 实现深拷贝的方法:

JSON.parse和JSON.stringify实现

JSON.parse(JSON.stringify())

递归实现

function deepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  let result;
  if (Array.isArray(obj)) {
    result = [];
    for (let i = 0; i < obj.length; i++) {
      result[i] = deepCopy(obj[i]);
    }
  } else {
    result = {};
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        result[key] = deepCopy(obj[key]);
      }
    }
  }

  return result;
}

4、你对promise的理解

解决回调地狱问题

5、什么是节流防抖,一般项目上哪里使用过

  • 防抖:一段时间可以执行多次,但是会清除前面的保留最后一次执行(相当于王者里的回城)

示例:滚动条滚动加载,搜索框搜索输入,用户名、手机号、邮箱输入验证

/**
 * 函数防抖:一段实现执行多次,只执行最后一次
 * @param {void} fn 回调函数
 * @param {number} t 节流时间
 * @returns {void}
 * @constructor
 */
function debounce(fn, t?) {
  const delay = t || 500;
  let timer: any;
  let that = this;
  return function () {
    const args = arguments;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      timer = null;
      fn.apply(that, args);
    }, delay);
  };
}
  • 节流:一段时间只能执行一次,相当于王者技能

示例:提交表单按钮

let timer;
let flag: boolean | undefined;
/**
 * 函数节流: 一段时间执行一次
 * @param {void} fn 回调函数
 * @param {number} wait 节流等待时间
 * @param {boolean} immediate 是否立马执行
 * @returns {void}
 * @constructor
 */
const throttle = (
  fn,
  wait = 500,
  immediate = true,
): void => {
  if (immediate) {
    if (!flag) {
      flag = true;
      // 如果是立即执行,则在wait毫秒内开始时执行
      typeof fn === "function" && fn();
      timer = setTimeout(() => {
        flag = false;
      }, wait);
    }
  } else if (!flag) {
    flag = true;
    // 如果是非立即执行,则在wait毫秒内的结束处执行
    timer = setTimeout(() => {
      flag = false;
      typeof fn === "function" && fn();
    }, wait);
  }
};

6、实现数组去重办法

  • 简单数组去重
function() {
    const arr = [1,2,3,2,3];
    let newArr = [];
    arr.forEach(item => {
        if(!newArr.inclouds(item)) {
            newArr.push(item)
        }
    })
}
  • 对象数组去重
function uniqueArray(arr, keyOrComparator) {
  if (!Array.isArray(arr)) {
    throw new Error('The first argument must be an array.');
  }

  if (typeof keyOrComparator === 'function') {
    // 使用自定义比较函数去重
    return arr.filter((item, index, self) => {
      return self.findIndex(t => keyOrComparator(item, t)) === index;
    });
  } else if (typeof keyOrComparator === 'string') {
    // 使用唯一键去重
    const seen = new Set();
    return arr.filter(item => {
      const key = item[keyOrComparator];
      if (seen.has(key)) {
        return false;
      } else {
        seen.add(key);
        return true;
      }
    });
  } else {
    // 默认行为:使用 JSON 字符串化去重
    const seen = new Set();
    return arr.filter(item => {
      const key = JSON.stringify(item);
      if (seen.has(key)) {
        return false;
      } else {
        seen.add(key);
        return true;
      }
    });
  }
}

项目篇

一、项目难点

1、切片上传文件

参考方案:

切片上传文件技术

先计算文件md5值,通过MD5值判断文件是否上传,避免重复上传,然后把文件切片处理,并发送传给服务器,通知服务器端进行切片的合并

2、websocket双向通信和SSE单选通信

参考方案:

SSE技术和WebSocket技术实现即时通讯-CSDN博客

3、移动端端适配

  • h5、App、ios、小程序适配不同端的适配
  • 不同大小手机css的适配大小

4、前端代码容易受到XSS(跨站脚本攻击)、CSRF(跨站请求伪造)等安全威胁。

  • XSS解决方案

    在用户输入时,我会使用正则表达式进行输入验证,确保输入内容符合预期格式。同时,我会对用户输入的内容进行HTML实体编码,防止恶意脚本被浏览器解析执行。此外,我还会在服务器端设置内容安全策略(CSP),进一步限制恶意脚本的执行。
  • CSRF解决方案

    我会在服务器端生成一个唯一的CSRF令牌,并将其作为隐藏字段添加到表单中。在处理表单提交时,我会验证令牌是否有效。同时,我还会结合用户IP地址和Referer头进行双重验证,确保请求的合法性。

二、项目功能

1、权限菜单

首先用户登录后我们会把权限和用户信息存到会话里,然后跳转到首页时候根据用户权限判断,需要展示的哪些菜单栏,并且在路由拦截里面进行权限跳转拦截,防止用户手动输入地址跳转

2、商品列表页面

原因:在商品列表数据有很多的时候,滚动加载会导致页面卡顿,内存溢出

解决方案:

  • 图片懒加载
  • 虚拟滚动(减少dom操作)

三、项目问题

1、在写react项目中遇到.ts文件无法使用const userStore = useUserStore();

项目中有个需求是要在ts文件使用store,因为它是在创建store之前引入,所有导致报错

原因:store创建之前使用了store

解决方案:

  • 创建createPinia实例,导出文件,在组件外部ts导入使用
  • 官方文档推荐在组件内部使用

2、在使用app端写renderjs从renderjs里面把数据传给逻辑层是,一直接受不到数据

原因:我是在使用vue3的写法写的,当时接受的方法写在setup里面,数据就是打印出来,目前不清楚原因是为什么

解决方案:

  • 于是我使用vue2的写法拿到了从视图层传过来的数据

3、uniapp在使用u-input是设置只读,点击触发不了外层点击事件

原因:在一般情况下,被只读&禁用的u-input元素会拦截所有的鼠标事件,导致外层的view上写的点击事件不再生效。而加上pointer-events: none;后,u–input就不再拦截鼠标事件,外层的view上的点击事件就能够正常生效了。

解决方案:禁用输入框或者设置只读,然后加上pointer-events: none样式

参考地址:【uniapp】解决在H5谷歌浏览器下 u-input 标签 设置只读后,click事件不生效_uniapp input 只读-CSDN博客

4、uview-plus升级到最新版本3.3.31报错Uncaught TypeError: import_meta.glob is not a function

原因:vite版本过低,我的原来vite版本原来2.9.9

解决方案:升级uview-plus版本但是没有升级vite版本,vite版本升级一下就好了

5、微信小程序设置动态具名插槽无法显示内容

解决方案:不动态写具名插槽

6、微信小程序ts文件里面写const instance = getCurrentInstance();打印出来是undefined

原因:getCurrentInstance() 是一个用于获取当前页面实例的方法,需要在页面setup里面获取,例如 onLoadonShow 等。如果在页面的生命周期函数之外调用,可能会导致无法正确获取实例。

解决方案:在vue文件获取const instance = getCurrentInstance();并且传到ts文件,不要在ts文件里面直接写

觉得对你有帮助的可以收藏加关注,后续还会更新更多内容,如有对文章有需要批改的地方欢迎留言,我会尽最大的努力完善最好的总结

欢迎大家使用华玥组件库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值