Home  >  Article  >  Java  >  [Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

青灯夜游
青灯夜游forward
2022-09-15 11:10:242831browse

Are you still bald because of working overtime and staying up late? Are you still building wheels for strange needs? Then you’ve found the right person! ! This article has personally experienced the pain of programmers. I vomited blood behind the scenes and compiled an article. I hope it will be helpful to everyone. Go, go, go! !

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

If you want to do your job well, you must first sharpen your tools

As a programmer, every day The thing I faced was writing code and bragging. But I always feel that I have not reached a balance between these two things. I always feel that I spend too much time writing code every day, and there is not much time for myself to brag. I wonder if you all have these questions and doubts?

We know that programmers are the most lazy creatures! Why! So the question is, why do you still have so little time for fishing? Are we too good at it? No, no, no, don’t underestimate yourself. What could be the reason?

The answer is, of course, you haven’t read this article yet. This article has personally experienced the pain of programmers. I vomited blood behind my back and compiled an article. Now I share it with everyone. I hope it will be helpful to everyone.

Directory

  • Overall preview

  • JSON Parsing tool

  • HTTP network request tool

  • String processing tool

  • Collection processing tool

  • File stream processing tool

  • Encryption and decryption tool

  • JAVA bean object conversion tool

  • Caching and current limiting tool


Get started

Overall preview

This article will classify triggers from the picture, introduce related tool kits, and briefly introduce their use. Because the length of this article is limited, it is only used as an introduction. The specific details still need to be understood slowly when writing code.

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

JSON parsing tool

json I believe I don’t need to say more about how commonly used parsing tools are in development. Well, it can be said to be a tool that programmers use every day. This is why I put it first. Let’s take a look at it, summarize it and use it, GO! The author I use more often is Fastjson, which is a tool for JSON parsing from Alibaba Open Source, and its usage is also quite simple.

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

1. maven import pom coordinates

<dependency>
    <groupid>com.alibaba</groupid>
    <artifactid>fastjson</artifactid>
    <version>1.2.83</version>
</dependency>

2. Let’s see how to use it

  • JSON Conversion between strings and entity objects
// 字符串转对象
Studen student = JSON.parseObject("{"name":"小明","age":18}", Student.class);
// 对象转字符串
String str = JSON.toJSONString(student);
  • JSON Strings and JSONObject Mutual conversion

JSONObject is just a data structure, which can be understood as a data structure in JSON format (key-value structure), you can use the put method to add elements to the json object. JSONObject can be easily converted into string, and other objects can also be easily converted into JSONObject objects

// 字符串转JSONObject对象
JSONObject jsonObject = JSONObject.parseObject("{"name":"小明","age":18}");
// JSONObject对象转字符串
String str = jsonObject.toJSONString();
  • JSON String Convert to Collection class
// 定义解析字符串
String studentListStr = "[{"name":"小明","age":18},{"name":"小牛","age":24}]";
// 解析为 List<student>
List<student> studentList = JSON.parseArray(studentListStr, Student.class);
// 定义解析字符串
String studentMapStr = "{"name":"小明","age":18}";
// 解析为 Map<string>
Map<string> stringStringMap = 
JSONObject.parseObject(studentMapStr, new TypeReference<map>>(){});</map></string></string></student></student>

fastjson That’s it. Here we only introduce simple usage. For more detailed usage, please refer to the official website Document, there are more usages waiting for you~~


HTTP 网络请求工具

除了 JSON 工具,作为一个优秀的互联网打工人,不学会网络请求,怎么能够在这个行业占有一席之地呢?HTTP 网络请求工具你值得拥有~~ 根据我的个人意愿,我简单介绍 httpclient的用法,因为我对这个比较熟悉

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

1、maven 导入 pom 坐标

2、如何使用

  • GET 请求(无参)
/**
* 无参的 GET 请求
*/
public static void noArgsGetHttp() throws IOException {
    // 定义 httpclient
    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    // 创建 httpGet
    HttpGet httpGet = new HttpGet("http://www.baidu.com");
    // 定义返回结果
    CloseableHttpResponse execute = null;
    // 发送执行
    execute = httpClient.execute(httpGet);
    // 获取返回值
    HttpEntity entity = execute.getEntity();
    System.out.println("响应状态为:" + execute.getStatusLine());
    if (Objects.nonNull(entity)) {
        System.out.println("响应内容长度为:" + entity.getContentLength());
        System.out.println("响应内容为:" + EntityUtils.toString(entity));
    }
    // 释放资源
    if (httpClient != null) {
        httpClient.close();
    }
    if (execute != null) {
        execute.close();
    }
}

响应状态为:HTTP/1.1 200 OK 响应内容长度为:-1 响应内容为:

  • GET 请求(有参)
 /**
* 有参的 GET 请求
*/
public static void haveArgsGetHttp() throws IOException, URISyntaxException {
    // 定义 httpclient
    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    // 创建参数列表
    List<namevaluepair> valueParamsList = new ArrayList();
    valueParamsList.add(new BasicNameValuePair("studentId","1"));
    // 创建对应请求 Uri
    URI uri = new URIBuilder()
        .setScheme("http")
        .setHost("localhost")
        .setPath("/getStudentInfo")
        .setParameters(valueParamsList)
        .build();
    // 根据 Uri 创建 httpGet
    HttpGet httpGet = new HttpGet(uri);
    // 定义返回结果
    CloseableHttpResponse execute = null;
    // 发送执行
    execute = httpClient.execute(httpGet);
    // 获取返回值
    HttpEntity entity = execute.getEntity();
    System.out.println("响应状态为:" + execute.getStatusLine());
    if (Objects.nonNull(entity)) {
        System.out.println("响应内容长度为:" + entity.getContentLength());
        System.out.println("响应内容为:" + EntityUtils.toString(entity));
    }
    // 释放资源
    if (httpClient != null) {
        httpClient.close();
    }
    if (execute != null) {
        execute.close();
    }
}</namevaluepair>
  • POST 请求(有参数)
/**
* post 有参数
*/
public static void haveArgsPosthttp() throws IOException {
    // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    // 创建Post请求
    HttpPost httpPost = new HttpPost("http://localhost:12345/posttest");
    JSONUtil.Student student = new JSONUtil.Student();
    student.setName("潘晓婷");
    student.setAge(18);

    String jsonString = JSON.toJSONString(student);
    StringEntity entity = new StringEntity(jsonString, "UTF-8");
    // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
    httpPost.setEntity(entity);
    httpPost.setHeader("Content-Type", "application/json;charset=utf8");
    // 响应模型
    CloseableHttpResponse response = httpClient.execute(httpPost);
    // 从响应模型中获取响应实体
    HttpEntity responseEntity = response.getEntity();
    System.out.println("响应状态为:" + response.getStatusLine());
    if (responseEntity != null) {
        System.out.println("响应内容长度为:" + responseEntity.getContentLength());
        System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    }
    // 释放资源
    if (httpClient != null) {
        httpClient.close();
    }
    if (response != null) {
        response.close();
    }
}

啊!这样一步一步总结下来好累啊,看到这里的小伙伴们,点一下手里的小赞。嘿嘿~~ 当然我只是简单介绍一下 httpClient 的使用,具体高深的使用方法和配置可以参考其他博主的详细介绍,让我们介绍下一个常用的工具吧。


字符串处理工具

字符串使我们开发中最常见的类型,也是我们最常需要操作的类型了。如果不知道字符串的常用工具,那在写代码的时候简直就是场灾难!!!

字符串判空,截取字符串、转换大小写、分隔字符串、比较字符串、去掉多余空格、拼接字符串、使用正则表达式等等。

StringUtils 给我们提供了非常丰富的选择。我们着重以本类来介绍使用。

1、导入maven坐标

<dependency>
    <groupid>org.apache.commons</groupid>
    <artifactid>commons-lang3</artifactid>
    <version>3.12.0</version>
</dependency>

2、常用方法介绍

  • 字符串判空 ⭐⭐⭐

(isNotBlankisBlanK)

String str = " ";
// 是否不为空
boolean res1 = StringUtils.isNotBlank(str);
// 是否为空
boolean res2 = StringUtils.isBlank(str);

(isNotEmptyisEmpty)

String str = " ";
// 是否不为空
boolean res1 = StringUtils.isNotEmpty(str);
// 是否为空
boolean res2 = StringUtils.isEmpty(str);

优先推荐使用 isBlankisNotBlank 方法,因为 它会把空字符串也考虑进去

  • 分隔字符串 —— split —— ⭐⭐⭐
String str2 = "1,2,3";
String[] split = StringUtils.split(str2);
System.out.println(Arrays.toString(split));

相较于 Stringsplit 方法来说,StringUtilssplit 方法不会有空指针异常

  • 判断是否纯数字 —— isNumeric —— ⭐⭐

给定一个字符串,判断它是否为纯数字 可以使用isNumeric方法

String str3 = "1";
boolean numeric = StringUtils.isNumeric(str3);
System.out.println(numeric);

当然,这个工具类除了上面简单的三个方法之外们还有其他很多对于我们来说很使用的方法,但是这里就不一一举例了, 有兴趣的小伙伴们可以看源码统计一下


集合相关处理工具

哦吼~~看完了字符串的常用工具,重中之重的集合它来了,如果说没有字符串,我们的程序就无法运行,那么没有集合,我们将会是每天在加班的中度过了,出去后将会自豪的说,老板的车轮胎我也是做了贡献的。

既然集合工具这么重要,那么当然要重点介绍。学会相关工具的使用,真的是能让我们事半功倍的,真的是能让摸鱼时间大大增加的,不信你看看。

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

Collections

它是 JAVA 的集合工具包,内部包括了很多我们常用的方法,下图展示了其中一些,方便食用!

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

  • 排序—— sort—— ⭐⭐⭐

在我们日常开发工作中,经常会遇到一些集合排序的需求。sort 就可以很好的帮助我们做好这一点

List<integer> list = new ArrayList();
list.add(2);
list.add(1);
list.add(3);
//升序
Collections.sort(list);
System.out.println(list);
//降序
Collections.reverse(list);
System.out.println(list);</integer>

结果: [1, 2, 3] [3, 2, 1]

  • 获取最大最小值 —— max / min ——⭐⭐⭐

最大值最小值是我们操作集合最常见的方法了吧!!Collections 就有现成的方法帮助我们实现

// 最大值最小值
List<integer> intList = new ArrayList();
intList.add(1);
intList.add(2);
intList.add(3);

Integer max = Collections.max(intList);
Integer min = Collections.min(intList);

System.out.println("集合元素最大值:" + max);
System.out.println("集合元素最小值:" + min);</integer>

结果:集合元素最大值:3 集合元素最小值:1

  • 转换线程安全集合—— synchronizedList ——⭐⭐⭐

在多线程状态下,普通集合会产生并发问题,比如 ArrayList 并发添加会产生空值情况,这时我们又不想改动我们之前的集合怎么办? 我们简单的通过Collections 的线程安全转化就可以做到了,简简单单一行代码就可以做到!是不是方便的很!

List<integer> synchronizedList = Collections.synchronizedList(intList);</integer>

当然,Collections 还有很多有用和有趣的方法等着我们去探索,只是只是作为了一个抛转引玉的效果,就不过多的赘述了。

CollectionUtils

我最常用的便是 CollecionUtils,它是 apache 开源的工具包。它的功能可以说是相当强大的,不信你可以往下看看,反正你能想到的集合操作基本上它都有。

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

  • 集合判空—— isNotEmpty——⭐⭐⭐

我们最常用的集合方法,没有之一,必须掌握它!!

List<string> stringList = new ArrayList();
boolean notEmpty = CollectionUtils.isNotEmpty(stringList);
System.out.println("集合不是空的吗?"+ notEmpty);</string>

集合不是空的吗?false

  • 交集/并集/补集/差集——⭐⭐⭐

在开发中,经常需要将多集合进行交并补等的数学操作,不会还是傻傻的子集写循环处理吧!那样还能有摸鱼的时间吗?下面就是大大提升效率的工具!!!

List<integer> list1 = new ArrayList();
list1.add(1);
list1.add(2);
list1.add(3);
List<integer> list2 = new ArrayList();
list2.add(3);
list2.add(4);
// 获取并集
Collection<integer> union = CollectionUtils.union(list1, list2);
System.out.println(union);

// 获取交集
Collection<integer> intersection = CollectionUtils.intersection(list1, list2);
System.out.println(intersection);

//获取交集的补集
Collection<integer> disjunctionList = CollectionUtils.disjunction(list1, list2);
System.out.println(disjunctionList);

// 获取差集
Collection<integer> subtract = CollectionUtils.subtract(list1, list2);
System.out.println(subtract);</integer></integer></integer></integer></integer></integer>

两集合并集:   [1, 2, 3, 4]

两集合交集: [3]

两集合交集的补集:[1, 2, 4]

两集合差集: [1, 2]

  • 判断两集合是否相等——isEqualCollection——⭐⭐⭐
// 判断两集合是否相等
List<integer> list3 = new ArrayList();
list1.add(3);
list1.add(4);
List<integer> list4 = new ArrayList();
list2.add(3);
list2.add(4);
boolean equalCollection = CollectionUtils.isEqualCollection(list3, list4);
System.out.println("两集合相等吗?:" + equalCollection);</integer></integer>

两集合相等吗?:true

Lists

最后在集合的工具类中再补充一个 google 官方的java包,里面有很多我们想不到的超级方便的小工具,既然是说集合,我们说一下它里面的 Lists 类,也是超级好用的!

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

  • 快速初始化集合——newArrayList——⭐⭐⭐

相信大家在开发中,都有过初始化集合的需要吧!那么我们一般都是 新建一个 ArrayList 然后一个一个 add 进去,现在告诉大家,不用这么麻烦,一个方法新建带初始化全搞定,真香警告!!

// 快速初始化集合
ArrayList<integer> integers1 = Lists.newArrayList(1, 2, 3);
System.out.println(integers1);</integer>

[1, 2, 3]

  • 集合分页——partition——⭐⭐⭐

有时候我们想将我们的大集合分散成为一些小集合,我们又不想手动操作怎么办?这些痛点肯定已经有人帮助我们想好了!!来来来,介绍一下!!

// 数组分页
ArrayList<integer> list7 = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<list>> partition = Lists.partition(list7, 5);
System.out.println(partition);</list></integer>

[ [1, 2, 3, 4, 5], [6, 7, 8, 9, 10] ]

介绍完了 集合相关的操作类,下面我们也要介绍一下文件流相关操作,这个操作在开发中也是经常用到的。


文件流处理工具

相信我们在工作已经厌烦了,经常写** IO 流相关的类了吧。经常简单的读取和写入一个文件,我们需要大费周章的去定义一些 InputStream OutputStream **等,感觉有一种杀鸡用牛刀的错觉。 介绍一个文件操作工具类,省去大量操作和关闭行为,超级好用,平常我可是经常用的。

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

  • 将信息写入文件——writeByteArrayToFile——⭐⭐⭐

最最常用的操作,怎么样很简单吧,就只用一行代码,秒杀!

// 将 test 写入 test.txt 文件
FileUtils.writeByteArrayToFile(new File("C:\Users\test.txt"), "test".getBytes());
  • 从文件读取信息——readFileToByteArray——⭐⭐⭐

知道了怎么往文件里写东西,他的好兄弟读取我们也得知道啊!

// 读取 test.txt 文件
byte[] bytes = FileUtils.readFileToByteArray(new File("D:\Users\test.txt"));
System.out.println("读取到的文本为:" + new String(bytes));

读取到的文本为:test

API 很多,我也不能一一为大家介绍,深入的了解还需要大家去,熟练地运用起来,并且是不是的去看看官方的文档,查漏补缺,相信你也可以见识到很多让你叹为观止的方法。


加解密工具类

平常我们经常会遇到比如对用户的密码进行加密 (MD5) ,校验接口的签名 (sha256) 加密等等 用到加密的场景虽然不是很多,但是有这样的工具何乐而不为呢?

因为常用的加密方法并不多,这里介绍两个方法给大家,想知道其他更多用法的伙伴们,去自己探索吧

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

// MD5 加密
String MD5 = DigestUtils.md2Hex("123");
System.out.println("加密后的结果:" + MD5);

//  sha(安全哈希算法) 加密
String sha256Hex = DigestUtils.sha256Hex("123");
System.out.println("sha256加密后:" + sha256Hex);

MD5加密后的结果:ef1fedf5d32ead6b7aaf687de4ed1b71

sha256加密后:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e3


JAVA bean 对象转换工具

说到这里,我们来说一下对象转化的工具,在开发中有些规范,比如DTO、DO、VO等等,之间,如果我们需要转换,单纯的我们要一个一个的 set 值,真是一项苦逼的活。

[Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!

BeanUtils

java bean对象的相关转化,我在这里介绍两个 ,一个 是大家都非常熟悉的 BeanUtils,还有一个就是我平常在开发中经常使用的 MapStructBeanUtils 最常用的莫过于对象的的拷贝了 。 不过面对需要深拷贝的对象大家要注意了,这里并不推荐大家使用此工具去实现

Student student = new Student();
student.setName("小明");
student.setAge(18);
Student newStudent = new Student();
BeanUtils.copyProperties(student,newStudent);
System.out.println(newStudent);

Student(name=小明, age=18)


MapStruct

下面我们重点说一下 MapStruct 这个转化,BeanUtils 就是一个大老粗,只能同属性映射,或者在属性相同的情况下,允许被映射的对象属性少。

但当遇到被映射的属性数据类型被修改或者被映射的字段名被修改,则会导致映射失败。而 mapstruct 就是一个巧媳妇儿了。

她心思细腻,把我们可能会遇到的情况都给考虑到了(要是我也能找一个这样的媳妇儿该多好,内心笑出了猪声)

1、首先啥都不用想上来我们先把该导的包导进去

<dependency>
	<groupid>org.mapstruct</groupid>
	<!-- jdk8以下就使用mapstruct -->
	<artifactid>mapstruct-jdk8</artifactid>
	<version>1.2.0.Final</version>
</dependency>
<dependency>
	<groupid>org.mapstruct</groupid>
	<artifactid>mapstruct-processor</artifactid>
	<version>1.2.0.Final</version>
</dependency>

2、用一下

  • 对象之间字段完全相同

第一步:定义好我们的基础类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student{
	private String name;
	private Integer age ;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher{
	private String name;
	private Integer age ;
}

第二步:接下来定义一个接口,但是注意不需要实现,他就呢能够帮我们转化很神奇的

@Mapper
public interface UserCovertToTeacher {
    UserCovertToTeacher INSTANCE = Mappers.getMapper(UserCovertToTeacher.class);
    Teacher toCovert(Student student);
}

最后一步:在代码中调用,聪明的小伙伴看下面代码,一下就明白了,就是这么简单

Student student = new Student();
student.setName("小明");
student.setAge(18);
Teacher teacher = UserCovertToTeacher.INSTANCE.toCovert(student);
System.out.println(teacher);

Teacher(name=小明, age=18)

  • 对象之间字段存在不相同情况

我们介绍了完全两个类字段相同的情况,那么,更加令我们头疼的 有多个字段名字不同但是有对应关系应该怎么搞呢?

我们进阶介绍一下,如何处理这种参数名不同的对应关系 目前假设我们新定义一个微信类,我们的学生要注册到微信上,我们就要将学生对象转化为微信对象

@Data
@AllArgsConstructor
@NoArgsConstructor
static class WeiXin{
	private String username;
	private Integer age ;
}

但是我们发现和我们上面的学生类,的名字参数名不同,怎么对应过去的? 答案就是在对方法上配置

@Mapper 
public interface UserCovertToWeinxin {
    UserCovertToWeinxin INSTANCE = Mappers.getMapper(UserCovertToWeinxin.class);
	// 配置字段映射规则
    @Mapping(source = "name",target = "username")
    BeanUtilTest.WeiXin toCovert(BeanUtilTest.Student student);
}
Student student = new Student();
student.setName("小明");
student.setAge(18);
WeiXin weiXin = UserCovertToWeinxin.INSTANCE.toCovert(student);
System.out.println(weiXin);

WeiXin(username=小明, age=18)

这么简单的两个小例子可包含不了 MapStruct这么强大的功能,不管是日期格式化、还是表达式解析、还是深拷贝,都能一一搞定,只是限于本篇文章,无法跟大家说了。想想都很伤心呢! 但是还是那句话,抛砖引玉么!剩下的就交给聪明的小伙伴们了!


缓存和限流器工具

最后一小节,我给大家带来我的珍藏,压箱底的东西要拿出来了,大家还不快快点赞收藏,记好,错过了,可就没有下家店了。

我也是在 guava 中发现了很多好用的工具的 首先介绍缓存工具,开发中,我们常用的内存缓存,也就常常是定义一个 Map 去存放,但是单纯的 Map 只能存和取,确无法做到,缓存过期、缓存淘汰,和相关通知等等复杂操作。

我们有必要学习掌握一种工具,能够 Cover 上面所有情况的缓存工具,有需求就有工具类,永远记住。!!!,Cache 登场了,还是老规矩,先看看它怎么用吧。

Cache

定义一个简单定时过期的缓存

Cache<string> cache = CacheBuilder.newBuilder()
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .build();
// 放入缓存
cache.put("小明","活着");
Thread.sleep(10000);
// 从缓存拿取值
System.out.println(cache.getIfPresent("小明"));</string>

null

看到没,结果显而易见,超过了缓存时间,就会自己释放。嘿嘿。

定义一个缓存符合以下限制:

  • 限制访问并发
  • 设置初始化容量
  • 限制缓存数量上限
Cache<string> cache = CacheBuilder.newBuilder()、
		    // 最大容量,超过按照 LRU 淘汰
                .maximumSize(100)
		    // 初始容量
                .initialCapacity(10)
		    // 并发等级 10
                .concurrencyLevel(10)
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .build();</string>

两个小例子,大家看明白了没有,真正的干货,还不赶紧用起来。

除了这个,一个限流器也是常常需要的,我们总不能自记去写一个限流器吧,需要考虑的太多,性能还不行哎!那就用接下来介绍的这个工具

RateLimiter

限流器大家在并发场景下经常会遇到,最简单的实现限流就是令牌桶算法,原理很简单,但是具体实现是很复杂的,RateLimiter 帮助我们解决这一点,只需要调用简单的 API 就能实现并发限流

定义限流器,每1秒钟通过 1 个请求

RateLimiter rateLimiter = RateLimiter.create(1,1,TimeUnit.SECONDS);

并发两个去获取,看一下结果吧,是不是符合我们的预期

new Thread(()->{
	System.out.println("线程 1 获取到执行权限了吗?" + rateLimiter.tryAcquire());
}).start();

new Thread(()->{
	System.out.println("线程 2 获取到执行权限了吗?" + rateLimiter.tryAcquire());
}).start();

线程 1 获取到执行权限了吗?true

线程 2 获取到执行权限了吗?false

怎么样,是不是只能有一个通过,简单例子说明问题。 具体用法还得大家在实际开发中具体体会,笔者在这里就不多BB了!!留着时间大家赶快去练习吧。争取成为一个 API 调用高手。

修炼完成

经过上面这么多的讲解、案例和对知识的思考,相信大家已经初步掌握了线程池的使用方法和细节,以及对原理运行流程的掌握, 如果你觉得本文对你有一定的启发,引起了你的思考。 点赞、转发、收藏,下次你就能很快的找到我喽!

(学习视频分享:编程基础视频

The above is the detailed content of [Compilation and sharing] 8 development tools to improve work efficiency and never be an overtime worker again!. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete