阅读视图
面试官 : “ 说一下 Map 和 WeakMap 的区别 ? ”
面试官 : “ 说一下 localhost 和127.0.0.1 的区别 ? ”
localhost 是主机名(域名) ,属于应用层概念;
127.0.0.1 是IPv4 回环地址,属于网络层概念。
两者都用于访问本机服务,但 localhost 必须通过解析才能映射到具体 IP(默认是 127.0.0.1 或 IPv6 的 ::1),而 127.0.0.1 是直接的网络层标识,无需解析。
一、本质定义与协议层次
| 概念 | localhost |
127.0.0.1 |
|---|---|---|
| 本质 | 互联网标准规定的特殊主机名(RFC 6761 定义) | IPv4 协议规定的回环地址(RFC 5735 定义) |
| 协议层次 | 应用层(DNS 协议解析范畴) | 网络层(IP 协议寻址范畴) |
| 归属 | 属于域名系统(DNS) | 属于 IP 地址体系 |
| 默认映射 | IPv4: 127.0.0.1;IPv6: ::1
|
仅 IPv4 回环网段(127.0.0.0/8)的第一个地址 |
关键补充
-
127.0.0.0/8网段:不只是127.0.0.1,整个127.x.x.x网段(共 16777216 个地址)都属于回环地址,访问任何一个都会指向本机。 -
localhost的特殊性:它是一个保留主机名,不能被注册为公共域名,且操作系统会优先通过hosts文件解析,而非公共 DNS 服务器。
二、解析流程的根本差异
这是两者最核心的区别 ——是否需要解析,以及解析的顺序。
1. localhost 的解析流程(应用层 → 网络层)
当你在浏览器输入 http://localhost:3000 时,操作系统会执行以下步骤:
-
检查本地
hosts文件- Windows 路径:
C:\Windows\System32\drivers\etc\hosts - Linux/macOS 路径:
/etc/hosts - 如果
hosts文件中有如下映射:127.0.0.1 localhost或::1 localhost,则直接使用对应的 IP。
- Windows 路径:
-
若
hosts文件无映射,查询本地 DNS 缓存- 操作系统会检查之前是否解析过
localhost,若有缓存则直接使用。
- 操作系统会检查之前是否解析过
-
若缓存无结果,查询本地 DNS 服务器
- 但由于
localhost是保留主机名,公共 DNS 服务器通常也会返回127.0.0.1或::1。
- 但由于
-
解析完成后,转换为 IP 地址进行网络请求
- 此时才进入网络层,使用解析后的 IP 连接本机服务。
2. 127.0.0.1 的访问流程(直接进入网络层)
当你输入 http://127.0.0.1:3000 时,跳过所有解析步骤:
- 操作系统直接识别这是一个 IPv4 回环地址。
- 直接将网络请求发送到本机的网络接口(回环接口,
lo接口)。 - 目标服务监听
127.0.0.1或0.0.0.0时,即可响应请求。
三、功能与使用上的具体差异
1. 协议支持差异
-
localhost:支持 IPv4 和 IPv6 双协议。- 若你的系统开启了 IPv6,
localhost可能优先解析为::1(IPv6 回环地址)。 - 例如:在 Node.js 中,
server.listen(3000, 'localhost')会同时监听 IPv4 的127.0.0.1:3000和 IPv6 的::1:3000。
- 若你的系统开启了 IPv6,
-
127.0.0.1:仅支持 IPv4。- 无论系统是否开启 IPv6,使用
127.0.0.1都只会走 IPv4 协议。 - 例如:
server.listen(3000, '127.0.0.1')仅监听 IPv4 地址。
- 无论系统是否开启 IPv6,使用
2. 性能差异
-
127.0.0.1略快:因为跳过了 DNS 解析流程(即使是本地hosts文件解析,也需要一次文件读取和匹配)。 - 差异极小:在开发环境中,这种性能差异几乎可以忽略不计,除非是高频次的请求(如每秒上万次)。
3. 服务监听的差异
服务端程序的监听地址,会影响是否能被 localhost 或 127.0.0.1 访问:
| 监听地址 | 能否被 localhost 访问 |
能否被 127.0.0.1 访问 |
能否被局域网其他设备访问 |
|---|---|---|---|
localhost |
✅ | ✅(IPv4 解析时) | ❌ |
127.0.0.1 |
✅(解析为 127.0.0.1 时) |
✅ | ❌ |
0.0.0.0 |
✅ | ✅ | ✅(通过本机局域网 IP) |
::1(IPv6) |
✅(解析为 ::1 时) |
❌ | ❌ |
4. 自定义映射的差异
-
localhost可以被自定义映射:-
你可以修改
hosts文件,将localhost映射到任意 IP,例如:192.168.1.100 localhost -
此时访问
localhost会指向局域网的192.168.1.100,而不是本机。
-
-
127.0.0.1无法被自定义:- 它是 IPv4 协议规定的回环地址,无论如何修改配置,访问
127.0.0.1都只会指向本机。
- 它是 IPv4 协议规定的回环地址,无论如何修改配置,访问
5. 兼容性差异
-
老旧系统 / 服务:某些非常古老的程序(如早期的 DOS 程序、嵌入式设备程序)可能不识别
localhost主机名,但一定能识别127.0.0.1。 -
IPv6 专属服务:某些服务仅监听 IPv6 的
::1,此时只能通过localhost访问(解析为::1),而127.0.0.1无法访问。
四、实际开发中的选择建议
-
优先使用
localhost- 理由:兼容性更好,支持双协议,符合开发习惯,且无需关心 IPv4/IPv6 配置。
- 场景:本地开发、测试环境、前端代理配置(如 Vite、Webpack 的
devServer.host: 'localhost')。
-
使用
127.0.0.1的场景- 强制使用 IPv4:当服务仅监听 IPv4 地址,或系统 IPv6 配置有问题时。
-
避免自定义映射:当你怀疑
hosts文件被修改,localhost被映射到非本机地址时。 -
某些工具的特殊要求:部分 CLI 工具或服务(如某些数据库客户端)默认只识别
127.0.0.1。
-
特殊场景:
0.0.0.0- 这不是回环地址,而是通配地址,表示监听本机所有网络接口(包括回环接口、局域网接口、公网接口)。
- 场景:需要让局域网其他设备访问本机服务时(如手机测试前端页面)。
五、验证两者差异的小实验
实验 1:修改 hosts 文件,观察 localhost 映射
- 打开
/etc/hosts(Linux/macOS)或C:\Windows\System32\drivers\etc\hosts(Windows)。 - 添加一行:
192.168.1.1 localhost。 - 执行
ping localhost,会发现 ping 的是192.168.1.1,而非127.0.0.1。 - 执行
ping 127.0.0.1,仍然 ping 本机。 - 恢复
hosts文件默认配置:127.0.0.1 localhost和::1 localhost。
实验 2:查看服务监听的地址
-
在 Node.js 中运行以下代码:
const http = require('http'); const server = http.createServer((req, res) => { res.end('Hello World!'); }); // 监听 localhost server.listen(3000, 'localhost', () => { console.log('Server running on localhost:3000'); }); -
执行
netstat -tulpn | grep 3000(Linux/macOS)或netstat -ano | findstr 3000(Windows)。 -
会发现服务同时监听
127.0.0.1:3000和::1:3000(IPv4 + IPv6)。 -
若将监听地址改为
127.0.0.1,则仅监听127.0.0.1:3000。
六、总结:核心区别一览表
| 对比维度 | localhost |
127.0.0.1 |
|---|---|---|
| 本质 | 主机名(域名) | IPv4 回环地址 |
| 协议层次 | 应用层(DNS) | 网络层(IP) |
| 解析需求 | 必须解析(hosts → DNS) | 无需解析 |
| 协议支持 | IPv4 + IPv6 | 仅 IPv4 |
| 自定义映射 | 可通过 hosts 文件修改 | 不可修改,固定指向本机 |
| 服务监听 | 可同时监听 IPv4/IPv6 | 仅监听 IPv4 |
| 兼容性 | 现代系统支持,老旧系统可能不支持 | 所有支持 IPv4 的系统都支持 |
| 性能 | 略慢(解析开销) | 略快(无解析开销) |
我是千寻, 这期内容到这里就结束了,我们有缘再会😂😂😂 !!!
面试官: “ 说一下怎么做到前端图片尺寸的响应式适配 ”
前端开发中,图片的尺寸适配是响应式设计的核心部分之一,需要结合图片类型、容器场景、设备特性来选择方案。以下是常见的图片尺寸策略和多窗口适配方法:
一、先明确:前端常用的图片尺寸场景
不同场景下,图片的 “合适尺寸” 差异很大:
| 场景 | 建议尺寸范围 | 示例 |
|---|---|---|
| 图标 / 小图标 | 24×24 ~ 128×128(2 倍图) | 按钮图标、头像缩略图 |
| 列表缩略图 | 300×200 ~ 600×400(2 倍图) | 商品列表、文章封面缩略图 |
| 详情页主图 | 800×600 ~ 1920×1080(2 倍图) | 商品详情图、Banner 图 |
| 背景图 | 1920×1080 ~ 3840×2160 | 全屏背景、页面 Banner |
| 移动端适配图 | 750×1334(2 倍图)、1242×2208(3 倍图) | 移动端页面元素图 |
二、多窗口适配的核心方法
1. 基础适配:max-width: 100%(通用)
最常用的适配方式,让图片不超过容器宽度,自动缩放高度:
img {
max-width: 100%; /* 图片宽度不超过父容器 */
height: auto; /* 高度自动按比例缩放,避免变形 */
}
✅ 适用场景:大部分内联图片、列表图、详情图。
2. 背景图适配:background-size
针对背景图,通过 CSS 属性控制缩放逻辑:
.bg-img {
width: 100%;
height: 300px;
background: url("bg.jpg") center/cover no-repeat;
/* 或单独设置: */
background-size: cover; /* 覆盖容器,可能裁剪 */
/* background-size: contain; 完整显示,可能留白 */
}
-
cover:优先覆盖容器,保持比例(常用全屏背景); -
contain:优先完整显示,保持比例(常用图标背景)。
3. 响应式图片:srcset + sizes(精准加载)
让浏览器根据设备尺寸 / 像素比,自动选择合适的图片(减少加载体积):
<img
src="img-800.jpg" <!-- 默认图 -->
srcset="
img-400.jpg 400w, <!-- 400px宽的图 -->
img-800.jpg 800w, <!-- 800px宽的图 -->
img-1200.jpg 1200w <!-- 1200px宽的图 -->
"
sizes="(max-width: 600px) 400px, 800px" <!-- 告诉浏览器容器宽度 -->
alt="响应式图片"
>
✅ 适用场景:对加载性能要求高的大图(如 Banner、详情主图)。
4. 移动端高清图:2 倍图 / 3 倍图
针对 Retina 屏,提供高分辨率图,避免模糊:
<!-- 方法1:srcset 按像素比适配 -->
<img
src="img@2x.png"
srcset="
img@1x.png 1x, <!-- 普通屏 -->
img@2x.png 2x, <!-- Retina屏 -->
img@3x.png 3x <!-- 超高清屏 -->
"
alt="高清图"
>
<!-- 方法2:CSS 背景图(针对图标) -->
.icon {
background: url("icon@2x.png") no-repeat;
background-size: 24px 24px; /* 实际显示尺寸是24×24,图片是48×48 */
width: 24px;
height: 24px;
}
5. 容器限制:object-fit(控制图片在容器内的显示方式)
当图片宽高比与容器不一致时,避免变形:
.img-container {
width: 300px;
height: 300px;
overflow: hidden;
}
.img-container img {
width: 100%;
height: 100%;
object-fit: cover; /* 覆盖容器,裁剪多余部分(常用头像、卡片图) */
/* object-fit: contain; 完整显示,留白 */
/* object-fit: fill; 拉伸变形(不推荐) */
}
6. 媒体查询:针对特定窗口尺寸切换图片
强制在不同屏幕下使用不同图片(适合差异较大的场景):
/* 移动端用小图 */
@media (max-width: 768px) {
.banner {
background-image: url("banner-mobile.jpg");
}
}
/* 桌面端用大图 */
@media (min-width: 769px) {
.banner {
background-image: url("banner-desktop.jpg");
}
}
三、总结适配思路
-
优先用
max-width: 100% + height: auto:覆盖 80% 的基础场景; -
背景图用
background-size: cover/contain; -
大图用
srcset + sizes:兼顾性能和清晰度; -
固定容器用
object-fit:避免图片变形; - 移动端用 2 倍 / 3 倍图:保证高清显示。
面试官: “ 请你讲一下 package.json 文件 ? ”
1. package.json 的作用
package.json 是 Node.js/npm 项目的核心配置文件,位于项目根目录,它的作用包括:
- 描述项目信息:名称、版本、作者、许可证等。
-
声明依赖:项目运行所需的包(
dependencies)和开发所需的包(devDependencies)。 -
定义脚本命令:通过
scripts字段,让你可以用npm run执行自定义任务(如启动、测试、构建)。 - 指定元数据:比如入口文件、浏览器兼容性等。
2. 基本结构示例
一个典型的 package.json 可能如下:
{
"name": "my-project",
"version": "1.0.0",
"description": "A sample Node.js project",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "jest",
"build": "webpack"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"jest": "^29.7.0",
"webpack": "^5.89.0"
},
"author": "Your Name",
"license": "MIT",
"keywords": ["node", "express", "example"]
}
3. 核心字段说明
3.1 项目信息字段
-
name:项目名称(必须小写,无空格)。 -
version:项目版本,遵循 SemVer(语义化版本),格式为x.y.z(主版本。次版本。补丁版本)。 -
description:项目的简短描述。 -
author:作者信息,可以是字符串或对象(如{"name": "xxx", "email": "xxx"})。 -
license:开源许可证类型(如MIT、ISC、GPL)。 -
keywords:项目关键字数组,方便在 npm 上搜索。
3.2 入口与配置字段
-
main:指定项目的入口文件(默认是index.js)。 -
type:指定模块系统类型:-
"commonjs"(默认):使用require()导入。 -
"module":使用import/export语法。
-
-
files:发布到 npm 时需要包含的文件或目录。 -
repository:项目代码仓库地址。
3.3 依赖字段
-
dependencies:生产环境依赖(项目运行时必需的包),例如:"dependencies": { "react": "^18.2.0" }版本号前的
^表示兼容当前版本的次版本更新。 -
devDependencies:开发环境依赖(仅开发时使用,比如测试、构建工具),例如:"devDependencies": { "eslint": "^8.55.0" } -
peerDependencies:声明项目运行时需要的外部依赖版本(常用于插件或库)。 -
optionalDependencies:可选依赖,即使安装失败也不会影响项目。
3.4 脚本字段
-
scripts:定义可执行的命令,例如:"scripts": { "start": "node index.js", "dev": "nodemon index.js" }执行方法:
npm run start npm run dev
4. package.json 的生成方式
-
手动创建:直接新建
package.json文件并写入内容。 -
使用命令:
npm init会通过交互方式生成。
-
使用默认配置:
npm init -y直接生成一个默认的
package.json。
5. 与 package-lock.json 的关系
-
package.json:声明依赖的版本范围。 -
package-lock.json:锁定安装时的具体版本,确保每次安装的依赖版本一致。
✅ 总结:package.json 是项目的 “身份证” 和 “说明书”,它定义了项目的基本信息、依赖关系、可执行脚本等。掌握它的结构和字段,是使用 npm 和 Node.js 开发的基础。