DevOps系列文章之 GitLab CI/CD

CICD是什么?

由于目前公司使用的gitlab,大部分项目使用的CICD是gitlab的CICD,少部分用的是jenkins,使用了gitlab-ci一段时间后感觉还不错,因此总结一下

介绍gitlab的CICD之前,可以先了解CICD是什么

我们的开发模式经历了如下的转变:瀑布模型->敏捷开发→DevOps(Development、Operations的组合词,是一组过程、方法与系统的统称)

后来随着DevOps的兴起,出现了持续集成(Continuous Integration)、持续交付(Continuous Delivery) 、持续部署(Continuous Deployment) 的新方法,关于持续集成、持续交付、持续部署,总结如下:

  • 持续集成的重点是将各个开发人员的工作集合到一个代码仓库中。通常,每天都要进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。
  • 持续交付的目的是最小化部署或释放过程中固有的摩擦。它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布(理想情况下)。
  • 持续部署是一种更高程度的自动化,无论何时对代码进行重大更改,都会自动进行构建/部署。

持续集成的好处是什么?

持续集成可以使问题尽早暴露,从而也降低了解决问题的难度,持续集成无法消除bug,但却能大大降低修复的难度和时间。

持续交付的好处是什么?

持续交付的好处在于快速获取用户反馈;适应市场变化和商业策略的变化。开发团队保证每次提交的修改都是可上线的修改,那么决定何时上线,上线哪部分功能则完全由产品业务团队决定。

虽然持续交付有显著的优点,但也有不成立的时候,比如对于嵌入式系统的开发,往往需要软硬件的配合。

持续部署的好处是什么?

持续部署的目标是通过减少批量工作的大小,并加快团队工作的节奏,帮助开发团队在其开发流程中消除浪费。这使团队能够一直处于一种可持续的平稳流状态, 让团队更容易去创新、试验,并达到可持续的生产率

市面上的CI有很多,如果在github上搜一下ci工具,也会搜到很多,比如:

  1. Travis CI
  2. Circle CI
  3. Jenkins
  4. AppVeyor
  5. CodeShip
  6. Drone
  7. Semaphore CI
  8. Buildkite
  9. Wercker
  10. TeamCity

这里只介绍Gitlab-CI

Gitlab-CI

在这里插入图片描述

  • 项目页面:

    Continuous Integration and Delivery | GitLab

  • 源代码:

    GitLab.org / GitLab FOSS · GitLab

  • 遵循 MIT 许可协议

GitLab 是 CI/CD 领域的一个新手玩家,但它已经在 Forrester Wave 持续集成工具中占据了领先地位。在这样一个竞争对手众多而水平又很高的领域,这是一项巨大的成就。是什么让 GitLab CI 如此了不起?

  • 它使用 YAML 文件来描述整个管道。
  • 它还有一个功能叫 Auto DevOps,使比较简单的项目可以自动构建内置了若干测试的管道。
  • 使用 Herokuish 构建包来确定语言以及如何构建应用程序。有些语言还可以管理数据库,对于构建新的应用程序并在开发过程一开始就将其部署到生产环境中,这是一个很重要的功能。
  • 提供到 Kubernetes 集群的原生集成,并使用多种部署方法的一种(如基于百分比的部署和蓝绿部署)将应用程序自动部署到 Kubernetes 集群中。

除了 CI 功能之外,GitLab 还提供了许多补充功能,比如自动把 Prometheus 和你的应用程序一起部署,实现运行监控;使用 GitLab 问题(Issues)、史诗(Epics)和里程碑(Milestones)进行项目组合和项目管理;管道内置了安全检查,提供跨多个项目的聚合结果;使用 WebIDE 在 GitLab 中编辑代码的能力,它甚至可以提供预览或执行管道的一部分,以获得更快的反馈。

相关概念

pipeline(管道、流水线)

  • 一次 Pipeline 其实相当于一次构建任务,里面可以包含多个流程(Stage),比如自动构建、自动进行单元测试、自动进行代码检查等流程 ;
  • 任何提交或者 Merge Request 的合并都可以触发 Pipeline ;

