1.1 douckr面试题

没问题!想在 Docker 面试中显得经验丰富,关键不是背概念,而是展现出你解决过真实问题。下面我为你精选了 6 道高频实战题,并附上"高手回答思路"和"加分话术",让你快速掌握精髓。

🗺️ Docker 高频实战面试题

1. 基础概念与原理:容器 vs 虚拟机
  • 问题:Docker 容器和传统虚拟机到底有什么区别?
  • 高手回答思路
    • 核心差异 :虚拟机是硬件级 虚拟化,模拟完整硬件和操作系统;Docker 是操作系统级虚拟化,共享宿主机内核。
    • 四大对比:资源占用上,容器(MB级)远小于虚拟机(GB级);启动速度上,容器(秒级)远快于虚拟机(分钟级);性能上,容器损耗极小,虚拟机有额外开销;隔离性上,虚拟机是强隔离,容器是进程级隔离。
  • 加分话术 :"容器本质上就是宿主机上一个被隔离的进程 。它的隔离依赖于 Linux 内核的三大基石:Namespace 做资源隔离,Cgroups 做资源限制,UnionFS 做分层存储。"
2. 镜像与 Dockerfile 实战:构建优化的镜像
  • 问题:说说你写 Dockerfile 的经验?如何减小镜像体积?
  • 高手回答思路
    • 选择轻量级基础镜像 :如 alpine-slim 版本。
    • 合并 RUN 命令:减少镜像层数。
    • 清理包管理器缓存:在同一个 RUN 中安装并清理。
    • 利用构建缓存 :将变动不频繁的指令(如 COPY 依赖文件)放在前面。
    • 使用多阶段构建:最终镜像只包含运行所需的产物。
  • 加分话术 :"比如构建一个 Spring Boot 应用,我会先用 maven:3.8-openjdk-11 编译,然后用 openjdk:11-jre-slim 运行,最终镜像能从几百 MB 降到几十 MB。"
3. 网络与数据管理:容器间通信与数据持久化
  • 问题:两个 Docker 容器如何通信?如何保证容器重启后数据不丢失?
  • 高手回答思路
    • 容器通信 :最推荐的方式是自定义桥接网络(Bridge) ,容器通过容器名 互相访问。也可以使用 --net=host 共享宿主机网络。
    • 数据持久化 :使用数据卷(Volume),由 Docker 管理,独立于容器生命周期。
  • 加分话术 :"生产环境我通常会配合 docker-compose.yml,在文件中定义好网络和服务,一条 docker-compose up 就能启动整套环境,服务间通过服务名就能发现彼此。"
4. 容器编排与 Compose:管理多容器应用
  • 问题:你们项目用了 Docker Compose 吗?它解决了什么问题?
  • 高手回答思路
    • 解决的问题 :Compose 解决了定义和运行多容器应用的痛点。
    • 核心价值 :通过一个 docker-compose.yml 文件定义所有服务、网络和卷,用一条命令就能一键启动整个应用栈。
  • 加分话术 :"我们项目的微服务本地开发环境就是用 Compose 编排的。docker-compose up -d 就能把服务、数据库、缓存全部跑起来,极大提升了团队的开发效率。"
5. 高级与故障排查:进入容器与查看日志
  • 问题:如果容器运行异常,你会如何排查?
  • 高手回答思路
    • 查看日志docker logs <container_name>
    • 进入容器docker exec -it <container_name> /bin/bash
    • 检查状态docker ps -a 查看容器状态,docker inspect <container_name> 查看详细信息。
    • 资源监控docker stats 查看实时资源占用。
  • 加分话术 :"我一般先看 docker logs,如果信息不足就 exec 进去看进程。特别有用的是 docker inspect,可以看到容器的完整元数据,比如 IP、挂载的卷、网络模式等。"
6. 高级与故障排查:资源限制
  • 问题:如何防止一个容器耗尽其所在主机的所有资源?
  • 高手回答思路
    • 使用 docker run 命令的 --memory--cpu-shares 等参数来限制资源。
    • 也可以在 docker-compose.ymldeployresources 下进行限制。
  • 加分话术:"我们会在 CI/CD 流程中为每个服务预设资源配额,这保证了测试环境的稳定性,避免了一个服务出问题而拖垮整台服务器。"

