总结
无论是哪家公司,都很重视高并发高可用的技术,重视基础,重视JVM。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。其实我写了这么多,只是我自己的总结,并不一定适用于所有人,相信经过一些面试,大家都会有这些感触。
最后我整理了一些面试真题资料,技术知识点剖析教程,还有和广大同仁一起交流学习共同进步,还有一些职业经验的分享。
<profile> <id>jdk-release-flag</id> <activation> <jdk>[9,)</jdk> </activation> <properties> <maven.compiler.release>8</maven.compiler.release> </properties> </profile>
apache-release
:这个是指最终发布的选项,在执行mvn release:perform
时启用<releaseProfiles>
profiles
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>2.5.3</version> <configuration> <releaseProfiles>apache-release</releaseProfiles> <arguments>-Dmaven.test.skip.exec ${arguments}</arguments> </configuration> </plugin>
虽然我们在刚打开项目的时候就更改了项目jdk版本,但是maven并不会实时更新激活的profiles选项,所以为谨慎起见,需要手动设置 Maven profiles 选项为 java-build
:
3.4. 执行 Ant build 生成和编译Java文件
安装 IDEA 的 Ant
插件:File
> Settings...
> Plugins
调出 IDEA 的 ant build 界面,如果没有,请依次点击菜单:View
> Tool Windows
> Ant
然后找到项目根目录下的 build.xml
文件,并右键点击它唤出菜单,选择 Add as Ant Build File
。
打开 Ant 界面的 Properties 属性设置,确认设置正确的 jdk:Run under JDK:
,保持与之前项目jdk一致(JDK 1.8)。同时也可以将 IDEA 默认的Ant自定义指定为其他已经安装的Ant。
3.4.1. 执行ant build-generated
而非ant eclipse
网上很多文章都要求执行 ant eclipse
任务,但实际上其本质只是生成一些 .eclipse
、.project
之类的文件和目录罢了,关键的其实是其依赖的其他任务。
这样的话,我们是用 InteliJ Idea 打开的项目,eclipse的项目文件就没有作用了,再执行这个任务生成一些没有用的文件就显得有不优雅了,既然关键的不是 eclipse
任务本身,而是其依赖,那我们就可以仅执行我们需要的依赖任务即可,恰好,根据对 eclipse
任务的依赖关系梳理,找到了一个完美的依赖任务,其几乎也依赖所有除 eclipse
之外的需要的任务,那不就巧了,它就是:
ant build-generated
笔记:
ant eclipse
任务的依赖关系梳理过程如下在正式执行
eclipse
任务之前会先执行其依赖的任务:
ant-eclipse-download
:下载 Ant-Eclipse,它是 Java 构建工具 Ant 生成 Eclipse 项目的任务,只需轻松导入和使用即可。Ant 构建脚本用作配置生成项目所基于的源代码和库的中心位置。init
:初始化操作,包括创建新的目录和设置时间戳格式,创建的目录包括:
${basedir}/build/classes
${basedir}/build/lib
${basedir}/build/package/lib
${basedir}/build/test/lib
ivy-download
:下载 Apache Ivy™ ,它是一个流行的依赖管理器,专注于灵活性和简单性。ivy-taskdef
:结合项目命名空间中的 antlib 定义,它将从 Ant 库或本地目录加载 Ivy 类。ivy-init
:使用${basedir}/ivysettings.xml
文件配置 Ivyivy-retrieve
:该任务将已解析的依赖项复制到文件系统中所需的任何位置ivy-retrieve-javacc
:初始化目录${basedir}/build/javacc/lib
,并执行一次ivy:retrieve
generate_jute_parser
:生产 jute 解析器- 初始化目录
${basedir}/build/jute_compiler/org/apache/jute/compiler/generated
;- 执行一次
ivy:artifactproperty
,根据之前解析过的依赖包的包名(解析包名根据<ivy:retrieve>
标签的pattern=${ivy.lib}/[artifact]-[revision].[ext]
属性),生成一批以[artifact].revision
格式命名的属性,并将依赖包的[revision]
赋值给对应包名的属性。例如slf4j-api.revision=1.7.25
、commons-lang.revision=2.6
和javacc.revision=5.0
等等。- 执行一次
move
同位移动来实现文件重命名,将带版本号的${basedir}/build/javacc/lib/javacc-${javacc.revision}.jar
重命名为没有版本号的${basedir}/build/javacc/lib/javacc.jar
- 执行一次
javacc
编译${basedir}/zookeeper-jute/src/main/java/org/apache/jute/compiler/generated/rcc.jj
为 java 类并输出到目录${basedir}/build/jute_compiler/org/apache/jute/compiler/generated/
jute
:用javac编译${basedir}/zookeeper-jute/src/main/java
和${basedir}/build/jute_compiler
两处源文件为class文件并输出到目录${basedir}/build/classes
compile_jute_uptodate
:比较源文件与目标文件时间戳,如果目标文件比源文件更新,则设置属性juteBuild.notRequired=true
,该属性用于任务compile_jute
的执行条件,只有在它为false
时才会执行compile_jute
任务。compile_jute
:生成一些java类- 创建新目录:
${basedir}/zookeeper-jute/target/main/java
- 创建新目录:
${basedir}/zookeeper-client/zookeeper-client-c/generated
- 执行java代码:
org.apache.jute.compiler.generated.Rcc
,该代码的作用就是编译位于${basedir}/zookeeper-jute/src/main/resources/zookeeper.jute
文件内容中的java代码,生成相应的类。包含:
org.apache.zookeeper.data.*
org.apache.zookeeper.proto.*
org.apache.zookeeper.server.quorum.*
org.apache.zookeeper.server.persistence.*
org.apache.zookeeper.txn.*
ver-gen
:执行javac
编译目录为${basedir}/zookeeper-server/src/main/java
下的java类,并将产出class文件输出到${basedir}/build/classes
目录git-revision
:- 创建新目录
${basedir}/.revision
- 判断如果是 windows 操作系统,则设置属性:
shell.name=cmd
、revision.cmd.line=/c ${basedir}/zookeeper-server/src/main/resources\lastRevision.bat
- 执行命令:经过人工拼接最终执行的是
cmd /c ${basedir}/zookeeper-server/src/main/resources\lastRevision.bat ${basedir}/.revision/revision.properties
(注意:${basedir}
是项目根目录,请读者自行脑中替换),所以是执行了一个windows批命令脚本。该脚本会收集当前git仓库的最后一次提交的hash值,并输出到一个revision.properties
文件中。- 将上一个命令输出的
revision.properties
导入到属性集中,其中只有一个属性:lastRevision
version-info
:- 创建目录
${basedir}/zookeeper-jute/target/main/java
- 执行java代码
org.apache.zookeeper.version.util.VerGen
,其main()
函数参数有三个分别为{3.5.9-SNAPSHOT,83df9301aa5c2a5d284a9940177808c01bc35cef,03/10/2024 00:00:00}
,创建一个org.apache.zookeeper.version.Info.java
文件,该文件记录了一下版本信息。process-template
:将目录${basedir}/zookeeper-client/zookeeper-client-c
中的configure.ac.in
和include/zookeeper_version.h.in
文件复制到同目录并且重命名删除它们的.in
后缀。build-generated
:执行javac
命令编译目录${basedir}/zookeeper-jute/target/main/java
下的所有java文件并将产出 class 文件输出到目录${basedir}/build/classes
ivy-retrieve-test
:测试执行ivy:retrieve
eclipse
:在执行完上面所有 ant 任务之后,才执行最后的这个 eclipse 任务
3.4.2. 对比构建前后项目多了什么
3.5. maven compile
在 Idea maven 界面执行 compile 目标,如下图所示。
如果严格按照以上步骤的话,没有意外的会编译成功:
main:
[INFO] Executed tasks
[INFO]
[INFO] --- maven-remote-resources-plugin:1.5:process (process-resource-bundles) @ zookeeper-assembly ---
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for Apache ZooKeeper 3.5.9:
[INFO]
[INFO] Apache ZooKeeper ................................... SUCCESS [ 2.642 s]
[INFO] Apache ZooKeeper - Documentation ................... SUCCESS [ 1.811 s]
[INFO] Apache ZooKeeper - Jute ............................ SUCCESS [ 3.659 s]
[INFO] Apache ZooKeeper - Server .......................... SUCCESS [ 4.100 s]
[INFO] Apache ZooKeeper - Client .......................... SUCCESS [ 0.108 s]
[INFO] Apache ZooKeeper - Recipes ......................... SUCCESS [ 0.310 s]
[INFO] Apache ZooKeeper - Recipes - Election .............. SUCCESS [ 0.628 s]
[INFO] Apache ZooKeeper - Recipes - Lock .................. SUCCESS [ 0.489 s]
[INFO] Apache ZooKeeper - Recipes - Queue ................. SUCCESS [ 0.411 s]
[INFO] Apache ZooKeeper - Assembly ........................ SUCCESS [ 0.470 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.832 s
[INFO] Finished at: 2024-03-11T02:08:15+08:00
[INFO] ------------------------------------------------------------------------
3.6. 准备一个zoo.cfg配置文件
进入目录 ${basedir}/conf/
,在同目录复制一个 zoo_sample.cfg
文件并重命名为 zoo.cfg
。
打开并且编辑,增加两个属性:
# windows系统下的绝对路径,该目录用于存储zookeeper数据
dataDir=F:\\privateBox\\kafkaCodeReadProject\\zookeeper\\tmp\\zookeeper
# 修改服务端口,避开常用的8080
admin.serverPort=8083
这个配置文件是执行 java 命令时需要作为参数用的,例如:
java org.apache.zookeeper.server.quorum.QuorumPeerMain F:\privateBox\kafkaCodeReadProject\zookeeper\conf\zoo.cfg
3.7. 配置classpath
由于 ant build 生成和编译的文件,大部分都放在了 ${basedir}/build/
目录下,所以单独构建 zookeeper-server 模块时会找不到一些由 zookeeper-jute 模块生成的一些类。例如:org.apache.zookeeper.data.ACL
、org.apache.zookeeper.data.Stat
以及更多
为了让zookeeper-server能接触的到这些类,需要将这些目录加到它的 classpath 里面。
具体操作方法如下:
依次点击菜单:File
> Project structure...
>
增加两个目录即可:
${basedir}/build/classes
${basedir}/conf
注意:目录
${basedir}/conf
里面没有 class 文件,所以 idea 询问你选择的是该目录中的什么类型文件,选择Classes
即可
配置完成之后,会发现,编辑器里也不会出现org.apache.zookeeper.data.ACL
、org.apache.zookeeper.data.Stat
等类红色警告,build project 的时候也不会提示找不到该类等错误了。
3.8. 启动 QuorumPeerMain
- 在
${basedir}/zookeeper-server
模块目录下找到org.apache.zookeeper.server.quorum.QuorumPeerMain
类。 - 右键选择
Modify Run Configuration...
开启设置启动参数配置 - jdk选择和项目保持一致,idea会默认选择自带的jdk,建议手动更改为保持项目和ant同一个jdk。
Program arguments
增加内容:${basedir}\conf\zoo.cfg
(请自行替换${basedir}
以确保输入一个绝对路径)
然后启动就可以了
查看 InteliJ Idea 启动时的控制台输出的 java
命令内容是什么:
"C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:54029,suspend=y,server=n -javaagent:C:\Users\Kitman\AppData\Local\JetBrains\IdeaIC2022.1\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\cat.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\charsets.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\crs-agent.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\dnsns.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\jaccess.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\localedata.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\nashorn.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\sunec.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\zipfs.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\jce.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\jfr.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\jsse.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\management-agent.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\resources.jar;C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\rt.jar;F:\privateBox\kafkaCodeReadProject\zookeeper\zookeeper-server\target\classes;F:\privateBox\kafkaCodeReadProject\zookeeper\zookeeper-jute\target\classes;F:\software\apache-maven-3.6.3\repo\org\apache\yetus\audience-annotations\0.5.0\audience-annotations-0.5.0.jar;F:\software\apache-maven-3.6.3\repo\io\netty\netty-handler\4.1.50.Final\netty-handler-4.1.50.Final.jar;F:\software\apache-maven-3.6.3\repo\io\netty\netty-common\4.1.50.Final\netty-common-4.1.50.Final.jar;F:\software\apache-maven-3.6.3\repo\io\netty\netty-resolver\4.1.50.Final\netty-resolver-4.1.50.Final.jar;F:\software\apache-maven-3.6.3\repo\io\netty\netty-buffer\4.1.50.Final\netty-buffer-4.1.50.Final.jar;F:\software\apache-maven-3.6.3\repo\io\netty\netty-transport\4.1.50.Final\netty-transport-4.1.50.Final.jar;F:\software\apache-maven-3.6.3\repo\io\netty\netty-codec\4.1.50.Final\netty-codec-4.1.50.Final.jar;F:\software\apache-maven-3.6.3\repo\io\netty\netty-transport-native-epoll\4.1.50.Final\netty-transport-native-epoll-4.1.50.Final.jar;F:\software\apache-maven-3.6.3\repo\io\netty\netty-transport-native-unix-common\4.1.50.Final\netty-transport-native-unix-common-4.1.50.Final.jar;F:\software\apache-maven-3.6.3\repo\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;F:\software\apache-maven-3.6.3\repo\org\slf4j\slf4j-log4j12\1.7.25\slf4j-log4j12-1.7.25.jar;F:\software\apache-maven-3.6.3\repo\log4j\log4j\1.2.17\log4j-1.2.17.jar;F:\privateBox\kafkaCodeReadProject\zookeeper\build\classes;F:\privateBox\kafkaCodeReadProject\zookeeper\conf;D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.2\lib\idea_rt.jar" org.apache.zookeeper.server.quorum.QuorumPeerMain F:\privateBox\kafkaCodeReadProject\zookeeper\conf\zoo.cfg
其中命令的 classpath 部分整理为列表如下所示:
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\cat.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\charsets.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\access-bridge-64.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\cldrdata.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\crs-agent.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\dnsns.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\jaccess.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\localedata.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\nashorn.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\sunec.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\sunjce_provider.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\sunmscapi.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\sunpkcs11.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\ext\zipfs.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\jce.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\jfr.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\jsse.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\management-agent.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\resources.jar
C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64\jre\lib\rt.jar
F:\privateBox\kafkaCodeReadProject\zookeeper\zookeeper-server\target\classes
F:\privateBox\kafkaCodeReadProject\zookeeper\zookeeper-jute\target\classes
F:\software\apache-maven-3.6.3\repo\org\apache\yetus\audience-annotations\0.5.0\audience-annotations-0.5.0.jar
F:\software\apache-maven-3.6.3\repo\io\netty\netty-handler\4.1.50.Final\netty-handler-4.1.50.Final.jar
F:\software\apache-maven-3.6.3\repo\io\netty\netty-common\4.1.50.Final\netty-common-4.1.50.Final.jar
F:\software\apache-maven-3.6.3\repo\io\netty\netty-resolver\4.1.50.Final\netty-resolver-4.1.50.Final.jar
F:\software\apache-maven-3.6.3\repo\io\netty\netty-buffer\4.1.50.Final\netty-buffer-4.1.50.Final.jar
F:\software\apache-maven-3.6.3\repo\io\netty\netty-transport\4.1.50.Final\netty-transport-4.1.50.Final.jar
F:\software\apache-maven-3.6.3\repo\io\netty\netty-codec\4.1.50.Final\netty-codec-4.1.50.Final.jar
F:\software\apache-maven-3.6.3\repo\io\netty\netty-transport-native-epoll\4.1.50.Final\netty-transport-native-epoll-4.1.50.Final.jar
F:\software\apache-maven-3.6.3\repo\io\netty\netty-transport-native-unix-common\4.1.50.Final\netty-transport-native-unix-common-4.1.50.Final.jar
F:\software\apache-maven-3.6.3\repo\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar
F:\software\apache-maven-3.6.3\repo\org\slf4j\slf4j-log4j12\1.7.25\slf4j-log4j12-1.7.25.jar
F:\software\apache-maven-3.6.3\repo\log4j\log4j\1.2.17\log4j-1.2.17.jar
F:\privateBox\kafkaCodeReadProject\zookeeper\build\classes
F:\privateBox\kafkaCodeReadProject\zookeeper\conf
D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.2\lib\idea_rt.jar
4. 在命令行 cmd 中编译和启动
在完成 准备一个zoo.cfg配置文件 步骤后,尝试在项目根目录打开 cmd 直接执行 cmd /k bin\zkServer.cmd
脚本启动服务,会直接报错,日志如下所示:
F:\privateBox\kafkaCodeReadProject\zookeeper>cmd /k bin\zkServer.cmd
F:\privateBox\kafkaCodeReadProject\zookeeper>call "C:\Program Files\Java\zulu8.76.0.17-ca-jdk8.0.402-win_x64"\bin\java "-Dzookeeper.log.dir=F:\privateBox\kafkaCodeReadProject\zookeeper\bin\..\logs" "-Dzookeeper.log.file=zookeeper-Kitman-server-DESKTOP-S0UTLJU.log" "-XX:+HeapDumpOnOutOfMemoryError" "-XX:OnOutOfMemoryError=cmd /c taskkill /pid %%p /t /f" -cp "F:\privateBox\kafkaCodeReadProject\zookeeper\bin\..\build\classes;F:\privateBox\kafkaCodeReadProject\zookeeper\bin\..\build\lib\*;F:\privateBox\kafkaCodeReadProject\zookeeper\bin\..\*;F:\privateBox\kafkaCodeReadProject\zookeeper\bin\..\lib\*;F:\privateBox\kafkaCodeReadProject\zookeeper\bin\..\conf" org.apache.zookeeper.server.quorum.QuorumPeerMain "F:\privateBox\kafkaCodeReadProject\zookeeper\bin\..\conf\zoo.cfg"
错误: 找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain
F:\privateBox\kafkaCodeReadProject\zookeeper>endlocal
无法加载某某类肯定是 classpath 中没有包含该类导致的,说明源码还没有编译完成,至少没有编译这个类到 classpath 包含的目录中,所以在找不到。
通过观察命令当中的 -cp
参数研究其 classpath
明确包含有以下目录:
${basedir}\build\classes
${basedir}\build\lib\*
${basedir}\*
${basedir}\lib\*
${basedir}\conf
也就是说,以上这些目录中,没有编译过的 org.apache.zookeeper.server.quorum.QuorumPeerMain
主类,说明我们还没有完成编译工作。
4.1. 安装 Ant
根据 zookeeper 项目根目录下的 README_packaging.txt
文件中的内容提示,ant 版本建议在 1.9.4
以上。
我们直接到官网下载一个最新的:
在 官方下载页面 下载一个当前最新版本的二进制包 apache-ant-1.10.14-bin.zip
。
注意!Ant 官方提供二进制包下载以及源码包下载,如果下载了源码包还要再次进行编译构建才能真正应用,所以建议直接下载二进制包方便直接配置应用。
解压缩二进制包,将解压缩后 bin
的父目录,添加到环境配置中,命名为ANT_HOME
,并添加 %ANT_HOME%/bin/
到 Path
中。
在新打开的 cmd 中执行 ant -version
验证安装成功。
4.2. 使用 Ant 编译
注意,我们这里不需要制定执行的 ant 任务,就直接执行一个:
ant
查看 build.xml
,发现其中是给项目配置了默认ant任务为 jar
的:
<project name="ZooKeeper" default="jar"
xmlns:ivy="antlib:org.apache.ivy.ant"
xmlns:artifact="antlib:org.apache.maven.artifact.ant"
xmlns:maven="antlib:org.apache.maven.artifact.ant"
xmlns:cs="antlib:com.puppycrawl.tools.checkstyle.ant">
有的读者可能会问:
为什么不是跟 Idea 打开项目时执行的 ant build-generated
一样呢?
从两个方面来回答:
- 其实 Idea 也可以用不选择某个任务来执行从而让它执行默认的
ant jar
,但是对于 Idea 环境来说,前者已经足够,ant jar
会生成更多的内容,比如会把zookeeper-server
模块整个编译到${basedir}/build/classes
里,那这样的话,和mvn compile
编译到模块target/classes
目录重复,而观察 InteliJ Idea 启动zookeeper的java命令内容 中的classpath,它是同时包含这两个目录的,一旦出现重复,而没有在更新代码之后及时保持两个目录下的编译结果一致,可能会出现不可预知的问题。 - 对于
zkServer.cmd
脚本只包含${basedir}/build/classes
而不包含模块target/classes
的 classpath 来说,ant build-generated
是不够用的,因为它不会编译zookeeper-server
模块,会导致脚本找不到主类。
以下记录执行 ant
命令(等效 ant jar
)的日志:
F:\privateBox\kafkaCodeReadProject\zookeeper>ant
Buildfile: F:\privateBox\kafkaCodeReadProject\zookeeper\build.xml
init:
[mkdir] Created dir: F:\privateBox\kafkaCodeReadProject\zookeeper\build\classes
[mkdir] Created dir: F:\privateBox\kafkaCodeReadProject\zookeeper\build\lib
[mkdir] Created dir: F:\privateBox\kafkaCodeReadProject\zookeeper\build\package\lib
[mkdir] Created dir: F:\privateBox\kafkaCodeReadProject\zookeeper\build\test\lib
ivy-download:
[get] Getting: https://repo1.maven.org/maven2/org/apache/ivy/ivy/2.5.0-rc1/ivy-2.5.0-rc1.jar
[get] To: F:\privateBox\kafkaCodeReadProject\zookeeper\zookeeper-server\src\main\resources\lib\ivy-2.5.0-rc1.jar
ivy-taskdef:
ivy-init:
ivy-retrieve:
[ivy:retrieve] :: Apache Ivy 2.5.0-rc1 - 20180412005306 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = F:\privateBox\kafkaCodeReadProject\zookeeper\ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: org.apache.zookeeper#zookeeper;3.5.9-SNAPSHOT
[ivy:retrieve] confs: [default]
[ivy:retrieve] found jline#jline;2.11 in maven2
[ivy:retrieve] found org.eclipse.jetty#jetty-server;9.4.35.v20201120 in maven2
[ivy:retrieve] found javax.servlet#javax.servlet-api;3.1.0 in maven2
[ivy:retrieve] found org.eclipse.jetty#jetty-http;9.4.35.v20201120 in maven2
[ivy:retrieve] found org.eclipse.jetty#jetty-util;9.4.35.v20201120 in maven2
[ivy:retrieve] found org.eclipse.jetty#jetty-io;9.4.35.v20201120 in maven2
[ivy:retrieve] found org.eclipse.jetty#jetty-servlet;9.4.35.v20201120 in maven2
[ivy:retrieve] found org.eclipse.jetty#jetty-security;9.4.35.v20201120 in maven2
[ivy:retrieve] found org.eclipse.jetty#jetty-util-ajax;9.4.35.v20201120 in maven2
[ivy:retrieve] found com.fasterxml.jackson.core#jackson-databind;2.10.3 in maven2
[ivy:retrieve] found com.fasterxml.jackson.core#jackson-annotations;2.10.3 in maven2
[ivy:retrieve] found com.fasterxml.jackson.core#jackson-core;2.10.3 in maven2
[ivy:retrieve] found org.slf4j#slf4j-api;1.7.25 in maven2
[ivy:retrieve] found org.slf4j#slf4j-log4j12;1.7.25 in maven2
[ivy:retrieve] found commons-cli#commons-cli;1.2 in maven2
[ivy:retrieve] found com.github.spotbugs#spotbugs-annotations;3.1.9 in maven2
[ivy:retrieve] found com.google.code.findbugs#jsr305;3.0.2 in maven2
[ivy:retrieve] found log4j#log4j;1.2.17 in maven2
[ivy:retrieve] found org.apache.yetus#audience-annotations;0.5.0 in maven2
[ivy:retrieve] found io.netty#netty-handler;4.1.50.Final in maven2
[ivy:retrieve] found io.netty#netty-common;4.1.50.Final in maven2
[ivy:retrieve] found io.netty#netty-resolver;4.1.50.Final in maven2
[ivy:retrieve] found io.netty#netty-buffer;4.1.50.Final in maven2
[ivy:retrieve] found io.netty#netty-transport;4.1.50.Final in maven2
[ivy:retrieve] found io.netty#netty-codec;4.1.50.Final in maven2
[ivy:retrieve] found io.netty#netty-transport-native-epoll;4.1.50.Final in maven2
[ivy:retrieve] found io.netty#netty-transport-native-unix-common;4.1.50.Final in maven2
[ivy:retrieve] :: resolution report :: resolve 569ms :: artifacts dl 44ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 27 | 0 | 0 | 0 || 27 | 0 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache.zookeeper#zookeeper
[ivy:retrieve] confs: [default]
[ivy:retrieve] 27 artifacts copied, 0 already retrieved (6939kB/40ms)
ivy-retrieve-clover:
clover.check:
clover.setup:
clover:
ivy-retrieve-javacc:
[mkdir] Created dir: F:\privateBox\kafkaCodeReadProject\zookeeper\build\javacc\lib
[ivy:retrieve] :: resolving dependencies :: org.apache.zookeeper#zookeeper;3.5.9-SNAPSHOT
[ivy:retrieve] confs: [javacc]
[ivy:retrieve] found net.java.dev.javacc#javacc;5.0 in maven2
[ivy:retrieve] :: resolution report :: resolve 20ms :: artifacts dl 0ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| javacc | 1 | 0 | 0 | 0 || 1 | 0 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache.zookeeper#zookeeper
[ivy:retrieve] confs: [javacc]
[ivy:retrieve] 1 artifacts copied, 0 already retrieved (291kB/4ms)
generate_jute_parser:
[mkdir] Created dir: F:\privateBox\kafkaCodeReadProject\zookeeper\build\jute_compiler\org\apache\jute\compiler\generated
[ivy:artifactproperty] DEPRECATED: 'ivy.conf.file' is deprecated, use 'ivy.settings.file' instead
[ivy:artifactproperty] :: loading settings :: file = F:\privateBox\kafkaCodeReadProject\zookeeper\ivysettings.xml
[move] Moving 1 file to F:\privateBox\kafkaCodeReadProject\zookeeper\build\javacc\lib
[javacc] Java Compiler Compiler Version 5.0 (Parser Generator)
[javacc] (type "javacc" with no arguments for help)
### 最后
### ActiveMQ消息中间件面试专题
* 什么是ActiveMQ?
* ActiveMQ服务器宕机怎么办?
* 丢消息怎么办?
* 持久化消息非常慢怎么办?
* 消息的不均匀消费怎么办?
* 死信队列怎么办?
* ActiveMQ中的消息重发时间间隔和重发次数吗?
**ActiveMQ消息中间件面试专题解析拓展:**
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/f401ecf7ea552c865d5eb849ac858116.webp?x-oss-process=image/format,png)
* * *
# redis面试专题及答案
* 支持一致性哈希的客户端有哪些?
* Redis与其他key-value存储有什么不同?
* Redis的内存占用情况怎么样?
* 都有哪些办法可以降低Redis的内存使用情况呢?
* 查看Redis使用情况及状态信息用什么命令?
* Redis的内存用完了会发生什么?
* Redis是单线程的,如何提高多核CPU的利用率?
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/1a732d8d691d94cf92a1251791a0abd4.webp?x-oss-process=image/format,png)
* * *
# **Spring面试专题及答案**
* 谈谈你对 Spring 的理解
* Spring 有哪些优点?
* Spring 中的设计模式
* 怎样开启注解装配以及常用注解
* 简单介绍下 Spring bean 的生命周期
**Spring面试答案解析拓展**
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/21dcccc78bbb686d74cb14e21210664e.webp?x-oss-process=image/format,png)
* * *
# 高并发多线程面试专题
* 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
* Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
* Java 中 wait 和 sleep 方法有什么区别?
* 如何在 Java 中实现一个阻塞队列?
* 如何在 Java 中编写代码解决生产者消费者问题?
* 写一段死锁代码。你在 Java 中如何解决死锁?
**高并发多线程面试解析与拓展**
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/8d146c34e9f3b9d4619dcc492d3e17a8.webp?x-oss-process=image/format,png)
* * *
# jvm面试专题与解析
* JVM 由哪些部分组成?
* JVM 内存划分?
* Java 的内存模型?
* 引用的分类?
* GC什么时候开始?
**JVM面试专题解析与拓展!**
![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/8d48ec3033eef8898d20613ce55d57c1.webp?x-oss-process=image/format,png)
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**
**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
写入,你如何保证数据完整性。
* Java 中 wait 和 sleep 方法有什么区别?
* 如何在 Java 中实现一个阻塞队列?
* 如何在 Java 中编写代码解决生产者消费者问题?
* 写一段死锁代码。你在 Java 中如何解决死锁?
**高并发多线程面试解析与拓展**
[外链图片转存中...(img-3JiUNM0c-1715415610007)]
* * *
# jvm面试专题与解析
* JVM 由哪些部分组成?
* JVM 内存划分?
* Java 的内存模型?
* 引用的分类?
* GC什么时候开始?
**JVM面试专题解析与拓展!**
[外链图片转存中...(img-e46xIWLT-1715415610007)]
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**
**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**