Jenkins

Jenkins

jenkins简介

Jenkins官网
Jenkins是一个开源CI&CD软件、提供友好操作界面的持续集成(CI)工具;
起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行;Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行;通常与版本管理工具(SCM)、构建工具结合使用。

常用的版本控制工具:SVN、GIT
构建工具有:Maven、Ant、Gradle

jenkins工作原理

将源代码从SVN/Git版本控制系统中拷贝一份到本地,然后根据设置的脚本进行build(构建);整个系统的关键就是build脚本,build脚本告诉Jenkins在一次集成中需要执行的任务。

jenkins特点

(1)易安装:仅仅一个 Jenkins.war,从官网下载该文件后,直接运行,无需额外的安装,更无需安装数据库
(2)易配置:提供友好的 GUI 配置界面
(3)变更支持:Jenkins 能从代码仓库(SVN/Git)中获取并产生代码更新列表,并输出到编译输出信息中
(4)支持永久链接:用户是通过 Web 来访问 Jenkins 的,而这些 Web 页面的链接地址都是永久链接地址,可以在各种文档中直接使用该链接;
(5)集成 E-Mail/RSS/IM:当完成一次集成时,可通过这些工具实时收取集成结果(构建一次集成需要花费一定时间,有了这个功能,就可以在等待结果过程中,干别的事情);
(6)JUnit/TestNG 测试报告:也就是用以图表等形式提供详细的测试报表功能;
(7)支持分布式构建:Jenkins 可以把集成构建等工作分发到多台计算机中完成;
(8)文件指纹信息:Jenkins 会保存构建集成所产生的 jars 文件、集成构建使用了哪个版本;
(9)支持第三方插件:Jenkins 支持 第三方插件,这使得 Jenkins 功能变得越来越强大

CI/CD是什么

CI持续集成
1、简介
CI 持续集成(全称:Continuous integration),中文意思是持续集成是一种软件开发时间;持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试;根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。
假设一个应用程序,其代码存储在GitLab的Git仓库中。开发人员每天都要多次推送代码更改。对于每次向仓库的推送,你都可以创建一组脚本来自动构建和测试你的应用程序,从而减少了向应用程序引入错误的机会。这种做法称为持续集成,对于提交给应用程序(甚至是开发分支)的每项更改,它都会自动连续进行构建和测试,以确保所引入的更改通过你为应用程序建立的所有测试,准则和代码合规性标准。
2、CI工作模式

Jenkins
3、持续集成的优势
(1)易于定位错误:
每一次的代码集成都需要执行相关的测试工作,持续集成频繁的集成次数天然的将复杂的代码逻辑切割为了小块,也就使得每一次测试中遇到的错误能够更加容易的被定位。
(2)易于控制开发流程:
更为细致的工作提交也就意味着更容易判断当前的工作进度,这对于管理者规划开发流程而言提供了一个有效的参考,同时也为开发人员省下了汇报工作的时间。
CD持续交付
1、简介
CD 持续交付(全称:Continuous Delivery), 中文意思是:持续交付 是在 CI持续集成 的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中;比如,我们完成单元测试后,可以把代码部署到连接数据库的Staging环境中更多的测试,如果代码没有问题,可以继续手动部署到生产环境。

2、CD工作模式

Jenkins
3、CD持续部署
简介
CD 持续部署(全称:Continuous Deployment),是 CI持续集成 ,CD持续交付的延伸。自动将交付的应用部署到生产环境。能及时收到用户反馈,降低部署的风险;
持续部署是持续交付的下一步,在持续交付的基础上,由开发人员或运维人员自助式的定期向生产环境部署稳定的构建版本,持续部署的目标是代码在任何时刻都是可部署的,并可自动进入到生产环境。

工作模式:

Jenkins

使用tomcat容器安装jenkins

部署tomcat,tomcat下载9.0版本的,10版本部署有bug,无法实现
tomcat下载9.0版本的下载地址
安装jdk

[root@jenkins ~]# dnf -y install java-11-openjdk

下载tomcat,解压tomcat,并部署安装

root@jenkins ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.67/bin/apache-tomcat-9.0.67.tar.gz
[root@jenkins ~]# ls
anaconda-ks.cfg  apache-tomcat-9.0.67.tar.gz
[root@jenkins ~]# tar xf apache-tomcat-9.0.67.tar.gz -C /usr/local/
[root@jenkins ~]# cd /usr/local/
[root@jenkins local]# ln -s apache-tomcat-9.0.67/ tomcat

关闭·防火墙,启动tomcat,测试能否访问tomcat首页

[root@jenkins local]# cd tomcat/
[root@jenkins tomcat]# systemctl stop firewalld.service
[root@jenkins tomcat]# vim /etc/selinux/config
SELINUX=disabled
[root@jenkins tomcat]# setenforce 0
[root@jenkins tomcat]# systemctl disable --now firewalld.service
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.

Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

