jenkins 插件目录_10 个 Jenkins 实战经验,助你轻松上手持续集成

众所周知,持续构建与发布是我们日常工作中要面对的的一个重要环节,目前很多公司都采用 Jenkins 来搭建符合需求的 CI/CD 流程,作为一个持续集成的开源工具,它以安装启动方便,配置简单,上手容易的特点,深受广大用户的欢迎,通过笔者这几年在公司使用 Jenkins 集群,来完成公司日常各项目组持续集成和发布流程的经验,给大家分享几个实用的经验。

1、 修改 JVM 的内存配置

Jenkins 启动方式有两种方式,一种是以 Jdk Jar 方式运行,一种是将 War 包放在 Tomcat 容器下运行。不管何种方式运行,都会存在一个问题就是,默认 JVM 内存分配太少,导致启动或者运行一段时间后内存溢出报错 java.lang.OutOfMemoryError: PermGen space

所以,需要在启动前修改 JVM 内存配置。以 Tomcat 容器方式启动 Jenkins 为例配置如下:

# 进入到 Jenkins 运行所在 Tomcat conf 目录
$ vim catalina.sh
# 在 #JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask`" 行下增加修改配置 JVM 内存配置大小,例如下边配置:JAVA_OPTS="$JAVA_OPTS -server -Xms512m -Xmx1024m -XX:PermSize=256M -XX:MaxPermSize=512m"

注意:这里的几个 JVM 参数含义如下:

  • -Xms: 使用的最小堆内存大小

  • -Xmx: 使用的最大堆内存大小

  • -XX: PermSize: 内存的永久保存区域大小

  • -XX: MaxPermSize: 最大内存的永久保存区域大小

这几个参数也不是配置越大越好,具体要根据所在机器实际内存和使用大小配置。

2、修改 Jenkins 主目录

Linux 下 Jenkins 默认安装目录为 /var/lib/jenkins/,这个目录磁盘空间有限,长时间使用会导致磁盘空间不够,建议修改为其他大磁盘空间目录。这里修改安装目录有两种方式,一种是配置为系统环境变量中,一种是配置到 Tomcat 容器环境变量中。

配置 JENKINS_HOME 到系统环境变量里面

# 注意:如果一台机器只安装一个 Jenkins 时,可以配置如下。$vim /etc/profile
...
export JENKINS_HOME=/data0/jenkins
export PATH=$PATH:$JENKINS_HOME
# 使配置生效
$ source /etc/profile

配置 JENKINS_HOME 到该 Jenkins 启动的 Tomcat 容器环境变量中

# 注意:如果一台机器上边安装多个 Jenkins 时,不能配置 JENKINS_HOME 到系统环境变量里面,
# 需要配置 JENKINS_HOME 到该 Jenkins 启动的 Tomcat 容器配置里面,这样可以区分不同的 Jenkins 目录。$ vim /data0/scm/apache-tomcat-7.0.85/conf/context.xml

...
# 增加以下配置,优先获取该配置路径。

这里要说明一下,如果一台机器上只安装了一个 Jenkins 服务时,可以配置 JENKINS_HOME 到系统环境变量里面,如果安装了多个 Jenkins 服务时,不能这么配置,因为 Jenkins 会读取系统环境变量中 JENKINS_HOME 作为主目录安装,那样会存在配置覆盖的问题。

此时应该采用第二种方式,各自配置 JENKINS_HOME 到自己启动的 Tomcat 容器环境变量中,Jenkins 会优先读取该容器环境变量作为各自的主目录安装。

附 Jenkins 寻找 JENKINS_HOME 环境变量的顺序为:首先读取容器环境变量,如果没有,则读取系统环境变量,如果还没有,则使用默认路径安装。

3、配置优化减少磁盘空间占用

Jenkins 运行 Job 构建比较多时,如果没有配置好清理策略的话,会导致占用磁盘空间比较大,最终由于磁盘空间不够导致构建失败的问题。

3.1、丢弃旧的构建配置

我们可以在 Job 中配置丢弃旧的构建,通过设置 “保持构建的天数” 和 “保持构建的最大个数” 两个参数,控制该 Job 最大保存构建数量。

dc063e0e4c6e0f28dd32559c82c808fb.png

b506d2df07d3947e35cf35aca483d59d.png