Stage(构建阶段)

  • Stage表示构建阶段,就是上面提到的流程 ;
  • 可以在一次 Pipeline中定义多个 Stage;
  • Stage有如下特点 :
    • 所有 stages 会按照顺序运行,即当一个 stage 完成后,下一个 Stage才会开始
    • 只有当所有 Stage 成功完成后,该构建任务 Pipeline 才算成功
    • 如果任何一个 Stage失败,那么后面的 Stage 不会执行,该构建任务 (Pipeline) 失败

阶段是对批量的作业的一个逻辑上的划分,每个 pipeline都必须包含至少一个 Stage。多个 Stage是按照顺序执行的,如果其中任何一个 Stage失败,则后续的 Stage不会被执行,整个 CI 过程被认为失败。

Jobs(任务)

  • job表示构建工作,表示某个stage里面执行的工作 ;
  • 一个stage里面可以定义多个job ;
  • jobs有如下特点 :
    • 相同 stage 中的jobs 会并行执行
    • 相同 stage 中的 jobs 都执行成功时,该 stage 才会成功
    • 如果任何一个job 失败,那么该 stage 失败,即该构建任务 (Pipeline) 失败

举一个例子,比如下面这个图:

在这里插入图片描述

这里的四个Statge(阶段): Verify、Build、Dockerpush、Deploy四个,这四个阶段组成一条Pipeline

每个阶段都有一个job,所以总共四个job,也就是unit-testjava-packagedocker-pushservice-1这四个,当然,每个stage可以由多个job组成,比如下面这个图:

Job 的执行过程中往往会产生一些数据,默认情况下 GitLab Runner 会保存 Job 生成的这些数据,然后在下一个 Job 执行之前(甚至不局限于当次 CI/CD)将这些数据恢复。这样即便是不同的 Job 运行在不同的 Runner 上,它也能看到彼此生成的数据。

.gitlab-ci.yml中提供了 before_script 和 after_script 两个全局配置项。这两个配置项在所有 Job 的 script 执行前和执行后调用。

关于.gitlab-ci.yml、before_script、after_script是什么,先别急,在后面有介绍

在了解了 Job 配置的 script、before_script、after_script 和 cache 以后,可以将整个 Job 的执行流程用一张图概括:

在这里插入图片描述

所以了解了Pipeline、Stage、Jobs后,还有一个很重要的东西,就是Runner

Runner

Runner就像一个个的工人,而Gitlab-CI就是这些工人的一个管理中心,所有工人都要在Gitlab-CI里面登记注册,并且表明自己是为哪个工程服务的。当相应的工程发生变化时,Gitlab-CI就会通知相应的工人执行软件集成脚本。如下图所示:

在这里插入图片描述

gitlab里面的runner叫Gitlab-Runner,Gitlab-Runner是配合Gitlab-CI进行使用的。一般地,Gitlab里面的每一个工程都会定义一个属于这个工程的软件集成脚本,用来自动化地完成一些软件集成工作。当这个工程的仓库代码发生变动时,比如有人push了代码,GitLab就会将这个变动通知Gitlab-CI。这时Gitlab-CI会找出与这个工程相关联的Runner,并通知这些Runner把代码更新到本地并执行预定义好的执行脚本(也就是在Job执行流程那个图中所示的第三步:script),所以,Gitlab-Runner就是一个用来执行软件集成脚本script的东西。

Runner类型

Gitlab-Runner可以分类两种类型:Shared Runner(共享型)Specific Runner(指定型)

  • Shared Runner:这种Runner(工人)是所有工程都能够用的。只有系统管理员能够创建Shared Runner。
  • Specific Runner:这种Runner(工人)只能为指定的工程服务。拥有该工程访问权限的人都能够为该工程创建Shared Runner。

关于Gitlab-runner的安装,会以单独一个文章进行介绍,注册runner会对应一个tag,记住这个tag;

