Q:Java中equals()和==的区别? A:==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同 Q:final关键字的使用? A:final可以修饰类,方法,变量; final修饰的类无法被继承; final修饰的方法无法被覆盖,无法被重写; final修饰的实例变量只能赋一次值; final修饰的引用:该引用只能指向1个对象,不过该引用指向的对象里的值可以修改。 Q:C++和Java的区别? A:C++允许多继承,Java只能单继承; C++允许运算符重载,Java不允许; C++有指针,Java封装了指针,程序员用不了。 Q:String、StringBuffer、StringBuilder的区别? A:底层用char[]实现; String(JDK1.0)不可变字符串; StringBuffer(JDK1.0)可变字符串,效率低,线程安全; StringBuilder(JDK5.0)可变字符串,效率高,线程不安全; 作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值。 Q:ArrayList、LinkedList、Vector的异同? A:三个类都是实现了List接口,存储数据的特点相同,存储有序的、可重复的数据; ArrayList线程不安全,但效率高,底层使用Object[]。JDK1.7中ArrayList的创建类似于恶汉式,JDK1.8中则是懒汉式,1.8效率更高,节省了点内存; LinkedLIst底层使用的双向链表,线程不安全; Vector线程安全,效率低,底层使用的Object[],JDK1.0就存在; Q:callable接口与runnable接口的区别 A:相比run方法,有返回值; 方法可以抛异常; 支持泛型的返回值; 需要借助FutureTask类,比如获取返回结果; Q:Future接口 A:可对具体的Runable、Callable任务的执行结果进行取消、查询是否完成、获取结果等; FutrueTask是Future接口的唯一实现类; FutureTask同时实现了Runnable、Future接口,它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。 1. 技术选型原因 问题示例: “为什么选择 Gerrit 而不是 GitLab 自带的 Merge Request(MR)功能?” 回答思路: * 强调代码审查的严格性:
“项目中涉及核心存储模块(如 MinIO 集成)和敏感数据处理,需确保代码质量。Gerrit 的强制代码评审流程(Change + Verified 标签)能避免未经审核的代码合并,而 GitLab 的 MR 流程依赖团队自律,适合更灵活的协作场景。” * 集成 CI/CD 的优势:
“Gerrit 与 Jenkins 深度集成,支持在代码提交阶段触发自动化测试,只有通过评审和测试的代码才能合并,形成闭环的质量门禁。” * 权限控制的精细度:
“Gerrit 支持基于分支、目录的细粒度权限管理(如限制 main 分支只能由团队负责人合并),这对多团队协作的复杂场景更友好。” 2. 具体实施流程 问题示例: “Gerrit 是如何与 Jenkins 和 GitLab 集成的?” 回答思路: * 流程链路:
“开发者通过 git push 提交代码到 Gerrit → Gerrit 自动创建 Change 并触发 Jenkins 构建 → Jenkins 运行单元测试、静态检查(如 SonarQube)→ 结果反馈到 Gerrit 的 Verified 标签 → 至少两位 Reviewer 通过后代码合并至主分支 → Jenkins 触发 Docker 镜像打包并部署到测试环境。” * 工具集成细节: * Jenkins:使用 Gerrit Trigger 插件监听 Gerrit 事件,配置构建规则(如 change-merged 时触发生产环境部署)。 * GitLab:通过镜像仓库同步 Gerrit 的主分支,保持两者代码一致,同时利用 GitLab 的 Issue 跟踪功能与 Gerrit Change-ID 关联。 3. 遇到的挑战与解决 问题示例: “在引入 Gerrit 的过程中,遇到过哪些问题?如何解决?” 回答思路: * 挑战 1:团队适应成本高
“部分开发者习惯直接推送代码到主分支,不熟悉 Gerrit 的 Change-Id 提交流程。
解决方案: * 编写《Gerrit 提交规范》文档,规范提交消息格式。 * 通过 Git Hook 自动生成 Change-Id,减少人工错误。 * 挑战 2:权限配置复杂
“需要为不同团队(如前端、后端)分配差异化的代码库访问权限。
解决方案: * 使用 Gerrit 的 Project.config 文件定义基于组的权限(如 refs/heads/*[Code-Review+2])。 * 结合 LDAP 同步公司组织架构,自动化管理用户组。” 4. 成果与量化效果 问题示例: “引入 Gerrit 后,对项目有哪些实际改进?” 回答思路: * 代码质量提升:
“通过强制评审和自动化测试拦截,生产环境 Bug 数减少 30%。” * 部署效率优化:
“Gerrit + Jenkins 的自动化流程将代码提交到部署的平均时间从 2 小时缩短至 30 分钟。” * 协作规范化:
“所有代码变更可追溯(Gerrit Change-ID 关联 Jira Issue),历史评审记录清晰,降低沟通成本。” 5. 对工具链的深入理解 问题示例: “Gerrit、GitLab、Jenkins 在流程中如何分工?” 回答思路: * Gerrit:
“作为代码评审的核心枢纽,负责准入控制(Code Review)和自动化测试触发。” * GitLab:
“作为代码托管和 Issue 管理平台,利用其 CI/CD 功能处理非核心路径的轻量级任务(如文档生成)。” * Jenkins:
“作为执行引擎,处理 Gerrit 触发的构建、测试和部署任务,同时集成 Ansible 实现云环境配置。” 6. 技术细节(备选) 问题示例: “Gerrit 的容器化部署是如何实现的?” 回答思路: * Docker Compose 编排:
“通过 docker-compose.yml 定义 Gerrit、PostgreSQL 和 OpenLDAP 服务,挂载持久化卷到 /home/moloom/tools_configuration/gerrit/,确保数据安全。” * 网络与安全:
“所有服务加入独立 Docker 网络 tools_configuration_bridge_tools,限制外部访问,同时配置 Nginx 反向代理和 HTTPS 加密。” 总结回答示例 “在项目中,Gerrit 作为代码质量的核心防线,通过强制评审和自动化测试确保只有合规代码进入生产环境。我们将其与 Jenkins、GitLab 深度集成,形成从提交→评审→构建→部署的闭环流程,最终将部署效率提升 60%,缺陷率降低 30%。过程中解决了权限管理和团队协作的挑战,积累了 DevOps 工具链的实战经验。”