如上图所示,我配置了最大保持 3 天之内的构建,如果超过 3 天的构建,则会在Job 执行前被清理掉。同时配置了最大保持构建数量为 10 个,意思就是如果 3 天内构建次数如果超过 10 次,则最多保留最近执行的 10 个构建。

这样配置的好处,除了能够自动清理一些 Build 之外,还能够为我们代码执行远程停止 Job Build 时,缩短停止时间,下边会讲到。

3.2、修改工作空间和构建记录根目录

Jenkins 工作主要分为安装主目录,工作空间目录以及构建记录目录,默认配置路径如下图所示:

21be8597aade5ba0309d51798a813f01.png

如果我们修改了 Jenkins 安装主目录之后,因为工作空间目录是在安装主目录下的 workspace 目录,构建目录在安装主目录下的 builds 目录,这样运行 Job 执行构建比较多时,还会存在磁盘空间不够的问题,那么此时可以在 “系统管理” —> “系统配置” —> “高级” 分别修改工作空间根目录和构建记录根目录,指向其他磁盘空间即可。

4、设置全局属性

适当设置全局属性,可以避免在 Job 中重复写一些固定值,例如输出日志地址、接口请求地址等等,而且当固定值需要修改时,只需要修改一次即可,不用去每个 Job 里面修改,方便维护。

我们可以去 “系统管理” —> “系统配置” —> “全局属性” 下增加 Environment variables 键值对,例如如下图:

1ff69fedd9df8c057cec9d0485cfde9f.png

那么,在 Job 构建时执行 “ Execute Shell” 使用时,可以直接应用即可,例如如下代码:

3921d6ac8b724dfcd76a0b0273d29e8a.png

5、JDK/Maven/Gradle 等软件多版本安装

对于一些常用的软件,比如 Jdk、Maven、Gradle等,可能每个项目对软件依赖版本不一样,有的项目依赖 Jdk7,有的依赖 Jdk8,所以为了更好的适配各个项目,可以指定安装多个版本软件,然后 Job 创建时选择其中一个版本使用。

这里以 Jdk 为例,去 “系统管理” —> “Global Tool Configuration” —> “JDK” 分别安装 jdk6、Jdk7、Jdk8。

244aac509939069463a34eeb1fc85200.png

然后,在创建 Job 时,选择项目需要的一个版本即可。

a3a4ecff94c7c38eb3cf562e32d3fefa.png

6、设置构建超时时间

有些 Job 在执行构建时,由于某些原因导致构建挂起,耗时比较长,而这些长时间挂起的 Job 会导致 Jenkins 内存占用比较大,性能下降,严重的会直接导致 Jenkins 挂掉。

所以,我们需要设置构建超时时间来预防这种事情发生,一旦超过一定的时间,要让 Job 自动停止掉。例如,这里我设置构建超过 30 分钟则将本次 Build 置为失败。

d30298adbb43c83be665259375f863c6.png

7、配置视图分类管理 Job

Jenkins 默认视图为 ALL 显示所有 Job 列表,如果 Job 比较多的话,找某个 Job 会不太方便,虽然有 Search 搜索功能,毕竟还是不太方便。

这时候,我们可以通过新建视图方式,对 Job 进行分门别类,这样管理和查找起来就方便多啦!例如这里我新建 “List View” 类型视图 “wy”,然后选择该视图所关联的 Job 就可以了。

fd6740848c550740e942f7a585e6e6e1.png

5391e2faaf0dd91863a818b3782a428b.png

这样通过视图切换,查找相关 Job 就方便多了。

8、配置多节点管理

一般我们会使用 Jenkins Slave 集群管理来完成日常持续集成操作,使用 Jenkins Slave 一主多从方式,可以将 Job 调度到对应的 Slave 机器上执行,能够大大提高系统并发执行效率。

我们可以从 “系统管理” —> “管理节点” —> “新建节点”,设置节点类型为 “Permanent Agent” 名称 “wy_slave0” 的一个从节点,当然有多个节点时,可以创建多个。

创建完毕之后,此时插件还属于不可用状态,因为还没有执行关联,具体关联方式可以参照 Jenkins 上节点关联说明(如下图,这里忽略操作),关联完毕之后,我们就可以在新建 Job 中配置指定那个 Slave 节点运行了。

f7f80afc75d27fcf9c4495102221451b.png

c39d7b7bc040ca9da09a8faa245d358c.png