.gitlab-ci.yml简介

.gitlab-ci.yml 文件被用来管理项目的 runner 任务,Gitlab CI通过.gitlab-ci.yml文件管理配置job,该文件定义了statge顺序、job应该如何触发和工作、执行什么脚本、如何构建pipeline等流程

该文件存放于仓库的根目录, 默认名为.gitlab-ci.yml

我们先看一个简单的例子:.gitlab-ci.yml

## 定义pipeline流程:verify->build->dockerpush->deploy
stages:
  - verify
  - build
  - dockerpush
  - deploy

#单元测试
unit-test:
  stage: verify # 属于哪个流程
  tags:
    - test-cicd # 在哪个runner上面执行,在注册runner可以自定义
  script:
    - echo unit-test # 执行脚本

#java编译
java-package:
  stage: build
  tags:
    - test-cicd
  script:
    - echo build

#push镜像
docker-push:
  stage: dockerpush
  tags:
    - test-cicd
  script:
    - echo docker-push

#deploy
service-1:
  stage: deploy
  tags:
    - test-cicd
  script:
    - echo deploy

该配置对应下面的pipeline,test-cicd是一个Specific Runner,执行脚本的类型是shell

在这里插入图片描述

所以,以unit-test这个job为例,点击该任务可以进入到log界面查看整个log执行流程

在这里插入图片描述

在这里插入图片描述

剩下的job的执行日志都大部分如此,就不一一列举了

几个重要的关键字解析

关于gitlab-ci.yml,里面有很多关键字配置,下面我主要列举一些比较常用的关键字

before_script和after_script

随着项目越来越大,Job 越来越多,Job 中包含的重复逻辑可能会让配置文件臃肿不堪。.gitlab-ci.yml 中提供了 before_script 和 after_script 两个全局配置项。这两个配置项在所有 Job 的 script 执行前和执行后调用。

before_script 和 script 在一个上下文中是串行执行的,after_script 是独立执行的。所以根据执行器(在runner注册的时候,可以选择执行器,docker,shell 等)的不同,工作树之外的变化可能不可见,例如,在before_script中执行软件的安装。

你可以在任务中定义 before_scriptafter_script,也可以将其定义为顶级元素,定义为顶级元素将为每一个任务都执行相应阶段的脚本或命令。

stages

stages的允许定义多个,灵活的场景阶段的pipline。定义的元素的顺序决定了任务执行的顺序。例如:

## 定义pipeline流程:verify->build->dockerpush->deploy
stages:
  - verify
  - build
  - dockerpush
  - deploy
  • build场景的任务将被并行执行。test、deploy 同理
  • build 任务成功后,test 执行。test 成功后,deploy 执行
  • 所有的都成功了,提交将会标记为成功
  • 任何一步任务失败了,提交标记为失败并之后的场景,任务都不回执行。

tags

tags可以从允许运行此项目的所有Runners中选择特定的Runners来执行jobs。

在注册Runner的过程中,我们可以设置Runner的标签,tags可通过tags来指定特殊的Runners来运行jobs:

#单元测试
unit-test:
  stage: verify # 属于哪个流程
  tags:
    - test-cicd # 在哪个runner上面执行,在注册runner可以自定义

script

script是一段由Runner执行的shell脚本,可以执行多个,例如:

job:
    script: mvn clean test

这个参数也可以使用数组包含好几条命令

job:
    script:
        - pwd
        - mvn clean test

only and except

only和except两个参数说明了job什么时候将会被创建:

  • only定义了job需要执行的所在分支或者标签
  • except定义了job不会执行的所在分支或者标签

以下是这两个参数的几条用法规则:

  • only和except如果都存在在一个job声明中,则所需引用将会被only和except所定义的分支过滤.
  • only和except允许使用正则
  • onlyexcept可同时使用。如果onlyexcept在一个job配置中同时存在,则以only为准,跳过except(从下面示例中得出)。
  • onlyexcept允许使用特殊的关键字:branchestagstriggers
  • onlyexcept允许使用指定仓库地址但不是forks的仓库(查看示例3)。

