前端八股文面经大全:秦丝科技前端(2026-04-24)·笔试深度解析

前言

大家好,我是木斯佳。

相信很多人都感受到了,在AI浪潮的席卷之下,前端领域的门槛在变高,纯粹的"增删改查"岗位正在肉眼可见地减少。曾经热闹非凡的面经分享,如今也沉寂了许多。但我们都知道,市场的潮水退去,留下的才是真正在踏实准备、努力沉淀的人。学习的需求,从未消失,只是变得更加务实和深入。

这个专栏的初衷很简单:拒绝过时的、流水线式的PDF引流贴,专注于收集和整理当下最新、最真实的前端面试资料。我会在每一份面经和八股文的基础上,尝试从面试官的角度去拆解问题背后的逻辑,而不仅仅是提供一份静态的背诵答案。无论你是校招还是社招,目标是中大厂还是新兴团队,只要是真实发生、有价值的面试经历,我都会在这个专栏里为你沉淀下来。专栏快速地址

温馨提示:市面上的面经鱼龙混杂,甄别真伪、把握时效,是我们对抗内卷最有效的武器。

面经原文内容

📍面试公司:秦丝科技

🕐面试时间:近期

💻面试形式:笔试(全手写题)

❓笔试题:

  1. 说明box-sizing属性

  2. 判断obj是否为空对象

  3. 判断3==true

  4. 小数四舍五入,3.335 → 3.34

  5. 反转字符串,i am developer → developer am i

  6. 闭包程序输出(名称随便取的)

    javascript 复制代码
    var a = 8;
    function output() {
      (function () {
        return function inner(){
          var a = 10;
          a++;
          console.log(a);
        }
      })()();
    }
    output();
    output();
  7. 文字截断样式

  8. 三列响应式布局

  9. 防抖

  10. 给出一个数组包含10个对象,每个对象包含名称字符串和分数数组,要求先去掉分数数组中的最大小值,然后取平均值

来源:牛客网 牛客745503321号

💡 木木有话说(刷前先看)

AI写代码习惯了,来份笔试题收录一下。

秦丝科技这场笔试,是一份非常典型的前端基础笔试题 。全是手写题,覆盖CSS(box-sizing、文字截断、三列布局)、JS基础(对象判空、类型转换、小数精度、反转字符串、闭包输出)、防抖实现、数组对象处理。难度中等偏基础,适合校招/实习同学用来检验基本功。第6题闭包输出有点绕,需要仔细分析作用域;第4题小数四舍五入涉及浮点数精度问题,是常见坑点。


📝 秦丝科技前端笔试·深度解析

🎯 笔试整体画像

维度 特征
笔试风格 基础实战型 + 手写代码型 + 细节考察型
难度评级 ⭐⭐⭐(三星,基础为主,闭包/精度题有坑)
考察重心 CSS基础属性、JS对象/类型转换、字符串处理、闭包作用域、数组算法
特殊之处 全手写无选择,考察实际编码能力

🔍 逐题深度解析

一、说明box-sizing属性

回答思路box-sizing控制元素宽高的计算方式。

取值

  • content-box(默认):宽度 = content宽度,padding和border额外增加
  • border-box:宽度 = content + padding + border,padding和border内缩
css 复制代码
/* 示例 */
.box1 {
  width: 200px;
  padding: 20px;
  box-sizing: content-box; /* 实际宽度240px */
}
.box2 {
  width: 200px;
  padding: 20px;
  box-sizing: border-box;  /* 实际宽度200px */
}

使用建议 :全局设置* { box-sizing: border-box; },布局计算更直观。


二、判断obj是否为空对象

回答思路:空对象指没有自身可枚举属性。

javascript 复制代码
// 方法1:Object.keys()(最常用)
function isEmpty(obj) {
  return Object.keys(obj).length === 0
}

// 方法2:JSON.stringify()
JSON.stringify(obj) === '{}'

// 方法3:for...in + hasOwnProperty
function isEmpty(obj) {
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) return false
  }
  return true
}

// 注意:null/undefined需先判空
function isEmpty(obj) {
  if (obj == null) return true
  return Object.keys(obj).length === 0
}

三、判断3==true

答案false

原因==会进行类型转换,但true转换为数字13 == 1false