5da4cb1922b646433bef6e81423b9e78.png

这里,有两种方式指定 Job 在那个 Slave 节点运行,一种是对于自由风格类型的 Job,我们可以通过在 “Restrict where this project can be run” 选项下指定 “Label Expression” 标签指定节点标签即可。

078b5f7133403d817987eadba1d32949.png

另一种是对于多配置项目类型的 Job,我们可以通过在 “Configuration Matrix” 先配置 “Slave” 选择 Node/Label 勾选指定一个或多个 Slave 执行。

2b6602d266ed3fb9d355d140a3eff65a.png

9、一些实用插件

Jenkins 的基础配置就能够满足我们日常的基本工作,但是为了提高构建效率和方便维护,Jenkins 上提供了很多实用的插件,使用这些插件,我们可以更加轻松、更加简便、更加高效的执行持续集成和发布流程。下边,我就简单介绍几个我使用的插件。

9.1、Locale 插件控制 Jenkins 页面国际化

默认 Jenkins 页面显示语言为英文,对于日常使用语言非英文的用户来说,就显得有点操作不便,该插件提供用户配置 Jenkins 页面国际化语言,例如中文、法语、泰文等等。

首先我们需要去 “Manage Jenkins” —> “Manage Plugins” —> “Available” 中选择 “Locale” 插件,点击 “Install without restart”,安装完不需要重启。

3660c353ba9192686ea1984a38cbcff3.png

安装完毕后,可以从 “Manage Jenkins” —> “Configure System” —> “Locale” 下 “Default Language” 输入框输入对应的语言英文缩写码,例如这里我想要简体中文,那么就需要填写 zh_CN,并勾选 “Ignore browser preference and force this language to all users” 复选框,来强制所有用户使用该配置。

7cb04aa10fd8e0db2fc56a47ec06d504.png

点击 “Save”,再次查看页面,页面大部分都已经显示为对应的中文简体了,包括各个 Job 配置页面部分也显示为中文简体了,这下很直观了。

67fefc4cf175f6808c79ab52f025b6f6.png

7c01aa47a2530d3b35d2e34ed6e190e3.png

9.2、Build Name Setter & Description Setter 插件支持自定义 Build 名称和描述

Build Name Setter 和 Description Setter 插件可以支持修改每次构建的 Name 名称和 Description 描述信息,默认 Jenkins 每次构建名称为 #ID + 构建时间(ID 自增),且无描述信息。

这样的弊端就是当某次构建出现了错误或者要排查某次构建信息,除了按构建时间区间挨个去点开日志,别无他法,而该插件可以很好的解决该问题。

使用该插件,我们可以为每次构建设置自定义名称和描述信息,名称支持从文件中读取和 macro 模板,描述信息还支持 RegEx 表达式来从构建日志中提取信息。首先我们需要去 “系统管理” —> “管理插件” —> “可选插件” 中选择 “Build Name Setter” 和 “Description Setter” 插件,安装完不需要重启。

617aeebcdc7593270c44260a9bb2c95d.png

接下来我们创建一个简单的示例 Job 来使用一下这两个插件。新建名称为 “wy_tt” 的 Job,接收两个参数 version 和 branch,然后配置 Build Name 为 # ${BUILD_NUMBER}-${branch},Build Description 为 构建版本:${version}

bc8ff1c00b308e2d91f015023a22f321.png

执行几次构建,每次修改传递的参数,此时去 Job 左侧构建历史里面,就可以看到每次构建的一些重要的辅助信息,这样将大大方便我们排查问题了。当然,我们还可以更高级的使用该插件,比如从文件中读取参数,使用表达式从构建日志中匹配 Key 值,这样功能将更加强大了。

b67a95d29a706a8a208cd774acbd89d7.png

9.3、Managed Script 插件管理脚本文件

该插件是为了在管理文件时创建 Script 脚本文件,然后在 Job 中配置直接使用,方便脚本的统一管理和维护。首先我们需要去 “系统管理” —> “管理插件” —> “可选插件” 中选择 “Managed script” 插件,安装重启即可。

613349cf0364e30c4e1453ce07f724d7.png

617a83f5428a3ca876ecd89faf6e1725.png

注意: 这里的脚本可以使用一些 Jenkins 系统的环境变量参数、参数化构建时传递的参数以及系统命令哦。

创建完毕后,我们在 Job 中构建处选择 “Execute managed script” 就可以使用这些脚本了。