[root@jenkins tomcat]# bin/startup.sh
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.

访问:

Jenkins
部署jenkins
下载jenkins到/usr/local/tomcat/webapps/目录下
官网地址
Jenkins
Jenkins
[root@jenkins tomcat]# cd
[root@jenkins ~]# cd /usr/local/tomcat/webapps/
[root@jenkins webapps]# pwd
/usr/local/tomcat/webapps

下载下来后会自动解压

[root@jenkins webapps]# wget http://mirrors.jenkins.io/war-stable/2.346.3/jenkins.war
[root@jenkins webapps]# ls
ROOT  docs  examples  host-manager  jenkins.war  manager

启动服务

[root@jenkins webapps]# cd /usr/local/tomcat/
[root@jenkins tomcat]# pwd
/usr/local/tomcat
[root@jenkins tomcat]# bin/catalina.sh stop
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
[root@jenkins tomcat]# bin/catalina.sh start
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.

浏览器访问jinkins
直接在http://192.168.222.138:8080/后面加jinkins就可以访问到

Jenkins
查看上图框出来的文件,该文件中记录这密码,复制密码并登录
[root@jenkins tomcat]# cat /root/.jenkins/secrets/initialAdminPassword
41ec057f2f0643339e015d44019c63ab

Jenkins
自定义jenkins
选择插件来安装
Jenkins
选择无,进行安装,后期需要什么插件就安装什么插件
Jenkins
创建管理员用户admin,密码为admin
Jenkins
Jenkins
Jenkins
此时登录进去是英文界面,我们进行替换国内源
Jenkins
点击 Advanced —> 更新为国内源 —> Submit
原国外插件源地址:https://updates.jenkins.io/update-center.json
国内插件源地址:https://mirror.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
Jenkins
Jenkins
往下面翻
Jenkins
安装简体中文插件
Jenkins
Jenkins
Jenkins
用户名和密码都是admin
Jenkins
Jenkins
安装Git GitHub GitLab Gitee插件
安装完成后,会重启jenkins
Jenkins
Jenkins
用户界面
任务管理
Jenkins
Jenkins
Jenkins
Jenkins
全局工具配置
安装jdk
Jenkins
Jenkins
Jenkins
节点管理

jenkins流水线项目发布流程

环境说明:

主机名称 ip地址 需要的应用服务 工具包 系统 jenkins 192.168.222.138 tomcat、jenkins git maven RHEL8/centos8 node2 192.168.222.139 tomcat 无 RHEL8/centos8

1、关闭防火墙和selinux

[root@jenkins ~]# systemctl stop firewalld.service
[root@jenkins ~]# vim /etc/selinux/config
SELINUX=disabled
[root@jenkins ~]# setenforce 0
[root@jenkins ~]# systemctl disable --now firewalld.service
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.

Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

2、在jenkins上部署服务tomcat和jenkins(上面已经部署),重新部署,登录web界面时选择安装推荐的插件,部署好后,设置国内源
安装jdk

[root@jenkins ~]# dnf -y install java-11-openjdk

下载tomcat,解压tomcat,并部署安装

root@jenkins ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.67/bin/apache-tomcat-9.0.67.tar.gz
[root@jenkins ~]# ls
anaconda-ks.cfg  apache-tomcat-9.0.67.tar.gz
[root@jenkins ~]# tar xf apache-tomcat-9.0.67.tar.gz -C /usr/local/
[root@jenkins ~]# cd /usr/local/
[root@jenkins local]# ln -s apache-tomcat-9.0.67/ tomcat

启动tomcat,测试能否访问tomcat首页

[root@jenkins local]# cd tomcat/
[root@jenkins tomcat]# bin/startup.sh
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.

访问:

Jenkins
部署jenkins
下载jenkins到/usr/local/tomcat/webapps/目录下
官网地址
Jenkins
Jenkins
[root@jenkins tomcat]# cd
[root@jenkins ~]# cd /usr/local/tomcat/webapps/
[root@jenkins webapps]# pwd
/usr/local/tomcat/webapps

下载下来后会自动解压

[root@jenkins webapps]# wget http://mirrors.jenkins.io/war-stable/2.346.3/jenkins.war
[root@jenkins webapps]# ls
ROOT  docs  examples  host-manager  jenkins.war  manager

启动服务

[root@jenkins webapps]# cd /usr/local/tomcat/
[root@jenkins tomcat]# pwd
/usr/local/tomcat
[root@jenkins tomcat]# bin/catalina.sh stop
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
[root@jenkins tomcat]# bin/catalina.sh start
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.

浏览器访问jinkins
直接在http://192.168.222.138:8080/后面加jinkins就可以访问到

