英孚面经(OC已经拒)
面试官很好,很多人一起面,感觉公司氛围也很好,给的待遇也不错。。但是我贪心了感恩他,大家可以尝试投递一下 更多面经请查看,这是第二篇,以后会陆续更新https://github.com/haandfeng/Mianjing 也会完善,我会持续引用之前面经的内容,也会根据自己面的公司看之前的面经,然后写上答案。如果大家觉得有用请多多关注,点赞收场star🥺🥺🥺
面试公司:英孚面试
面试岗位:IT实习生
面试问题:
SQL基础
一张表叫table,两个column,一个叫stu_id(唯一)一个course(唯一),我要求看到所有选了某门课超过2的这些所有信息
SELECT *
FROM table
WHERE course IN (
SELECT course
FROM table
GROUP BY course
HAVING COUNT(stu_id) > 2
);
Maven作为一个开发工具,具体有什么用途
Maven 是一个用于构建和管理 Java 项目的工具,广泛应用于 Java 开发中。它的主要用途可以概括为以下几点:
1. 构建自动化:
Maven 自动化了项目的构建过程,包括编译源代码、打包 JAR/WAR 文件、执行单元测试、生成文档等。通过简单的命令,开发者可以轻松地构建和部署项目。
• 编译和打包:Maven 能根据项目配置文件(pom.xml)自动进行编译、打包操作。
• 生命周期管理:Maven 提供了预定义的构建生命周期(如 clean, compile, test, install 和 deploy 等),确保每个阶段都能按顺序执行。
2. 依赖管理:
Maven 使用中央仓库(Central Repository)来自动下载和管理项目所依赖的库文件和插件。
• 依赖声明:开发者只需在 pom.xml 文件中声明项目的依赖(如第三方库),Maven 会自动下载并包含这些依赖。
• 版本管理:Maven 支持自动管理不同版本的依赖,避免了版本冲突和手动下载的麻烦。
3. 项目管理:
Maven 的 pom.xml 文件不仅用于描述项目的依赖关系,还包含了项目的元数据、构建配置、插件配置等,帮助开发者在不同环境中快速启动并管理项目。
• 模块化:Maven 支持多模块项目(Multi-module Project),方便大型项目的管理。
• 构建配置管理:可以通过继承父 POM 文件,统一管理多个项目的构建设置。
4. 持续集成和部署:
Maven 可以与持续集成(CI)工具如 Jenkins、GitLab CI 等结合使用,自动执行构建、测试和部署等操作。
5. 插件支持:
Maven 提供了丰富的插件,帮助开发者在构建过程中执行各种任务,如代码检查、文档生成、部署操作等。
• 常用插件:maven-compiler-plugin(编译源代码),maven-surefire-plugin(运行单元测试),maven-jar-plugin(创建 JAR 文件),maven-deploy-plugin(将构建结果部署到远程仓库)等。
6. 文档生成:
Maven 可以自动生成项目文档,包括 Javadoc、依赖树、构建报告等,帮助团队管理和维护项目。
7. 可扩展性:
Maven 的架构支持插件和扩展,可以根据项目需求进行定制化,适应不同的开发需求。
8. 跨平台:
Maven 是基于 Java 的工具,可以在任何支持 Java 的平台上运行,提供了一种跨平台一致的构建和管理方式。
典型的 Maven 使用流程:
-
创建项目:开发者通过 Maven 命令或 IDE 创建一个新的 Maven 项目。
-
定义依赖:在 pom.xml 中添加项目所需的第三方库、插件和其他模块。
-
构建项目:运行 mvn clean install 来编译、测试、打包项目并将构建结果安装到本地仓库。
-
发布和部署:使用 mvn deploy 将项目发布到远程仓库或者进行部署。
Maven常用指令
1. mvn clean • 作用:清理项目,删除 target 目录下的所有文件。常用于在重新构建项目之前清理上次构建留下的文件。 • 使用场景:在构建过程中遇到问题时,清理掉旧的编译结果,再次进行构建。
2. mvn compile • 作用:编译项目的源代码。它会根据 src/main/java 目录中的 Java 源代码进行编译,生成 target/classes 目录中的 .class 文件。 • 使用场景:当你只想编译代码而不进行打包或测试时使用。
3. mvn test • 作用:运行项目中的单元测试。它会编译源代码并执行测试(通常是在 src/test/java 中的测试类)。 • 使用场景:确保项目的单元测试在构建过程中成功通过。
4. mvn package • 作用:编译源代码并打包成 JAR/WAR 文件,通常会将打包结果放在 target/ 目录下。 • 使用场景:完成项目的构建并生成可分发的文件。
5. mvn install • 作用:构建项目并将构建结果(如 JAR/WAR 文件)安装到本地 Maven 仓库(~/.m2/repository)。 • 使用场景:在本地仓库中安装构建的项目,以便其他项目能够引用它作为依赖。
6. mvn deploy • 作用:构建项目并将构建结果部署到远程 Maven 仓库(例如 Nexus 或 Artifactory)。 • 使用场景:当需要将构建好的项目发布到共享的远程仓库时使用。
7. mvn clean install • 作用:先执行 clean 清理操作,然后执行 install 安装过程。通常用于确保在新一轮构建时,不会有旧的文件干扰。 • 使用场景:常用于完整的构建流程,在从头开始构建时确保不会留下遗留文件。
8. mvn validate • 作用:验证项目是否正确,检查 pom.xml 文件中的配置是否正确并且依赖是否存在。 • 使用场景:在构建之前验证项目的配置是否正确。
9. mvn site • 作用:生成项目的站点文档。Maven 可以生成一些标准的项目报告(例如:测试报告、依赖报告、插件报告等)。 • 使用场景:生成项目的文档,便于团队协作和后续维护。
10. mvn dependency:tree • 作用:显示当前项目的依赖树,帮助开发者理解项目依赖关系。 • 使用场景:调试依赖问题,查看依赖的版本和层级。
11. mvn clean verify • 作用:先清理项目(clean),然后执行验证步骤(verify),以确保项目符合特定的质量标准。 • 使用场景:进行完整的项目验证,确保一切都正常。
12. mvn spring-boot:run • 作用:启动一个 Spring Boot 项目(如果项目是 Spring Boot 项目)。 • 使用场景:在开发过程中直接启动 Spring Boot 应用进行调试。
13. mvn dependency:analyze • 作用:分析项目中的依赖,检查是否有多余的依赖或遗漏的依赖。 • 使用场景:帮助清理项目的冗余依赖,优化项目配置。
常用的参数: • -D:用来传递系统属性,例如:
mvn clean install -DskipTests
这将跳过测试执行。 • -U:强制更新本地仓库中的依赖,检查远程仓库是否有更新的版本。
mvn clean install -U
validate和verify的区别是
1. mvn validate • 作用:验证项目的配置是否正确。主要是检查 pom.xml 配置文件中的内容是否符合 Maven 的标准和规则。 • 具体操作: • 检查 pom.xml 是否存在,格式是否正确。 • 验证项目的依赖是否有效,是否能够从配置的仓库中找到。 • 确保 Maven 配置中没有错误或遗漏。 • 使用场景:通常在构建之前运行,确保项目的配置没有问题。它并不会进行代码的编译或测试,也不会执行任何构建的后续操作。主要是用于验证项目环境的完整性。 • 生命周期中的位置:位于构建生命周期的开始阶段。
2. mvn verify • 作用:验证项目的构建是否成功,通常是执行测试、检查生成的构件(如 JAR/WAR 文件)是否符合质量标准。 • 具体操作: • 在项目编译和测试之后,执行所有的测试(如单元测试、集成测试等)。 • 验证项目是否符合预期的质量标准(如运行测试、检查代码质量、检查构建的有效性等)。 • 使用场景:通常在构建和测试阶段之后运行,确保构建成功并且通过了所有的测试。verify 阶段通常用于执行质量保证任务,例如运行集成测试、检查代码质量等。 • 生命周期中的位置:位于构建生命周期的后期阶段,通常在 install 之前执行
git提交代码的指令
相关面试题:[[广州兴业#git 假设你现在正在开发了另外一个功能,但是现在线上它有报了个bug过来,怎么操作]]
在使用 Git 时,提交代码是常见的操作之一。以下是一些常用的 Git 提交代码的指令及其解释: 1. git init • 作用:初始化一个新的 Git 仓库。如果是首次使用 Git 版本控制,你需要先在项目目录中初始化一个 Git 仓库。 • 命令:
git init
2. git add <file> • 作用:将修改添加到暂存区(staging area),准备提交。 • 常见用法: • 添加一个文件:
git add filename
• 添加所有修改的文件:
git add .
3. git commit -m "<message>" • 作用:将暂存区的修改提交到本地 Git 仓库。-m 后跟的是提交信息,用于描述这次提交的内容。 • 命令:
git commit -m "描述提交内容"
• 示例:
git commit -m "Fix issue with login validation"
4. git commit -a -m "<message>" • 作用:自动将所有已修改的文件(已跟踪的文件)添加到暂存区,并提交。-a 会跳过 git add 步骤,直接将已修改的文件提交。 • 命令:
git commit -a -m "描述提交内容"
• 这条命令不会提交新添加的文件(未被跟踪的文件),如果有新文件需要提交,仍然需要使用 git add。 5. git commit --amend • 作用:修改上一次的提交信息或将新的更改合并到上一次提交中。通常用于修正一些小错误或更新提交信息。 • 命令:
git commit --amend
• 如果不加 -m 参数,Git 会打开编辑器让你修改提交信息。 6. git status • 作用:查看当前 Git 仓库的状态,显示哪些文件已修改,哪些文件已暂存,哪些文件还未跟踪。 • 命令:
git status
7. git log • 作用:查看 Git 仓库的提交历史记录,按时间倒序显示提交的 SHA 值、提交者、提交时间和提交信息。 • 命令:
git log
8. git push • 作用:将本地的提交推送到远程仓库(如 GitHub、GitLab 等)。在第一次推送时,可能需要指定远程仓库和分支。 • 命令:
git push origin <branch_name>
• 示例:
git push origin master
9. git pull • 作用:从远程仓库拉取最新的代码并合并到本地仓库。 • 命令:
git pull origin <branch_name>
• 示例:
git pull origin master
10. git diff • 作用:查看文件的修改差异,显示工作目录和暂存区之间的差异。 • 命令:
git diff
11. git stash • 作用:暂时保存未提交的更改(即工作进度),将它们从当前工作区移除,可以随时恢复。 • 命令:
git stash
• 恢复保存的更改:
git stash apply
和 git add
的区别
• git add 将你工作目录中已修改或新增的文件(未被 Git 跟踪的文件)添加到 暂存区。暂存区是 Git 用来准备提交(commit)文件的地方。
• git stash 会把当前工作目录和暂存区的所有修改(包括新增的文件)临时保存到 Git 的栈中,并恢复工作区和暂存区到上一次提交的状态。它不会提交更改,只是暂时保存起来,以便你稍后恢复这些更改。
12. 典型的提交流程:
- 修改文件:在本地代码中做出修改。
- 查看文件状态:
git status
- 将修改的文件添加到暂存区:
git add .
- 提交修改:
git commit -m "描述提交内容"
- 推送到远程仓库:
git push origin <branch_name>
这些是 Git 提交代码时常用的指令,可以帮助你更高效地管理代码的版本和变更。
在黑马点评中用到了springboot的哪些组件
???我回答了request mapping但我看gpt回答不是这样的,我不清楚怎么回答好,求大佬解答
redis清除本地缓存的命令
• 清除当前数据库的所有缓存:
FLUSHDB
清除所有数据库的所有缓存:
FLUSHALL
• 删除特定键:
DEL key1 key2 key3
• 删除符合特定模式的键(例如所有以 user: 开头的键):
KEYS user:* | xargs DEL
redis常用命令
建议直接看菜鸟教程或者问gpt
认识什么排序,讲讲原理,时间复杂度
说了很多,他让我讲快排和冒泡排序,
快排
- 选择一个基准元素(pivot)。
- 将数组按照基准元素分成两个部分,左边部分小于基准,右边部分大于基准。
- 对左边和右边的部分递归地进行排序。
- 最终所有的子数组都被排序后,整个数组即完成排序。 O(nlogn)
冒泡排序
- 从数组的第一个元素开始,依次比较相邻的两个元素。
- 如果前一个元素比后一个元素大,则交换它们的位置。
- 每一趟遍历后,最大的元素会“冒泡”到数组的末尾。
- 重复步骤 1-3,直到数组完全排序。 O(n^2)
UML具体是哪三个单词
Unified Model Language 统一模型语言
描述一下实习你怎么优化数据库的查询时间的
==感觉这块我可以背背,组成自己的一段话,常问,以后会慢慢总结提升的== SQL语句的优化,join,查询的优化 加索引
算法题:51. N 皇后
让我选前缀和 回溯 排序,我选了回溯
看了一下我的leetcode和github界面
问为什么用C++ 写算法不用Java
- 因为一开始看的教学视频用java,不想完全照抄他的代码,想要有思考的改写,所以用C++
- 比较熟悉他的STL库
双端队列在C++ STL是哪个,特点是
在 C++ STL 中,双端队列对应的容器是 deque(双端队列)。deque 是一个可以在两端进行高效插入和删除的容器,具有以下特点:
deque 的特点: 支持双端操作: • 可以在队列的两端(头部和尾部)进行高效的插入和删除操作,时间复杂度为 O(1)。 随机访问: • deque 提供对元素的随机访问,即支持通过索引直接访问元素,类似于 vector,时间复杂度为 O(1)。
N皇后的时间复杂度
是一个全排列算法,
在每一层的递归中,我们需要选择一个列来放置皇后。放置皇后时,我们需要确保该列、该行、以及两个对角线没有其他皇后。因此,放置皇后的选择数在初始时是 N,但随着递归的进行,合法的选择数会减少。
• 在第 1 行放置第一个皇后时,可以选择 N 列中的任何一列。
• 在第 2 行放置第二个皇后时,可以选择 N-1 列中的任何一列(因为已放置第一个皇后,排除了它所在的列)。
• 在第 3 行,可能有更多的列被排除,所以选择数进一步减少。
那么,最坏情况下的时间复杂度是:O(N!)
写N皇后的时候前面的取址符有什么作用
不用拷贝数组,传递地址,比较快
C++的Lamba表达式怎么写,用它来比较一下字符串类型的大小,用它来sort
C++ 中的 Lambda 表达式 是一种匿名函数,它可以在代码中定义并立即使用,通常用于临时的或局部的功能。Lambda 表达式的语法如下:
[捕获列表](参数列表) -> 返回类型 { 函数体 }
• 捕获列表:指定外部变量如何被 Lambda 捕获(按值捕获、按引用捕获等)。 • 参数列表:与普通函数一样,指定输入参数。 • 返回类型:可以省略,编译器会自动推断。 • 函数体:Lambda 表达式的主体,包含了具体的功能实现。 示例:使用 Lambda 表达式比较字符串大小并用 std::sort 排序 下面是一个示例,展示了如何使用 Lambda 表达式比较字符串的大小,并用它来排序一个字符串数组或向量。
#include <iostream>
#include <vector>
#include <algorithm> // for std::sort
using namespce std;
int main() {
// 初始化一个字符串向量
vector<std::string> words = {"banana", "apple", "cherry", "date", "elderberry"};
// 使用 Lambda 表达式按字典顺序对字符串进行排序
sort(words.begin(), words.end(), [](const string& a, const string& b) -> bool {
return a < b; // 比较字符串 a 和 b 的大小
});
}
常用的捕获方式
按值捕获:捕获外部变量的副本
[x] { /* Lambda 体可以使用 x 的副本 */ }
• 捕获变量 x 的副本,并且在 Lambda 内部使用副本。这意味着 Lambda 内部对 x 的修改不会影响外部的 x。
按引用捕获:捕获外部变量的引用
[&x] { /* Lambda 体可以修改 x */ }
• 捕获变量 x 的引用,允许 Lambda 内部直接修改外部变量的值。
按值捕获所有变量:捕获所有外部变量的副本
[=] { /* Lambda 体可以使用外部所有变量的副本 */ }
• 捕获外部所有变量的副本,并在 Lambda 内部使用它们。注意,如果捕获了外部的某个变量,那么 Lambda 内部的副本是不可变的,即无法修改这些副本。
按引用捕获所有变量:捕获外部所有变量的引用
[&] { /* Lambda 体可以修改外部所有变量 */ }
• 捕获外部所有变量的引用,Lambda 内部可以直接修改这些外部变量。
同时按值和按引用捕获:可以选择性地指定按值或按引用捕获特定的变量
[x, &y] { /* x 按值捕获,y 按引用捕获 */ }
• 捕获 x 的副本(按值捕获),并且捕获 y 的引用(按引用捕获)。
按值捕获所有变量并指定按引用捕获某些变量:
[=, &y] { /* 所有变量按值捕获,y 按引用捕获 */ }
• 捕获所有外部变量的副本,并且捕获 y 的引用。
捕获 this 指针:捕获当前对象的指针(对于成员函数)
[this] { /* 可以使用成员函数中的 this 指针访问对象的成员 */ }
• 捕获当前对象的 this 指针,允许在 Lambda 内部访问成员变量和成员函数。这通常在成员函数中使用。
捕获列表的详细示例
#include <iostream>
#include <vector>
#include <algorithm>
class Example {
public:
int x;
Example(int val) : x(val) {}
void demonstrate() {
// Lambda 按值捕获外部变量
auto byValue = [x = this->x]() {
std::cout << "Captured by value: " << x << std::endl;
};
// Lambda 按引用捕获外部变量
auto byReference = [&]() {
x = 100; // 修改外部变量
std::cout << "Captured by reference: " << this->x << std::endl;
};
// Lambda 按值捕获所有变量
auto captureAllByValue = [=]() {
std::cout << "Captured all by value: " << x << std::endl;
};
// Lambda 按引用捕获所有变量
auto captureAllByReference = [&]() {
x = 200; // 修改外部变量
std::cout << "Captured all by reference: " << x << std::endl;
};
// 捕获 this 指针
auto captureThis = [this]() {
std::cout << "Captured this pointer: " << this->x << std::endl;
};
byValue();
byReference();
captureAllByValue();
captureAllByReference();
captureThis();
}
};
int main() {
Example example(10);
example.demonstrate();
return 0;
}
解释:
-
按值捕获 auto byValue = x = this->x:在 Lambda 内部 x 是外部变量 this->x 的副本,修改 x 不会影响外部的 x。
-
按引用捕获 auto byReference = &: Lambda 内部捕获外部所有变量的引用,并且修改 x 会影响到外部 x 的值。
-
按值捕获所有变量 auto captureAllByValue = =: 捕获所有外部变量的副本,Lambda 内部对外部变量的修改不会影响外部变量。
-
按引用捕获所有变量 auto captureAllByReference = &: 捕获所有外部变量的引用,Lambda 内部对外部变量的修改会影响外部变量。
-
捕获 this 指针 auto captureThis = this: 捕获当前对象的 this 指针,允许访问成员变量和成员函数。