💡 面试加分技巧

  1. 多提"场景":回答时尽量使用"在我们项目中..."、"当时遇到一个问题是..."这样的句式。
  2. 手写命令:能流畅说出常用命令和关键参数。
  3. 结合生态:提到 Docker 时,顺便带出 Kubernetes、CI/CD 等,展现你的知识广度。
  4. 展现热情:表现出对容器化、云原生技术的兴趣。

祝你面试顺利!上面这6道题里,有哪道是你特别担心被问到的吗?我可以针对这道题再帮你整理一套详细的应对话术~

太好了!Java微服务 + Docker 是面试里的 "王炸"组合 ,面试官最爱问的是JVM调优、服务发现、配置传递和优雅下线等真正在生产环境会踩坑的点。

下面这5道题,专为Java微服务场景定制,跟紧我的思路,学完你就能跟面试官侃侃而谈。


题1:JVM内存与容器化(必考陷阱题)

  • 问题 :Spring Boot 应用容器化后,你在 -Xmx 设置了堆内存为 512MB,但容器内存限制只给了 400MB,会发生什么?如何安全设置?
  • 高手回答思路
    • 踩坑点 :JDK 8u131 之前的版本不感知容器资源限制,JVM 会按宿主机内存的 1/4 来分配堆,导致容器实际内存超限,被 Linux 内核(OOM Killer)强制杀死。
    • 解决方案
      1. 升级到 JDK 8u191+ 或 JDK 10+,JVM 默认开启 -XX:+UseContainerSupport,自动感知 CGroup 限制。
      2. 最佳实践 :不要写死 -Xmx,而是使用比例参数:-XX:MaxRAMPercentage=80.0(表示堆内存占容器限制的 80%),给 Metaspace 和 JVM 自身预留 20%。
  • 加分话术 :"我们生产环境统一使用 -XX:MaxRAMPercentage=75.0 -XX:InitialRAMPercentage=75.0,这样即使运维调整了 Pod 的内存配额,应用也能自适应,不用重新构建镜像。"

题2:Spring Boot 分层镜像构建(CI/CD提速)

  • 问题:你们每次代码提交都要重新 Build 几百兆的镜像,构建太慢怎么办?
  • 高手回答思路
    • 痛点:传统 Dockerfile 把所有 Jar 包打在一起,只要改一行代码,整个镜像层缓存全部失效。
    • 核心解法 :利用 Spring Boot 2.3+ 的 Layered Jars(分层Jar包) 特性。
    • 实操步骤
      1. pom.xml 中配置 Spring Boot Maven 插件生成分层 Jar。
      2. Dockerfile 中分步 COPY:先复制 dependencies/(依赖包,变动极少),再复制 snapshot-dependencies/,最后复制 application/(业务代码)。
      3. 利用 Docker 的 Layer 缓存机制,只有业务代码层变动时才重新编译,依赖层直接命中缓存。
  • 加分话术 :"我们配合 CI/CD 流水线,借助分层构建,镜像推送时间从原来的 3 分钟缩短到了 30 秒以内。如果是使用 Maven 插件,我还会用 dockerfile-maven-plugin 直接构建,省去手动 docker build 的环节。"