Jenkins
查看上图框出来的文件,该文件中记录这密码,复制密码并登录
root@jenkins tomcat]# cat /root/.jenkins/secrets/initialAdminPassword
fc3a1c3be0d94327a9ba48790f2ebfbb

Jenkins
使用推荐插件进行安装
Jenkins
Jenkins
Jenkins
Jenkins
Jenkins
Jenkins
点击 Advanced —> 更新为国内源 —> Submit
原国外插件源地址:https://updates.jenkins.io/update-center.json
国内插件源地址:https://mirror.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
Jenkins
Jenkins
往下面翻
Jenkins
3、先在jenkins主机上生成一个密钥,传给node2主机
[root@jenkins ~]# ssh-keygen
Generating public/private rsa key pair.

Enter file in which to save the key (/root/.ssh/id_rsa): //回车
Created directory '/root/.ssh'.

Enter passphrase (empty for no passphrase):  //回车
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.

Your public key has been saved in /root/.ssh/id_rsa.pub.

The key fingerprint is:    //回车
SHA256:ZYs4NKha67nu0hX2GP7sXokv4f6IXMBNLCsS8iPKjCw root@jenkins
The key's randomart image is:  //回车
+---[RSA 3072]----+
|                 |
|     o           |
|o   o =   o      |
|.o o+* o + .     |
|o *o+=+ S .      |
|*= ++.oo .       |
|E=.. +o.o        |
|o..o o=+         |
| +*.o+=oo        |
+----[SHA256]-----+
[root@jenkins ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.222.139
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.222.139 (192.168.222.139)' can't be established.

ECDSA key fingerprint is SHA256:anVVbTlEIzA1E8rB7IbLzaf7t9oQjB0qFP6Dd/ijnJI.

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.222.139's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.222.139'"
and check to make sure that only the key(s) you wanted were added.

可以提前做一个映射,防止访问不了github

[root@jenkins ~]# vim /etc/hosts
[root@jenkins ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
20.205.243.166 github.com    //添加

4、在node2上部署tomcat

[root@node2 ~]# systemctl stop firewalld.service
[root@node2 ~]# vim /etc/selinux/config
SELINUX=disabled
[root@node2 ~]# setenforce 0
[root@node2 ~]# systemctl disable --now firewalld.service
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.

Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

[root@node2 ~]# dnf  -y install java-11-openjdk
[root@node2 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.67/bin/apache-tomcat-9.0.67.tar.gz
[root@node2 ~]# ls
anaconda-ks.cfg  apache-tomcat-9.0.67.tar.gz
[root@node2 ~]# tar xf apache-tomcat-9.0.67.tar.gz -C /usr/local/
[root@node2 ~]# cd /usr/local/
[root@node2 local]#  ln -s apache-tomcat-9.0.67/ tomcat
[root@node2 local]# ls tomcat/
BUILDING.txt     LICENSE  README.md      RUNNING.txt  conf  logs  webapps
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin          lib   temp  work
[root@node2 local]# cd tomcat/
[root@node2 tomcat]# bin/catalina.sh start
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.

进行访问:

Jenkins
可以提前做一个映射,防止访问不了github
[root@node2 ~]# vim /etc/hosts
[root@node2 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
20.205.243.166 github.com    //添加

5、在node1中配置jenkins
创建任务

Jenkins
创建流水线任务
Jenkins
发布流水线的方法我在这里给大家介绍两种,一种是脚本的方式,一种是使用文本参数的方式
首选都需要在jinkins所在服务器,也就是jenkins中安装git和maven
[root@jenkins ~]# dnf -y install git maven

就是通过文本参数来实现流水线项目发布
添加文本参数

Jenkins
添加git下载信息 http://github.com/lizhenliang/tomcat-java-demo.git
Jenkins
添加字符参数,打包
Jenkins
Jenkins
添加字符参数 定义tomcat路径
Jenkins
Jenkins
添加文本参数 定义客户端ip
Jenkins
Jenkins
编写流水线脚本
pipeline {
    agent any

    stages {
        stage('pull code') {
            steps {
                git "http://github.com/lizhenliang/tomcat-java-demo.git"
            }
        }
        stage('package') {
            steps {
                sh """
                mvn clean
                mvn package
"""
            }
        }
        stage('deploy') {
            steps {
                                sh """
                                scp target/ly-simple-tomcat-0.0.1-SNAPSHOT.war root@192.168.222.139:/usr/local/tomcat/webapps/
                                ssh root@192.168.222.139 '/usr/local/tomcat/bin/catalina.sh stop && /usr/local/tomcat/bin/catalina.sh start'
"""
            }
        }
    }
}

Jenkins
进行创建,并查看刚刚定义好的变量参数值
Jenkins
构建
Jenkins
Jenkins
在node2上面查看刚刚脚本创建的内容
[root@node2 ~]# cd /usr/local/tomcat/webapps/
[root@node2 webapps]# ls
ROOT  examples      ly-simple-tomcat-0.0.1-SNAPSHOT      manager
docs  host-manager  ly-simple-tomcat-0.0.1-SNAPSHOT.war

进行访问
http://192.168.222.139:8080/ly-simple-tomcat-0.0.1-SNAPSHOT/

Jenkins

Original: https://www.cnblogs.com/tushanbu/p/16744355.html
Author: 涂山布
Title: Jenkins

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/573936/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • vim分屏功能总结

    vim的分屏功能总结起来,基本都是ctrl+w然后加上某一个按键字母,触发一个功能。(1)在shell里打开几个文件并且分屏:vim -On file1 file2 ……

    Linux 2023年6月14日
    098
  • Docker 环境 Nacos2 MySQL8

    本文介绍 docker 环境下安装并单机运行 Nacos2,使用 docker 环境下的 MySQL 8 存储数据。 1 拉取镜像 1.1 创建目录 在硬盘上创建 nacos 的有…

    Linux 2023年6月7日
    0100
  • linux定时删除N天前的旧文件

    语句写法: find 对应目录 -mtime +天数 -name “文件名” -exec rm -rf {} \; 例1:find /usr/local/b…

    Linux 2023年6月13日
    0108
  • sed语句用法

    sed编辑器 sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要…

    Linux 2023年6月6日
    099
  • 版本控制gitlab

    版本控制gitlab 版本控制gitlab 什么是版本控制gitlab gitlab部署 什么是版本控制gitlab GitLab 是一个用于仓库管理系统的开源项目,使用Git作为…

    Linux 2023年6月6日
    0112
  • Python eval()函数

    The eval() takes three parameters: expression – this string as parsed and evaluated …

    Linux 2023年6月8日
    0100
  • 我写的 Python 代码,同事都说好

    人生苦短,我用 Python。 程序员的追求就是不写代码,早日财务自由。不对,一不小心把实话说出来了,应该是将代码写得简洁,优雅。 Python 程序员的追求则是 Pythonic…

    Linux 2023年6月7日
    0109
  • mac如何安装FinalShell

    1、Mac一键安装脚本: curl -o finalshell_install.sh www.hostbuf.com/downloads/finalshell_install.sh…

    Linux 2023年5月28日
    0102
  • Redis-firewall使用命令

    Redis-firewall使用命令 一、iptables防火墙 1、基本操作 查看防火墙状态 service iptables status 停止防火墙 service ipta…

    Linux 2023年6月14日
    0103
  • 剑指offer计划25(模拟中等)—java

    1.1、题目1 剑指 Offer 29. 顺时针打印矩阵 1.2、解法 常规开头,先判断特殊情况,然后创建四个变量存放矩阵四边的长度限制。创建res数组存放结果。循坏开始,遍历完一…

    Linux 2023年6月11日
    098
  • 国庆专属头像一键生成搭建教程,附源码!

    国庆节马上就要来啦! 没有一个像样的微信头像怎么行。 为此小编为大家带来了一款国庆节国旗头像生成源码,有服务器、域名的朋友可以自行下载上传至服务器之后提供给大家使用。 没有服务器、…

    Linux 2023年6月7日
    0128
  • 用 Redis 做一个可靠的延迟队列

    抢先体验 本文的完整代码实现在hdt3213/delayqueue,可以直接使用 go get 安装: go get github.com/hdt3213/delayqueue 使…

    Linux 2023年5月28日
    0111
  • JS 模块化- 04 CMD 规范与 Sea JS

    1 CMD 规范介绍 CMD: Common Module Definition, 通用模块定义。与 AMD 规范类似,也是用于浏览器端,异步加载模块,一个文件就是一个模块,当模块…

    Linux 2023年6月6日
    0116
  • [编程一生]历史文章分类汇总

    2021年过去了,总结一下我的239篇原创。方便大家利用自带的搜索功能当智能机器人来用。 面试类 方法论 架构类 网络通信与 操作系统原理 稳定性建设 Java 中间件 程序人生 …

    Linux 2023年6月13日
    094
  • Ubuntu Typora安装

    Ubuntn Typora安装 现在好像开始收费了,网上给的方法都是从官网下载的,感觉迟早不能用,因为要钱了 官网好像给的安装方法如下,可是好像不太好用 or run: sudo …

    Linux 2023年6月14日
    0102
  • 致远 OA 组合 getshell

    测试版本为: 致远 A8-V5 协同管理软件 V6.1SP2 1.获取cookie信息 2….

    Linux 2023年5月28日
    0318
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球