javascript 复制代码
3 == true   // false(true → 1)
1 == true   // true(1 == 1)
0 == false  // true(0 == 0)
'3' == 3    // true(字符串转数字)

扩展 :严格相等===不进行类型转换,3 === truefalse


四、小数四舍五入,3.335 → 3.34

回答思路 :JS浮点数精度问题,直接toFixed可能不准确。

javascript 复制代码
// 方法1:Math.round + 乘除(注意精度)
function round(num, decimals = 2) {
  const factor = Math.pow(10, decimals)
  return Math.round(num * factor + 1e-10) / factor
  // +1e-10 解决浮点数精度问题,如 3.335 * 100 = 333.4999999
}
console.log(round(3.335, 2)) // 3.34

// 方法2:toFixed + 修正(不推荐,有精度问题)
// 3.335.toFixed(2) 在某些环境下可能输出 '3.33'

// 方法3:使用Number.EPSILON
function round(num, decimals = 2) {
  const factor = Math.pow(10, decimals)
  return Math.round((num + Number.EPSILON) * factor) / factor
}

原理 :3.335在二进制中是近似值,乘以100后得到333.499999...,导致Math.round向下取整。


五、反转字符串,"i am developer" → "developer am i"

题目:单词顺序反转,不是字符反转。

javascript 复制代码
function reverseWords(str) {
  return str.split(' ').reverse().join(' ')
}

// 处理多个空格的情况(保留一个空格)
function reverseWordsAdvanced(str) {
  return str.trim().split(/\s+/).reverse().join(' ')
}

console.log(reverseWords('i am developer'))  // "developer am i"

六、闭包程序输出

题目代码

javascript 复制代码
var a = 8;
function output() {
  (function () {
    return function inner(){
      var a = 10;
      a++;
      console.log(a);
    }
  })()();
}
output();
output();

逐步解析

  1. 外层output函数执行时,内部是一个立即执行函数表达式(IIFE)
  2. IIFE返回inner函数,然后立即调用 (末尾的()
  3. inner函数内部声明了局部变量var a = 10,然后a++变为11
  4. 这个ainner内部的局部变量,与外层的var a = 8无关(作用域隔离)
  5. 每次调用output(),都会重新执行IIFE,重新创建inner函数并调用

输出 :两次都是11

javascript 复制代码
// 执行流程
output()  // inner执行:var a = 10; a++ → a = 11; console.log(11)
output()  // 完全独立的新执行:var a = 10; a++ → a = 11; console.log(11)

常见陷阱 :如果inner中没有var a = 10,则会向外层查找,访问外层的var a = 8并修改它(形成闭包)。


七、文字截断样式(单行/多行)

单行截断

css 复制代码
.ellipsis {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

多行截断(WebKit)

css 复制代码
.multi-ellipsis {
  display: -webkit-box;
  -webkit-line-clamp: 3;    /* 显示行数 */
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

多行截断(通用方案)

css 复制代码
/* 使用max-height + 伪元素渐变遮罩 */
.multi-ellipsis-fallback {
  max-height: 4.5em;        /* line-height * 行数 */
  overflow: hidden;
  position: relative;
}
.multi-ellipsis-fallback:after {
  content: '...';
  position: absolute;
  bottom: 0;
  right: 0;
  background: linear-gradient(to right, transparent, white);
}

八、三列响应式布局

方案1:Flexbox

css 复制代码
.container {
  display: flex;
  flex-wrap: wrap;
}
.column {
  flex: 1;
  min-width: 200px;  /* 最小宽度,小于则换行 */
}

方案2:Grid

css 复制代码
.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

方案3:浮动(传统)

css 复制代码
.column {
  float: left;
  width: 33.33%;
}
@media (max-width: 600px) {
  .column { width: 100%; }
}

九、防抖

javascript 复制代码
function debounce(fn, delay) {
  let timer = null
  return function(...args) {
    clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

// 使用示例
const debouncedSearch = debounce((keyword) => {
  console.log('搜索:', keyword)
}, 500)

十、数组对象处理:去掉分数最大最小值后取平均值

题目 :数组包含10个对象,每个对象有name(字符串)和scores(分数数组),要求先去掉分数数组中的最大值和最小值,然后计算平均值。

javascript 复制代码
// 示例数据结构
const students = [
  { name: '张三', scores: [85, 90, 78, 92, 88] },
  { name: '李四', scores: [75, 82, 95, 88, 79] },
  // ... 共10个
]

// 处理函数
function processScores(students) {
  return students.map(student => {
    const scores = student.scores
    if (!scores || scores.length <= 2) {
      // 如果分数太少,无法去除最大最小值
      return { ...student, average: null, originalScores: scores }
    }
    
    // 方法1:排序后去掉首尾
    const sorted = [...scores].sort((a, b) => a - b)
    const trimmed = sorted.slice(1, -1)  // 去掉最小和最大
    const average = trimmed.reduce((sum, s) => sum + s, 0) / trimmed.length
    
    // 方法2:不排序,找到最大最小值(O(n))
    // 适合大数据量场景
    
    return {
      ...student,
      trimmedScores: trimmed,
      average: Math.round(average * 100) / 100  // 保留两位小数
    }
  })
}

// 使用
const result = processScores(students)
console.log(result)

完整示例

javascript 复制代码
const students = [
  { name: '张三', scores: [85, 90, 78, 92, 88] },
  { name: '李四', scores: [75, 82, 95, 88, 79] },
  { name: '王五', scores: [90, 85, 80, 95, 100] },
  // ... 共10个
]

const processed = students.map(({ name, scores }) => {
  const sorted = [...scores].sort((a, b) => a - b)
  const trimmed = sorted.slice(1, -1)
  const avg = trimmed.reduce((a, b) => a + b, 0) / trimmed.length
  return { name, originalScores: scores, average: avg.toFixed(2) }
})

console.log(processed)
// 输出: { name: '张三', originalScores: [...], average: '86.50' }

注意边界

  • 分数数组长度 ≤2 时无法去除最大最小值
  • 多个人分数相同时,只去除一个最大值和一个最小值

📚 知识点速查表

知识点 核心要点
box-sizing content-box(默认,宽不含padding/border) / border-box(宽含padding/border)
对象判空 Object.keys(obj).length === 0,需先判null
类型转换 3 == true3 == 1 → false
小数精度 0.1+0.2 !== 0.3,使用Math.round(num*100)/100Number.EPSILON
单词反转 str.split(' ').reverse().join(' ')
闭包输出 分析作用域,注意IIFE和内部变量作用域
文字截断 单行text-overflow: ellipsis,多行-webkit-line-clamp
三列响应式 Flex flex:1、Grid auto-fit、浮动+媒体查询
防抖 清除上次timer,延迟执行
数组处理 排序sort → 切片slice → 累加reduce → 平均值

📌 最后一句:

秦丝科技这场笔试,是一份"小而全"的基础摸底试卷。从CSS的box-sizing到JS的闭包输出,从浮点数精度到数组对象处理,每一题都在考察前端工程师的基本功是否扎实 。没有偏题怪题,但第6题的闭包和第4题的精度问题,很容易踩坑。基础不牢,地动山摇------笔试过关,靠的不是运气,而是日积月累的代码手感。

相关推荐
喜欢吃鱿鱼2 小时前
VUE项目 弹窗改为页面供其他项目嵌入iframe - 截取地址栏URL中的参数
前端·javascript·vue.js
无心使然云中漫步2 小时前
Openlayers调用ArcGis地图服务之二 —— 动态地图(/export)
前端·arcgis·vue·数据可视化
Chengbei112 小时前
全新开源 Burp AI 扫描插件、支持 17 类 Web检测,自带 WAF 绕过,一键自动化挖掘并智能验证
前端·人工智能·自动化
爱宇阳2 小时前
HTML头部元信息避坑指南
前端·html
ZC跨境爬虫2 小时前
UI前端美化技能提升日志day6:(使用苹果字体+计算样式对比差异)
前端·javascript·css·ui·状态模式
胡志辉的博客2 小时前
前端反调试:常见套路、识别方法与绕过思路
前端·javascript·web安全·状态模式·安全威胁分析·代码混淆
牛奶2 小时前
老板问我接口设计,我甩给他一个文档
前端·restful·graphql
gskyi2 小时前
uni-app 高阶实战:onLoad与getCurrentPages深度技巧
前端·javascript·vue.js·uni-app
月明水寒2 小时前
IDEA2026.1 vue文件报错
前端·javascript·vue.js·intellij-idea·idea·intellij idea