例子解析:

1.job将会只在issue-开头的refs下执行,反之则其他所有分支被跳过:

job:
    # use regexp
    only:
        - /^issue-.*$/
    # use special keyword
    except:
        - branches

2.job只会在打了tag的分支,或者被api所触发,或者每日构建任务上运行

job:
    # use special keywords
    only:
        - tags      # tag 分支 commit 之后触发
        - triggers  # API 触发
        - schedules # 每日构建触发

3.job将会在父仓库gitlab-org/gitlab-ce的非master分支有提交时运行。

job:
    only:
        - branches@gitlab-org/gitlab-ce
    except:
        - master@gitlab-org/gitlab-ce

when

when可以设置以下值:

  1. on_success - 只有前面stages的所有工作成功时才执行。 这是默认值。
  2. on_failure - 当前面stages中任意一个jobs失败后执行。
  3. always - 无论前面stages中jobs状态如何都执行。
  4. manual - 手动执行(GitLab8.10增加)。
stages:
- build
- cleanup_build
- test
- deploy
- cleanup
 
build_job:
  stage: build
  script:
  - make build
 
cleanup_build_job:
  stage: cleanup_build
  script:
  - cleanup build when failed
  when: on_failure
 
test_job:
  stage: test
  script:
  - make test
 
deploy_job:
  stage: deploy
  script:
  - make deploy
  when: manual
 
cleanup_job:
  stage: cleanup
  script:
  - cleanup after jobs
  when: always

脚本说明:

  • 只有当build_job失败的时候才会执行`cleanup_build_job 。
  • 不管前一个job执行失败还是成功都会执行`cleanup_job 。
  • 可以从GitLab界面中手动执行deploy_jobs。

manual:

  • 在GitLab的用户界面中显示该作业的“播放”按钮
  • 意味着deploy_job仅在单击“播放”按钮时才会触发job。

修改上面那个例子

stages:
  - verify
  - build
  - dockerpush
  - deploy
  - cleanup

before_script:
  - pwd
after_script:
  - echo after_script

#单元测试
unit-test:
  stage: verify
  tags:
    - test-cicd
  script:
    - echo unit-test

#java编译
java-package:
  stage: build
  tags:
    - test-cicd
  script:
    - echo build

#push镜像
docker-push:
  stage: dockerpush
  tags:
    - test-cicd
  script:
    - echo docker-push

#deploy
service-1:
  stage: deploy
  tags:
    - test-cicd
  script:
    - echo deploy
  when: manual # 手动触发job,只有点击按钮才会触发

cleanup_job:
  stage: cleanup
  script:
    - echo clean up
  when: always # 前面的job成功与否,都会执行该job

pipeline如下:

在这里插入图片描述

allow_failure

when一起控制job执行与否的配置还有一个就是allow_failure

allow_failure可以用于当你想设置一个job失败的之后并不影响后续的CI组件的时候。失败的jobs不会影响到commit状态。

下面的这个例子中,java-packagejava-package2将会并列进行,如果java-package2失败了,它也不会影响进行中的下一个stage,因为这里有设置了allow_failure: true。

stages:
  - verify
  - build
  - dockerpush
  - deploy
  - cleanup

before_script:
  - pwd
after_script:
  - echo after_script

#单元测试
unit-test:
  stage: verify
  tags:
    - test-cicd
  script:
    - echo unit-test

#java编译
java-package:
  stage: build
  tags:
    - test-cicd
  script:
    - echo build

#java编译
java-package2:
  stage: build
  tags:
    - test-cicd
  script:
    - execute_script_that_will_fail # 该shell会导致job执行失败
  allow_failure: true # 不影响后面的任务进行

#push镜像
docker-push:
  stage: dockerpush
  tags:
    - test-cicd
  script:
    - echo docker-push

#deploy
service-1:
  stage: deploy
  tags:
    - test-cicd
  script:
    - echo deploy
  when: manual