题3:微服务注册发现与容器网络(Eureka/Nacos)

  • 问题:你的 Java 微服务部署在 Docker 中,注册中心(如 Nacos/Eureka)上显示的 IP 是容器内网 IP(如 172.17.x.x),别的服务无法访问,怎么解决?
  • 高手回答思路
    • 根本原因:服务启动时默认取主机名/IP,在容器内取到的是容器内部的虚拟 IP,而其他宿主机上的容器无法直接路由这个 IP。
    • 解决办法(三选一,推荐第一种)
      1. 环境变量覆盖 :启动容器时传入 -e SPRING_CLOUD_NACOS_DISCOVERY_IP=宿主机真实IP,强制服务向注册中心上报宿主机 IP。同时设置 SPRING_CLOUD_NACOS_DISCOVERY_PORT=映射到宿主机的端口
      2. 使用主机网络docker run --net=host,容器与宿主机共用网络栈,但会损失隔离性,端口易冲突。
      3. K8s 环境 :配合 K8s 的 hostNetwork 或使用 Headless Service + DNS 解析。
  • 加分话术 :"我一般会在 application.yml 中预留占位符,比如 spring.cloud.nacos.discovery.ip=${HOST_IP:localhost},然后在 docker-compose.yml 里通过 environment 动态注入 HOST_IP。如果是在 K8s 中,更推荐使用 Downward API 将 status.podIP 注入环境变量。"

题4:优雅停机与健康检查(无损发布)

  • 问题 :每次发版 docker stop 容器时,总有部分正在处理的请求报错,如何实现无感知发布?
  • 高手回答思路
    • 优雅停机的三步走
      1. Spring Boot 配置 :开启优雅停机(server.shutdown=graceful),并设置 spring.lifecycle.timeout-per-shutdown-phase=30s,给现有请求 30 秒完成时间。
      2. 就绪探针(Readiness Probe) :配合 management.endpoint.health.probes.enabled=true 暴露 /actuator/health/readiness。当收到 docker stop 信号(SIGTERM)时,Spring Boot 会让就绪探针先变为 FAIL,从负载均衡(如 Nginx 或 K8s Service)中摘除流量。
      3. Docker 配合docker stop 默认有 10 秒的 grace-period,务必将其延长至 30 秒以上(docker stop -t 30),等待应用完全退出。
  • 加分话术 :"我们结合 K8s 的 preStop 钩子,在 Pod 销毁前先执行 sleep 5,等 Service 的 Endpoint 更新完毕,再发送 SIGTERM,完美避免了发版期间的 502 报错。"

题5:云原生构建工具(Jib / Buildpacks)

  • 问题:你们生产环境不允许安装 Docker 守护进程(Docker daemon),那如何构建 Java 镜像?
  • 高手回答思路
    • 痛点 :传统 docker build 依赖 Docker 环境,在 CI 机器上不好装或权限受限。
    • 现代化方案
      1. Google Jib :Maven/Gradle 插件,无需 Dockerfile 和 Docker 守护进程,直接将 Java 项目构建为镜像并推送到镜像仓库。它默认就是分层构建 ,且具备重复数据删除功能。
      2. Spring Boot 官方 Buildpacks :使用 ./mvnw spring-boot:build-image,它会自动探测应用类型,生成最优化的 OCI 镜像,自动配置 JVM 参数(如上面提到的内存比例)。
  • 加分话术 :"我们团队已经从 Dockerfile 切换到了 Jib。因为它不需要在 CI 节点上维护 Docker 环境,而且构建速度极快。最关键的是,Jib 生成的镜像层结构专门针对 Java 优化,比手写 Dockerfile 更科学。如果是 Spring Boot 3.x 项目,我也会推荐直接用官方 Buildpacks,真正实现 'Build once, run anywhere'。"

💡 针对 Java 微服务的额外加分动作

  • APM 探针注入 :提到在 Dockerfile 中通过环境变量 JAVA_TOOL_OPTIONS 注入 SkyWalking 或 Pinpoint 的 Agent,实现无侵入监控。
  • 时区与字符集 :提到基础镜像务必设置 ENV TZ=Asia/ShanghaiLANG=C.UTF-8,避免日志时间差 8 小时和中文乱码。
  • 文件句柄 :提到高并发下修改 ulimit -n,否则 Netty 或 Tomcat 会报 "Too many open files"。

这 5 道题是 Java 微服务 Docker 化的核心命门。如果你想让回答更深入,我可以再单独给你拆解一下 JVM 参数在容器中的最佳实践(比如要不要用 G1GC,参数怎么写) ,或者 如何将 SkyWalking Agent 优雅地打入基础镜像,你想先听哪个?😊