993864f155b479ce05ab9c28832a60ea.png

9.4、PostBuildScript 插件根据 Build 状态执行脚本

推荐安装 PostBuildScript 插件,该插件可以在构建后操作中,根据构建结果状态,执行对应的脚本操作,很实用的一个插件。

同上安装该插件,重启 Jenkins 完毕插件生效后,Job 中构建后操作处选择 “Execute Scripts” ,然后在 “Add build step” 中选择 “Execute shell” 等选项(当然也可以配合上一个插件,那么这里就选择 “Execute managed script”),下边选择一个 build 状态条件值,如果选择 SUCCESS 状态,那么该脚本只有在 Build 成功时才会执行,其他状态依次类推,状态可以多选哦,多选代表多种状态都能下触发。

85819cbdcde28ce9dc7e4ab1771a60a6.png

9.5、Jenkins2.0 Pipeline 插件执行持续集成发布流程

Jenkins 2.0 的精髓是 Pipeline as Code,是帮助 Jenkins 实现 CI 到 CD 转变的重要角色。Pipeline是一套运行于 Jenkins 上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程。

Pipeline 中任何发布流程都可以表述为一段 Groovy 脚本,并且 Jenkins 支持从代码库直接读取脚本。使用 Pipeline 执行持续集成发布流程好处是显而易见的,它可以把以前需要多个节点上多个 Job 使用一段脚本来替代,而且脚本语言功能强大,可以很好的完成一些复杂的流程操作,推荐大家尝试使用。这里就不多说了,详细可以参考之前文章 初试Jenkins2.0 Pipeline持续集成。

9.6、Kubernetes Plugin 插件动态创建 Jenkins Slave

我们知道传统的 Jenkins Slave 一主多从方式会存在一些痛点,比如 Master 单点故障,Slave 配置环境差异,资源分配不均衡等导致可靠性和可维护性比较差,而使用 Kubernetes Plugin 插件可以动态的创建和删除 Jenkins Slave 节点,使用它可以很好的保证服务高可用,动态伸缩合理使用资源,以及良好的扩展性。

使用该插件后,它的工作流程大致为:当 Jenkins Master 接受到 Build 请求时,会根据配置的 Label 动态创建一个运行在 Docker Container 中的 Jenkins Slave 并注册到 Master 上,当运行完 Job 后,这个 Slave 会被注销并且 Docker Container 也会自动删除,恢复到最初状态。这里也不多说了,详细可以参考之前文章 初试 Jenkins 使用 Kubernetes Plugin 完成持续构建与发布。

10、JAVA 代码触发 Jenkins Job 创建、删除、停止等操作

Jenkins Job 创建、删除、构建等操作,除了在页面手动操作外,我们还可以通过 Jenkins API 接口执行对应操作,详细接口可参考 Jenkins
REST API 文档地址:http:///api。这里我要演示的是使用 Jenkins-client.jar 包,使用 JAVA 代码操作如何创建、删除、停止、触发构建等,使用代码触发 jenkins 相关操作,好处就是自己可控,这样可以配合自己的业务需要,随时启动或者新建 Job 啦。