cleanup_job:
  stage: cleanup
  tags:
    - test-cicd
  script:
    - echo clean up
  when: always

java-package2会执行错误

在这里插入图片描述

运行的pipeline如下,可见java-package2的执行错误

在这里插入图片描述

variables

GitLab CI允许你为.gitlab-ci.yml增加变量,该变量将会被设置入任务环境。通过两种方式可以引用

  • 美元符+大括号引用:${}
  • 美元符:$

示例如下:

variables:
  SOFT_VERSION: '1.0'
  TAG_NAME: 'xxx'
#构建镜像
docker-build:
  stage: dockerpush
  tags:
    - test-cicd
  script:
    - docker build -t $TAG_NAME:${SOFT_VERSION}

如果有些值不想在配置文件中显示,比如密码什么的,可以在代码仓库中setting->CICD->Variables 自定义变量,跟在.gitlab-ci.yml配置变量效果是一样的

在这里插入图片描述

variables的保留字

gitlab-ci有一些预定义变量,这些变量大部分以CI开头

预定义变量:
VariableGitLabRunnerDescription
CIall0.4标识该job是在CI环境中执行
CI_COMMIT_REF_NAME9.0all用于构建项目的分支或tag名称
CI_COMMIT_REF_SLUG9.0all先将$CI_COMMIT_REF_NAME的值转换成小写,最大不能超过63个字节,然后把除了0-9a-z的其他字符转换成-。在URLs和域名名称中使用。
CI_COMMIT_SHA9.0allcommit的版本号
CI_COMMIT_TAG9.00.5commit的tag名称。只有创建了tags才会出现。
CI_DEBUG_TRACE9.01.7debug tracing开启时才生效
CI_ENVIRONMENT_NAME8.15alljob的环境名称
CI_ENVIRONMENT_SLUG8.15all环境名称的简化版本,适用于DNS,URLs,Kubernetes labels等
CI_JOB_ID9.0allGItLab CI内部调用job的一个唯一ID
CI_JOB_MANUAL8.12all表示job启用的标识
CI_JOB_NAME9.00.5.gitlab-ci.yml中定义的job的名称
CI_JOB_STAGE9.00.5.gitlab-ci.yml中定义的stage的名称
CI_JOB_TOKEN9.01.2用于同GitLab容器仓库验证的token
CI_REPOSITORY_URL9.0allgit仓库地址,用于克隆
CI_RUNNER_DESCRIPTION8.100.5GitLab中存储的Runner描述
CI_RUNNER_ID8.100.5Runner所使用的唯一ID
CI_RUNNER_TAGS8.100.5Runner定义的tags
CI_PIPELINE_ID8.100.5GitLab CI 在内部使用的当前pipeline的唯一ID
CI_PIPELINE_TRIGGEREDallall用于指示该job被触发的标识
CI_PROJECT_DIRallall仓库克隆的完整地址和job允许的完整地址
CI_PROJECT_IDallallGitLab CI在内部使用的当前项目的唯一ID
CI_PROJECT_NAME8.100.5当前正在构建的项目名称(事实上是项目文件夹名称)
CI_PROJECT_NAMESPACE8.100.5当前正在构建的项目命名空间(用户名或者是组名称)
CI_PROJECT_PATH8.100.5命名空间加项目名称
CI_PROJECT_PATH_SLUG9.3all$CI_PROJECT_PATH小写字母、除了0-9a-z的其他字母都替换成-。用于地址和域名名称。
CI_PROJECT_URL8.100.5项目的访问地址(http形式)
CI_REGISTRY8.100.5如果启用了Container Registry,则返回GitLab的Container Registry的地址
CI_REGISTRY_IMAGE8.100.5如果为项目启用了Container Registry,它将返回与特定项目相关联的注册表的地址
CI_REGISTRY_PASSWORD9.0all用于push containers到GitLab的Container Registry的密码
CI_REGISTRY_USER9.0all用于push containers到GItLab的Container Registry的用户名
CI_SERVERallall标记该job是在CI环境中执行
CI_SERVER_NAMEallall用于协调job的CI服务器名称
CI_SERVER_REVISIONallall用于调度job的GitLab修订版
CI_SERVER_VERSIONallall用于调度job的GItLab版本
ARTIFACT_DOWNLOAD_ATTEMPTS8.151.9尝试运行下载artifacts的job的次数
GET_SOURCES_ATTEMPTS8.151.9尝试运行获取源的job次数
GITLAB_CIallall用于指示该job是在GItLab CI环境中运行
GITLAB_USER_ID8.12all开启该job的用户ID
GITLAB_USER_EMAIL8.12all开启该job的用户邮箱
RESTORE_CACHE_ATTEMPTS8.151.9尝试运行存储缓存的job的次数

更多配置,可以参考官方参考文档:CI/CD YAML syntax reference | GitLab

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/339834.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣刷MySQL-第五弹(详细讲解)

🎉欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹 ✨博客主页:小小恶斯法克的博客 🎈该系列文章专栏:力扣刷题讲解-MySQL 🍹文章作者技术和水平很有限,如果文中出…

超级菜鸟怎么学习数据分析?

如果你有python入门基础,在考虑数据分析岗,这篇文章将带你了解:数据分析人才的薪资水平,数据人应该掌握的技术栈。 首先来看看,我在搜索数据分析招聘时,各大厂开出的薪资: 那各大厂在数据领域…

【Spring 篇】MyBatis多表操作:编织数据的交响乐

欢迎来到MyBatis的多表操作世界!在这个充满交响乐的舞台上,我们将探索如何巧妙地编织多个数据表的数据,创造出一场旋律动听的数据交响曲。无需繁琐的SQL拼接,MyBatis让多表操作变得优雅而简单。让我们一起进入这个音乐殿堂&#x…

二.Winform使用Webview2在Demo1中实现地址简单校验

Winform使用Webview2在Demo1中实现地址简单校验 往期目录回顾添加对于的简单url验证提示通过上节和本节涉及到的函数有 往期目录 往期相关文章目录 专栏目录 回顾 通过一.Winform使用Webview2(Edge浏览器核心) 创建demo(Demo1)实现回车导航到指定地址 我们已经知道了解决资源…

裁员背景下 | 【2024年人生的里程碑】作为独立开发者,第一次承接外包项目的心得经历,也许说出你的心声哦!

🚪 每日一句 种子不落在肥土而落在瓦砾中,有生命力的种子决不会悲观和叹气,因为有了阻力才有磨炼。 背景介绍 在裁员背景下,寻找自主承包项目成为了一种可行且具有吸引力的选择。对于职业技术人员而言,自主承包项目不…

【服务器】Xshell与Xftp软件的使用指南

目录 【Xshell软件】 1.1 Xshell软件的功能 1.2 Xshell软件的使用 【Xftp软件】 2.1 Xftp软件的功能 2.2 Xftp软件的使用 可替代产品【FinalShell】 3.1 FinalShell软件的使用 3.2 FinalShell连接服务器失败解决方法 可替代产品【FileZilla】

暴力破解常见的服务器

目录 使用 pydictor 生成自己的字典工具liunx下载使用常用的参数说明插件型字典 (可自己根据 API 文档开发) 使用 hydra 工具在线破解系统用户密码使用 hydra 破解 windows 7 远程桌面密码使用 hydra 工具破解 ssh 服务 root 用户密码 使用 Medusa 工具在线破解medusa参数说明M…

STM32之RTC实时时钟

一、实时时钟概述 1、实时时钟介绍 英文缩写:RTC。显示年、月、日、时、分、秒、星期,自动计算闰年,能够区分每个月的天数。 RTC特点:能从RTC获取到具体的日期时间,断掉后再开机时间仍然准确(需要纽扣电池&#xff…

JSON简单了解

文章目录 1、JSON介绍2、ES6模版字符串3、JS对象转化为JSON字符串3.1、手动JS对象转化为JSON字符串3.2、自动JS对象转化为JSON字符串 4、JS对象和java互相转换 1、JSON介绍 JSON 概念:JavaScript Object Notation。JavaScript 对象表示法,简单理解JSON是…

如何控制项目管理中的日程冲突?

《全球公司生产力报告》发现,62% 的公司领导表示,资源调度是他们在项目管理方面面临的最大挑战。其中,日程冲突是利用共享资源池管理多个项目的典型挑战。例如,团队成员参与的活动可能会重叠,也可能是任务分配给了无法…

设计模式篇---中介者模式

文章目录 概念结构实例总结 概念 中介者模式:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 就好比世界各个国家之间可能会产生冲突,但是当产…

乡镇县城小市场的外卖服务需求,现在是属于谁的机遇?

目前,县域经济正面临着几大利好。“返乡就业、返乡创业和告老还乡”现象越发普遍,这不仅在小县城中有所体现,同样在乡镇中也呈现出同样的趋势。一些产业链和工厂纷纷下沉到乡镇,带来了更多的就业机会。这不仅能够吸引年轻人回乡就…

【C初阶——基础刷题】刷题8

本文由睡觉待开机原创,转载请注明出处。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言,共同进步! 这里写目录标题 题目链接T1:T2:T3:T4:T5:T6:T7:T8:…

行云部署前端架构解析-前言 | 京东云技术团队

一个简单的自我介绍 项目规模 截止目前上万次代码提交,总代码行数1超过21万行,其中人工维护的代码超过 13万行,近千个文件。 前端线上服务直接对接的后端服务,达十多个。 跟很多应用一样, 它有行云的入口, 也有独立的服务, 还…

【Linux】python版本控制和环境管理

文章目录 1.查看目前python的版本2.添加软件源并更新3.选择你想要下载的版本4.警示:没必要设置默认版本误区千万千万不要覆盖python3软链接解决办法 5.pip软件包管理最省心稍微麻烦换源 网上有很多教程都是教导小白去官方下载之后编译安装。但是,小白连c…

【数据结构】 循环单链表的基本操作 (C语言版)

目录 一、循环单链表 1、循环单链表的定义: 2、循环单链表的优缺点: 二、循环单链表的基本操作算法(C语言) 1、宏定义 2、创建结构体 3、循环单链表的初始化 4、循环单链表的插入 5、求单链表长度 6、循环单链表的清空…

<信息安全>《2 国内主要企业网络安全公司概览(二)》

4 北京天融信科技有限公司(简称天融信) 信息内容LOGO成立日期创始于1995年总部北京市海淀区上地东路1号院3号楼北侧301室背景民营企业是否上市天融信[002212]A股市值99亿主要产品网络安全大数据云服务员工规模6000多人简介天融信科技集团(证券代码:0022…

Java多线程并发篇----第二十九篇

系列文章目录 文章目录 系列文章目录前言一、什么是不可变对象,它对写并发应用有什么帮助二、Java 中用到的线程调度算法是什么?三、什么是线程组,为什么在 Java 中不推荐使用?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点…

功能最强大的在线考试、投票系统,支持一键部署,开源了

简介 功能最强大&搭建最简单&界面更美观的在线考试/调查问卷/公开查询/题库刷题/360度评估/投票系统,支持一键部署。 特性 支持 20 多种题型,如填空、选择、下拉、级联、矩阵、分页、签名、题组、上传、横向填空等 多种创建问卷方式&#xff…

应用层—HTTP详解(抓包工具、报文格式、构造http等……)

文章目录 HTTP1. 抓包工具的使用1.1 配置信息1.2 观察数据 2. 分析 https 抓包结果3. HTTP请求详解3.1 认识 URL3.1.1 URL 基本格式3.1.2 查询字符串 (query string)3.1.3 关于 URL Encode 3.2 认识 http 方法3.2.1 [经典问题] Get 和 Post 主要的区别是什么?&#…
最新文章