当前位置: 首页 > news >正文

前端 拼多多4399笔试题目

拼多多

3 选择题

  1. opacity|visibity|display区别
    在CSS中,opacity: 0visibility: hidden 都可以让元素不可见,但它们的行为不同

opacity: 0(透明度为0)

  • 元素仍然占据空间(不移除文档流)
  • 元素可以被交互(例如仍然能点击,除非配合 pointer-events: none
  • 元素可通过动画慢慢变回可见

📌 元素是“看不见的”但仍在页面上


visibility: hidden

  • 元素仍然占据空间
  • 元素不可被交互(鼠标点击不到)
  • 通常用于暂时隐藏,但仍保留布局

📌 元素是“不可见的”而且“不可交互的”


哪个“会显示”?

  • 两个都不会显示元素(肉眼看不见)
  • 但如果你问“哪个会被点击 / 可以响应事件”,opacity: 0 的元素仍然可响应点击事件(默认),而 visibility: hidden 的不行。

补充比较:

属性占位可点击动画支持常见用途
opacity: 0淡入淡出、过渡动画
visibility: hidden一般控制可见性但保留布局

如果你还想知道和 display: none 的对比,也可以告诉我。

  1. 浏览器渲染流程
    是的,从 www.sitecom 页面中通过 <link> 标签加载 csdn.css(假设来自 CSDN 域名,如 https://csdn.net/style/csdn.css),属于跨域资源加载,是否会触发限制取决于资源的类型和浏览器规则:

结论:不会触发 CORS 跨域限制,但可能被 CSP 限制

加载方式是否跨域是否需要 CORS是否容易被拦截
<link rel="stylesheet" href="https://csdn.net/style/csdn.css">✅ 是❌ 不需要 CORS⚠️ 可能被 CSP 或平台策略限制

🔍 详细解释:

1. CSS 是“非简单请求”,但不需要 CORS

  • 加载 CSS 文件不会触发浏览器的 CORS 机制(即不会检查 Access-Control-Allow-Origin)。
  • CSS、图片、JS 文件通过 <link><img><script> 加载时,浏览器默认允许跨域加载资源,只要资源本身能被正常访问。

🔸 所以 只要 CSDN 那个 CSS 地址是公开的、状态码为 200,浏览器就会加载它,不会报 CORS 错误。


2. 可能会被 CSP(Content Security Policy)限制

如果你在 www.sitecom 设置了 CSP(内容安全策略):

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self'">

那就只能加载本站点的 CSS,CSDN 的外链就会被拦截,控制台会报 CSP 相关的错误。

✅ 若你需要允许 CSDN 资源,需要在 CSP 中加上:

<style-src 'self' https://csdn.net;

3. 浏览器和平台限制(可能导致问题)

  • 浏览器隐私策略或插件:部分插件或隐私增强浏览器可能拦截外部资源。
  • CDN 限制:CSDN 的 CDN 可能不允许“站外调用”(Referrer 检查或 token 限制),返回 403。
  • 移动端容器或小程序:某些平台(如 WebView、快应用、小程序)限制外链样式表加载,尤其是非 https 的。

✅ 总结

你在 www.sitecom 页面中加载 https://csdn.net/style/csdn.css

  • 不会触发 CORS 错误
  • 可能被 CSP 策略拦截(如有配置)
  • 可能被目标站点拒绝服务(如有防盗链)
  • 推荐方式:若必须使用,最好将 CSDN 的 CSS 下载后自行托管,避免未来不可控问题。

需要我帮你检查具体 CSS 链接是否可访问或如何托管在本地吗?

  1. 计算机网络相关内容
    使用 https 可以增强安全性,但它

⚠️ 不能完全预防 XSS 和 CSRF 攻击。


✅ HTTPS 的作用是:

  • 加密传输内容(防止被中间人窃听或篡改)
  • 验证服务端身份(防止中间人伪装网站)
  • 防止会话被劫持(如Cookie被拦截)

❌ HTTPS 无法直接防御以下攻击:

1. XSS(跨站脚本攻击)

  • 原理:攻击者将恶意脚本注入页面(如用户输入没被过滤)

  • HTTPS 无法阻止恶意脚本执行

  • 防御方式

    • 输入/输出过滤(如 HTML escape)
    • 设置 CSP(Content Security Policy)
    • 禁用内联脚本、eval() 等危险特性

2. CSRF(跨站请求伪造)

  • 原理:用户登录后被诱导访问恶意链接,对目标站点执行操作(如伪造请求)

  • HTTPS 无法阻止攻击者诱导用户发送请求

  • 防御方式

    • 使用 CSRF Token 验证请求来源
    • 设置 SameSite Cookie 策略(如 SameSite=LaxStrict
    • 验证 Referer / Origin 头

✅ HTTPS + XSS/CSRF 防护措施 = 安全基础

类型HTTPS是否有效真正防护方式
XSS❌ 无效输入/输出过滤、CSP
CSRF❌ 无效CSRF Token、SameSite Cookie
中间人✅ 有效HTTPS 加密、防止劫持
会话劫持✅ 有效HTTPS + HttpOnly/SameSite Cookie

🟢 最佳实践:

  1. 始终使用 HTTPS(含子域名)
  2. 开启 HttpOnlySecureSameSite Cookie
  3. 使用 CSP 头防御 XSS
  4. 使用 CSRF Token 机制防御伪造请求
  5. 输入内容做过滤和转义

如你需要,我可以帮你配置一套完整的 HTTP 安全响应头(CSP、HSTS、X-Frame-Options 等)或演示如何防御 XSS/CSRF。要吗?


3代码题(问答题)

只能说没有环境,纯纯手写,也不知道写没写对,难道还要HR看?很困惑

1. 实现16进制的数的和(含大数)

function hexAddBig(hex1, hex2) {// 将十六进制字符串加上 '0x' 前缀,转换为 BigIntconst num1 = BigInt('0x' + hex1);const num2 = BigInt('0x' + hex2);// 相加并转换为十六进制大写字符串const result = (num1 + num2).toString(16).toUpperCase();return result;
}// 示例
console.log(hexAddBig("FFFFFFFFFFFFFFFF", "1")); // 输出:10000000000000000

2. 实现Git类(根据需求写一个类)

明白了,你希望 `log()` 只显示已经 `push()` 过的提交记录。我帮你改下代码,`push()` 会把当前所有提交标记为已推送,`log()` 只打印这些已推送的提交。---```javascript
class Git {constructor(repoName) {this.repo = repoName || "unnamed-repo";this._commits = [];this._pushedCommits = [];}commit(message, time) {if (!message) {console.warn(`[${this.repo}] Commit message is required.`);return this;}this._commits.push({message,timestamp: time || new Date().toISOString(),});return this;}push() {if (this._commits.length === 0) {console.log(`[${this.repo}] Nothing to push.`);} else {// 把当前未推送的提交都移到 _pushedCommitsthis._pushedCommits.push(...this._commits);this._commits = [];console.log(`[${this.repo}] Pushed ${this._pushedCommits.length} commit(s).`);}return this;}log() {if (this._pushedCommits.length === 0) {console.log(`[${this.repo}] No pushed commits yet.`);} else {this._pushedCommits.forEach(({ message, timestamp }) => {console.log(`${this.repo} ${timestamp} ${message}`);});}return this;}static init(repoName) {return new Git(repoName);}
}

使用示例:

const git = Git.init("my-repo");git.commit("init commit").commit("fix bug").log(); // 这里不会打印任何内容,因为还没 pushgit.push().log(); // 这里会打印之前 push 的提交git.commit("new feature").log(); // 还是只打印 push 过的提交,不包含新提交git.push().log(); // 打印所有 push 过的提交,包括新 feature

这样逻辑是:

  • commit() 新提交存储在 _commits
  • push()_commits 全部移动到 _pushedCommits,代表已经推送过
  • log() 只打印 _pushedCommits

3. 基于Promise实现应用场景(接力棒赛跑)


目标回顾

你有一个 teamsConfig,结构是:

{team1: [runnerFn1, runnerFn2, ...],team2: [runnerFn1, runnerFn2, ...],...
}

每个 runnerFn 是一个返回 Promise 的函数,表示该运动员跑完后异步完成。

你希望:

  • 所有队伍的第一个运动员同时开始跑
  • 同一队伍的运动员必须一个接一个跑完,串行执行
  • 所有队伍的最后一个运动员跑完后,根据耗时排序,输出排名

代码

function relayRace(teamsConfig) {var results = [];           // 用来保存每个队伍的完成时间和队名var finishedCount = 0;      // 记录已经完成的队伍数var teamNames = Object.keys(teamsConfig);  // ['team1', 'team2', ...]return new Promise(function (resolve) {// 遍历所有队伍teamNames.forEach(function (teamName) {var team = teamsConfig[teamName];  // 该队伍运动员数组var startTime = Date.now();         // 记录队伍起跑时间// 定义一个递归函数,用于串行执行队伍中的运动员function runRunner(i) {if (i >= team.length) {// 运动员全部跑完,计算耗时var duration = Date.now() - startTime;// 保存结果,包含队伍名和耗时results.push({ teamName: teamName, duration: duration });finishedCount++;   // 完成队伍数量加1// 如果所有队伍都跑完了,排序并返回结果if (finishedCount === teamNames.length) {// 按耗时升序排序,耗时少的排在前面results.sort(function (a, b) {return a.duration - b.duration;});// 结束 Promise,返回排序后的结果resolve(results);}return;  // 结束该队伍递归}// 当前运动员跑步,返回 Promisevar runner = team[i];runner().then(function () {// 当前运动员跑完后,递归调用执行下一个运动员runRunner(i + 1);});}// 开始执行第一个运动员,所有队伍第一个运动员会同时触发runRunner(0);});});
}

详细解释

1. 为什么用 Object.keys

teamsConfig 是对象,不是数组。我们要拿到队伍名称列表:

var teamNames = Object.keys(teamsConfig);

这样我们能遍历每个队伍,知道“哪个队伍”对应哪个运动员数组。


2. 为什么用 Promise

整个比赛是异步的,要等所有队伍跑完才能得到最终排名,所以用 Promise 来包装,方便外面用 .then() 获取结果。


3. 为什么递归 runRunner(i)

同一队伍运动员必须一个接一个跑,不能同时跑。调用第 i 个运动员函数得到一个 Promise,跑完后才跑 i+1。

递归写法:

  • 如果 i >= team.length,说明跑完了
  • 否则 runner[i]() 返回 Promise,跑完后递归跑下一个

这样保证串行执行。


4. 为什么 finishedCount

我们有多个队伍同时比赛,forEach 启动所有队伍跑步。

需要知道什么时候所有队伍都完成,才能排序输出结果。

finishedCount 就是计数器,每当一个队伍跑完(递归结束时)就加一。

当等于队伍总数时,就调用 resolve,通知外面跑完了。


5. 为什么每个队伍用自己的 startTime

题目要求:

  • 所有队伍的第一个运动员同时开始
  • 记录的是每个队伍自己的耗时

我们在 forEach 循环里对每个队伍分别调用 Date.now(),开始时间就是该队伍第一个运动员实际开始的时刻。

因为是并行启动的,这样自然符合“同时开始”的要求。


6. 排序和输出

比赛结束后,把 results 按耗时排序:

results.sort(function (a, b) {return a.duration - b.duration;
});

耗时越少排名越靠前。


7. 如何使用?

你需要传入格式是:

{team1: [runnerFn, runnerFn, ...],team2: [runnerFn, runnerFn, ...],...
}

每个 runnerFn 是一个返回 Promise 的函数,表示运动员跑步异步完成。


示例代码

function createRunner(name, time) {return function () {return new Promise(function (resolve) {console.log(name + " start running");setTimeout(function () {console.log(name + " finished running");resolve();}, time);});};
}var teamsConfig = {team1: [createRunner("Team1-Runner1", 1000), createRunner("Team1-Runner2", 800)],team2: [createRunner("Team2-Runner1", 900), createRunner("Team2-Runner2", 1200)],team3: [createRunner("Team3-Runner1", 1100), createRunner("Team3-Runner2", 700)],
};relayRace(teamsConfig).then(function (rankings) {console.log("Race finished! Rankings:");rankings.forEach(function (res, i) {console.log("#" + (i + 1) + " " + res.teamName + " - Time: " + res.duration + "ms");});
});

总结

  • 使用 Object.keys 遍历队伍名,遍历对象
  • 用递归函数串行执行队伍中运动员
  • 用计数器判断所有队伍完成
  • 结果排序输出,给出排名

这样实现没有用 async/await 和 generator,逻辑清晰,符合题目要求。


如果你需要我帮你写注释版代码,或者进一步改进(比如加超时检测、错误处理),告诉我!


4399

10选择题目

在这里插入图片描述

3个简答题目

1.XSS攻击

在这里插入图片描述

0.1+0.2等于0.3吗

在这里插入图片描述

3个编程题目

1. HTML/CSS基础题目,基于Flex布局实现一个卡片布局

你发的内容是一个数字串:0272700。请问你想了解或操作它的什么方面?以下是几种可能的解释方向,你可以确认一下你的意图:


🧾 可能的理解方式:

类型解释
📦 条形码或产品编号可能是商品、仓库或物流中的 SKU 编号(可能需要查数据库或系统)
🏢 公司代码(如韩国)可能是股票代码,比如韩国证券交易所(KRX)中 三星电机 的股票代码是 027270,你写的是 0272700,可能多了一个 0。需确认。
🔢 数值或编码含义可能是你在做编程、算法题中用到的值,或者某种内部 ID(比如用户编号)
🧪 作为输入测试数据也可能是你用于测试输入框、校验、正则等功能的字符串
❓ 手滑或误输入有时是误发的内容,你可直接说明你想做什么

🧭 如果你能补充:

  • 你是在哪看到的这个数字?
  • 想查什么?(比如含义、归属、正则、格式处理?)
  • 是用于前端输入、JS 脚本、接口测试等吗?

我就能更准确地帮你分析或写代码。欢迎补充上下文。

2. 实现一个类

下面是一个基于 ES6+ 实现的 AsyncBatcher 类,支持以下功能:

✅ 功能要求实现

  • 构造函数支持 batchSizedelay(单位 ms)
  • addTask(task) 方法:添加异步任务(是个函数,返回 Promise)
  • 任务将在达到批大小或延迟后批量执行
  • flush() 方法:立即执行当前批次所有等待任务
  • 每个 addTask 返回的 Promise 可拿到对应任务的结果

✅ 实现代码

class AsyncBatcher {constructor(batchSize, delay) {this.batchSize = batchSize;this.delay = delay;this.queue = [];this.timer = null;}addTask(taskFn) {return new Promise((resolve, reject) => {this.queue.push({ taskFn, resolve, reject });if (this.queue.length === 1) {// 启动延迟定时器this.timer = setTimeout(() => this._runBatch(), this.delay);}if (this.queue.length >= this.batchSize) {this._runBatch();}});}flush() {if (this.queue.length > 0) {this._runBatch();}}async _runBatch() {clearTimeout(this.timer);this.timer = null;const currentBatch = this.queue.splice(0, this.batchSize);await Promise.all(currentBatch.map(async ({ taskFn, resolve, reject }) => {try {const result = await taskFn();resolve(result);} catch (err) {reject(err);}}));}
}

✅ 使用示例

const batcher = new AsyncBatcher(3, 2000);// 模拟异步任务
const createTask = (id) => () =>new Promise((res) => {setTimeout(() => res(`任务 ${id} 完成`), 500);});batcher.addTask(createTask(1)).then(console.log);
batcher.addTask(createTask(2)).then(console.log);
batcher.addTask(createTask(3)).then(console.log); // 达到 batchSize,会立即执行
batcher.addTask(createTask(4)).then(console.log); // 新一批等待 delay 或手动 flushsetTimeout(() => {batcher.flush(); // 手动触发剩余任务
}, 1000);

🧠 注意点

  • 所有任务执行都是并发的(Promise.all
  • 如果任务数没满,但超时到了,也会触发
  • flush() 可随时让队列中的任务立即执行
  • 若需要支持自定义批处理逻辑(例如任务之间组合处理),可额外传入一个批处理器函数

如果你需要:

  • 限制并发数(如批任务内部并发上限)
  • 允许添加回调(batch 完成后通知)
  • 支持取消 pending 的任务

我也可以帮你扩展这一类。是否需要增强版?

3. 回溯遍历一个vDOM,获得所有路径

你问得很对!**使用回溯(Backtracking)**思路确实更清晰、更符合“路径查找”的语义,尤其在以下情况:

  • 你想找出所有从根到目标节点的路径
  • 你想在遍历中动态构建路径、尝试、撤销
  • 你希望未来支持提前剪枝、多个目标匹配、路径过滤等功能

✅ 回溯解法本质上就是 DFS + 路径数组动态维护:

相比 DFS 用 newPath = [...path, name]回溯更高效,因为它在一个数组上操作,并在每次递归后“回退”一步,避免复制数组。


✅ 回溯实现版本(更接近真实算法语义)

function findComponentPaths(vNode, targetComponent) {const results = [];const path = [];function backtrack(node) {if (!node || typeof node !== 'object') return;const name =typeof node.type === 'string'? node.type: node.type?.name || 'Anonymous';path.push(name);const isMatch =typeof targetComponent === 'string'? name === targetComponent: node.type === targetComponent;if (isMatch) {results.push([...path]); // 必须复制,否则后面修改 path 会影响已存路径}const children = node.children || [];const list = Array.isArray(children) ? children : [children];for (const child of list) {backtrack(child);}path.pop(); // 回退一步}backtrack(vNode);return results;
}

✅ 回溯相比 DFS + 拷贝的优势

比较点DFS 复制路径回溯方式(path 共享 + pop)
内存消耗每步都复制 pathpath 一条,只在 push/pop
表达意图逻辑能通但略啰嗦更贴近“探索 -> 撤销”的语义
扩展剪枝能力略繁琐可随时加 if 控制递归/剪枝
性能多次 path.slice() 复制低复制开销,更适合大树

✅ 示例输入再次验证

const tree = {type: 'App',children: [{type: 'Layout',children: [{ type: 'Sidebar' },{type: 'Content',children: [{ type: 'Sidebar' }]}]}]
};console.log(findComponentPaths(tree, 'Sidebar'));
// 输出:
// [
//   ['App', 'Layout', 'Sidebar'],
//   ['App', 'Layout', 'Content', 'Sidebar']
// ]

🧠 总结

  • 回溯方式更适合路径类搜索问题

  • ✅ 代码更高效、优雅、语义化

  • 如果你想未来加入:

    • 匹配多个目标组件
    • 限制最大路径长度
    • 路径过滤条件
    • 找到一个路径就返回(如 DFS 找最近)

那回溯结构更便于扩展。

需要我进一步加上“匹配多个组件”、“路径包含某关键字的路径”、“目标只找第一个”等扩展功能吗?

http://www.lryc.cn/news/608895.html

相关文章:

  • RabbitMQ面试精讲 Day 8:死信队列与延迟队列实现
  • 数据分析—numpy库
  • JS逆向 - (国外)川航 - Reese84(cookie)
  • Mongo索引
  • git相关配置问题汇总
  • Linux 文件与目录操作详解
  • 从Docker衔接到导入黑马商城以及前端登录显示用户或密码错误的相关总结(个人理解,仅供参考)
  • PyTorch生成式人工智能(24)——使用PyTorch构建Transformer模型
  • accept4系统调用及示例
  • ABP VNext + CloudEvents:事件驱动微服务互操作性
  • 数据治理:DQC(Data Quality Center,数据质量中心)概述
  • [每周一更]-(第153期):**PDF终极防护指南:命令行全栈加密+一键权限锁死实战(附脚本模板)**
  • Docker--解决x509: certificate signed by unknown authority
  • 医院课题管理全动态流程 (AI-Enhanced, Data-Driven Research Lifecycle)
  • JAVA中的String类方法介绍
  • 基于transformer的目标检测——匈牙利匹配算法
  • 【Excel】利用函数和Power Query进行数据分析
  • 基于Matlab的深度学习智能行人检测与统计系统
  • Java企业级应用性能优化实战
  • 2025年人工智能十大趋势 - 基础模型的跃迁
  • 达梦数据库联机备份和脱机备份的区别
  • C++ 入门基础(3)
  • 自私挖矿攻击
  • C++引用:高效安全的别名机制详解
  • RPG增容3:尝试使用MVC结构搭建玩家升级UI(一)
  • Claude Code入门学习笔记(四)--Claude Code的使用
  • [硬件电路-150]:数字电路 - 数字电路与模拟电路的异同
  • 志邦家居PMO负责人李蓉蓉受邀为PMO大会主持人
  • Rust:开发 DLL 动态链接库时如何处理 C 字符串
  • 2025-0803学习记录21——地表分类产品的精度验证