public class JenkinsUtils {

private static String jenkins_url = "http://127.0.0.1/jenkins/";
private static String jenkins_user = "admin";
private static String jenkins_token = "1b356d175432ed0d34c440d68d00fe49";

/**
* 通过模板创建 Job
* @param jobName
* @param jobTemplate
* @return
*/
public static boolean createJobFromTemplate(String jobName, String jobTemplate) {
try {
URI uri = new URI(jenkins_url);
JenkinsServer jenkins = new JenkinsServer(uri, jenkins_user, jenkins_token);
String template = jenkins.getJobXml(jobTemplate);
Document doc = DocumentHelper.parseText(template);
String newConfigXml = doc.asXML();
jenkins.createJob(jobName, newConfigXml, false);
}catch (Exception e){
e.printStackTrace();
return false;
}
return true;
}

/**
* 删除/禁用 Job
* @param jobName
* @return
*/
public static boolean deleteJob(String jobName){
try {
URI uri = new URI(jenkins_url);
JenkinsServer jenkins = new JenkinsServer(uri, jenkins_user, jenkins_token);
jenkins.deleteJob(jobName, false);
jenkins.disableJob(jobName, false);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

/**
* 启动 Job 构建
* @param jobName
* @param params
* @return
*/
public static boolean startJob(String jobName, String params){
try {
String buildUrl = jenkins_url + jobName + "/buildWithParameters?" + params;
HttpUtils.HttpGet(buildUrl);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

/**
* 停止正在构建中的 Job,先清除等待队列中的 build,在停止运行中的 build
* @param jobName
* @return
*/
public static boolean stopJob(String jobName){
try {
URI uri = new URI(jenkins_url);
JenkinsServer jenkins = new JenkinsServer(uri, jenkins_user, jenkins_token);
// 先 kill 掉 queue 里面的 build
QueueItem qi = jenkins.getJob(jobName).getQueueItem();
if(qi != null){
HttpUtils.HttpPost(jenkinsUrl + "queue/cancelItem?id=" + qi.getId());
}
// 在 kill 掉正在运行中的 build
List bulidsList = jenkins.getJob(jobName).getAllBuilds();
for(Build b:bulidsList){
if(b.details().isBuilding()){
try{
b.Stop();
}catch(Exception ee){
ee.printStackTrace();
return false;
}
}
}
} catch(Exception e) {
e.printStackTrace();
return false;
}
return true;
}
}

这里有一个地方要注意,在停止构建中的 Job 时,这里是遍历所有 Build,然后在 Kill 掉运行中的 Build,如果 Build 历史比较多的时候,会耗时比较久,这将会导致立马重新执行该 Job Build 时, Build 会被异常 Abort 掉。。。也尝试过获取最后一次 Build 执行 Stop 操作,好像也不太好使。所以这里大家可以通过上边 3.1、丢弃旧的构建配置 中的操作,减少构建历史记录,这样就可以很快执行完毕,就不会出现上述问题了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jdbc 批量insert_JDBC相关知识解答

1. JDBC_PreparedStatement插入大量数据_批处理插入_效率比较(1) jdbc新增大量数据时, 如何处理能提高效率?答:使用批处理提高效率(2) 什么是批处理? JDBC如何进行批处理?答:批处理:在与数据库的一次连接中,批量的执行条 SQL 语…

python 实现显著性检测_强!汽车车道视频检测:python+OpenCV为主实现

1 说明:1.1 完整版:汽车车道动态视频检测讲解和注释版代码,小白秒懂。1.2 pythonOpenCVmoviepynumpy为主的技术要点。1.3 代码来源:https://github.com/linghugoogle/CarND-Advanced-Lane-Lines #虽然感觉也是fork别人的&#xff…

如何学习c语言 零基础20天学会C语言

C语言开发 学习C语言不是一朝一夕的事情,但也不需要花费十年时间才能精通。如何以最小的代价学习并精通C语言是本文的主题。请注意,即使是“最小的代价”,也绝不是什么捷径,而是以最短的时间取得最多的收获,同时也意味…

学习C/C++的简单方法

如何学习C呢。C和C是很多专业的必修课,尤其对计算机专业来说,更是重中之重。C语言是早期发展的高级语言,具备执行速度快,语法优美等特点。是底层高效率系统的首选开发语言。今天就和大家分享一下怎么学好C/C语言吧 _ 怎么学好C、…

python数据预处理代码_Python中数据预处理(代码)

本篇文章给大家带来的内容是关于Python中数据预处理(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。1、导入标准库import numpy as np import matplotlib.pyplot as plt import pandas as pd 2、…

零基础想学好C语言编程,首先要掌握的是正确的学习思路!

如果新手要学习编程,一些前辈都会建议从Python、PHP、Java开始学。 不过,有些程序员是直接从C语言强势入门编程的。 那么,如何学习C语言呢?下面提供4种入门C语言的方法: 0、刷题 绝大多数的程序员学编程的时候,还…

C/C++初学者快速提升?

如今,软件开发行业继续向前大步迈进。信息技术越来越吃香,越来越多人学习学习c语言,那么如何系统有效的学习C语言?下面分享给大家的有效学习语言的方法,希望可以帮到你! 一、了解大纲,通览教材 想学好C语言最重要的一…

pytorch 矩阵相乘_深度学习 — — PyTorch入门(三)

点击关注我哦autograd和动态计算图可以说是pytorch中非常核心的部分,我们在之前的文章中提到:autograd其实就是反向求偏导的过程,而在求偏导的过程中,链式求导法则和雅克比矩阵是其实现的数学基础;Tensor构成的动态计算…

codeblocks如何让输出结果 空格_简单讲讲如何实现两个正整数相加,然后输出这个结果...

首先吧,两个整数123 456,相加得到579,我们就得输出579,这个很容易操作,但是如果是:1212161596156198115645646886148461554 2671232162176217624372497590415915915029125 呢?long ? long lo…

C语言和其他高级语言的最大的区别是什么?

提到C语言,我们知道C语言和其他高级语言的最大的区别就是C语言是要操作内存的! 我们需要知道——变量,其实是内存地址的一个抽像名字罢了。在静态编译的程序中,所有的变量名都会在编译时被转成内存地址。机器是不知道我们取的名字…

零基础学C语言必备书籍,抖音编程达人推荐(进群交流学习互动)

C语言从入门到进阶的书籍推荐。 【基础】 这本谭浩强写的【C语言程序设计】可谓是广大人事的入门书籍。我曾经用的教材就是这本,里面大概涵盖了 C语言 语法的 80% 。一个很适合自学的入门书。 【c prime puls】 是 C语言 最经典的入门书籍,极力推荐。每…

网站如何进行渠道跟踪_网站如何进行搜索引擎优化?

这是一个很一般的平台标题,没有任何吸引力,但是它真的可以被一个很好的基层站长估计的很少,我问一个做了多年基层站长的朋友,我说如何做好搜索引擎优化的SEO,他给我的答案很难,答案太大了,所以我…

什么是编程语言,大神教你为什么要学C语言?

首先来说说编程语言这个概念。 编程,其实就是让计算机听懂自己的话,让计算机帮自己想干的事情。编程语言,就是让你能够和计算机进行交流的一种语言。说白了就是让你的软件按你的命令干活。 打比方说,我们经常在僵尸片里面看到&a…

xshell vim 不能粘贴_linux基础知识:vim(vi)的知识

### vim三种模式命令行模式:在该模式下不能对文本进行- 直接编辑,可以输入一些操作(删除行,复制行,移动光标,粘贴)【打开之后默认进入的模式】编辑模式:在该模式下可以对文件内容进行编辑末行模式&#xff…

新手如何学习C语言/C++,教你一年时间是拿到年薪50万

最近会有一些初中高中大学的同学问,C语言C不知道怎么学习不会写代码怎么办?大致上都是一些类似的问题吧,回想一下自己走过的路,反复的了很久思考然后写了这篇文章,希望可以对一些迷惘新手小白程序员同学一丝帮助&#…

mac adb 找不到设备_win/Mac办公软件下载找不到资源?试试这三个强大的神器

大家好,我们在办公时,office、wps等办公软件是我们必须用到的,还有一些专业软件:CAD、PS、PROE、UG、SolidWorks、keyshot、VRay、3DsMax、Labview、Maya、AE、AI、ANSYS等也是各行各业的专业人员工作时必不可少的,但是…

C语言入门经验:零基础如何学习C语言?

工作中,接触过很多想到学习c语言而又没有一点计算机基础的人。经常有人问”我没有一点基础,该怎么入门c语言啊”。看过很多初学者久久摸不到门路,每到这个时候,脑海中总会浮现一个问题:学习c语言真的就那么难吗? 不难…

20天掌握C语言,C语言零基础到项目实战,玩转C语言

一般来说,和其他编程语言相比,C/C语言学起来会比较累,如果想达到项目开发的状态,更是需要花费很长时间的努力。那么,如何才能更好地把所学知识用到实际工作中去呢?今天小编就带大家来看看学习C/C语言到什么…

32岁了学python来的及吗_现在27岁学python来得及吗?

答案是肯定的,27岁学习Python语言是来得及的。 学习Python语言是当前一个比较好的选择,原因有以下几点: 第一,Python语言有健全的生态。Python语言虽然在最近几年被广泛关注,但是Python语言并不是一个新出现的语言&…

怎样快速画出一个正方体_小学数学非常有效的“画图”解题法,快速解题的“金钥匙”...

小学阶段的数学主要培养的是孩子的逻辑思维能力,是从形象思维逐步过度到抽象思维的过程,如果在小学阶段没有将基础打牢,那么等孩子上初中后面对更复杂的学习内容,就会变得更吃力。在小学数学中,“画图”是帮助孩子建立…