Quartz学习笔记
来源:互联网 发布:caffe 安装 编辑:程序博客网 时间:2024/05/28 03:03
1.编写任务类
public class HelloJob implements Job {
/**
* 需要一个无参的public构造以便scheduler在它需要的时候可以实例化这个class.
*/
public HelloJob() {
}
/**
* 要执行的代码
*
* @param context JobExecutionContext
* @throws JobExecutionException
*/
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello World! - " + new Date());
}
}
我们设定job从当前系统时间开始执行,并且每隔2秒钟执行一次。
public class RepeatTest {
public static void main(String args[]) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myjob", "mygroup1").build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "mygroup1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
//实例化scheduler
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start(); // 启动scheduler
java.util.Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//输出当前时间
System.out.println(simpleDateFormat.format(calendar.getTime()));
scheduler.scheduleJob(jobDetail, trigger);
}
}
控制台输出:
2017-11-30 09:04:00
Hello World! - Thu Nov 30 09:04:00 CST 2017
Hello World! - Thu Nov 30 09:04:02 CST 2017
Hello World! - Thu Nov 30 09:04:04 CST 2017
Hello World! - Thu Nov 30 09:04:06 CST 2017
Hello World! - Thu Nov 30 09:04:08 CST 2017
获取JobDetail的Key详情。
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
// 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定
JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
.withIdentity("myjob", "jobgroup1")// 定义标识符
.build();
System.out.println("jobDetail's name : " + jobDeatil.getKey().getName());
System.out.println("jobDetail's group : " + jobDeatil.getKey().getGroup());
System.out.println("jobDetail's jobClass : " + jobDeatil.getJobClass().getName());
// 创建一个 Trigger 实例,定义该 job 立即执行,并且每隔两秒重复执行一次,直到永远
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "trigroup1")// 定义标识符
.startNow()// 定义立即执行
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())// 定义执行频度
.build();
// 创建 Scheduler 实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
// 绑定 JobDetail 和 trigger
scheduler.scheduleJob(jobDeatil, trigger);
// 执行任务
scheduler.start();
// 打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is : " + sf.format(date));
}
}
控制台输出:
jobDetail's name : myjob
jobDetail's group : jobgroup1
jobDetail's jobClass : com.anyco.test01.HelloJob
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Hello World! - Thu Nov 30 10:20:04 CST 2017
Current Time Is : 2017-11-30 10:20:04
Hello World! - Thu Nov 30 10:20:06 CST 2017
Hello World! - Thu Nov 30 10:20:08 CST 2017
Hello World! - Thu Nov 30 10:20:10 CST 2017
Job&JobDetail
Job定义
实现业务逻辑的任务接口
浅谈Job
Job接口非常容易实现,只有一个execute方法,类似TimerTask的run方法,在里面编写业务逻辑Job接口源码public interface Job { void execute(JobExecutionContext context) throws JobExecutionException;}
Job实例在Quartz中的生命周期
每次调度器执行job时,它在调用execute方法前会创建一个新的job实例当调用完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收
浅谈JobDetail
JobDetail为Job实例提供了许多设置属性,以及JobDetailMap成员变量属性,它用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。
JobDetail属性
name:任务名称group:任务所属组jobClass:任务实现类jobDataMap:传参的作用
JobExecutionContext&JobDataMap
JobExecutionContext是什么
当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法;Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。
JobDataMap是什么
在进行任务调度时JobDataMap存储在JobExecutionContext中,非常方便获取JobDataMap可以用来装载任务可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它JobDataMap实现了JDK的Map接口,并且添加了一些非常方便的方法用来存取基本数据类型
获取JobDataMap的两种方式
重新编写HelloJob类如下
public class HelloJob implements Job {
// 方式二:getter和setter获取
// 成员变量 与 传入参数的key一致
private String message;
private Float floatJobValue;
private Double doubleTriggerValue;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Float getFloatJobValue() {
return floatJobValue;
}
public void setFloatJobValue(Float floatJobValue) {
this.floatJobValue = floatJobValue;
}
public Double getDoubleTriggerValue() {
return doubleTriggerValue;
}
public void setDoubleTriggerValue(Double doubleTriggerValue) {
this.doubleTriggerValue = doubleTriggerValue;
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is : " + sf.format(date));
// 编写具体的业务逻辑
//System.out.println("Hello World!");
JobKey key = context.getJobDetail().getKey();
System.out.println("My name and group are : " + key.getName() + " : " + key.getGroup());
TriggerKey trkey = context.getTrigger().getKey();
System.out.println("My Trigger name and group are : " + trkey.getName() + " : " + trkey.getGroup());
// 方式一:Map中直接 获取自定义参数
JobDataMap jdataMap = context.getJobDetail().getJobDataMap();
JobDataMap tdataMap = context.getTrigger().getJobDataMap();
String jobMsg = jdataMap.getString("message");
Float jobFloatValue = jdataMap.getFloat("floatJobValue");
String triMsg = tdataMap.getString("message");
Double triDoubleValue = tdataMap.getDouble("doubleTriggerValue");
System.out.println("jobMsg is : " + jobMsg);
System.out.println("jobFloatValue is : " + jobFloatValue);
System.out.println("triMsg is : " + triMsg);
System.out.println("triDoubleValue is : " + triDoubleValue);
// 方式一:Map中直接获取 获取自定义参数
JobDataMap jobDataMap = context.getMergedJobDataMap();
jobMsg = jobDataMap.getString("message");
jobFloatValue = jobDataMap.getFloat("floatJobValue");
triMsg = jobDataMap.getString("message");
triDoubleValue = jobDataMap.getDouble("doubleTriggerValue");
System.out.println("jobMsg is : " + jobMsg);
System.out.println("jobFloatValue is : " + jobFloatValue);
System.out.println("triMsg is : " + triMsg);
System.out.println("triDoubleValue is : " + triDoubleValue);
System.out.println("============================");
// 方式二:getter和setter获取
System.out.println("message is : " + this.message);
System.out.println("jobFloatValue is : " + this.floatJobValue);
System.out.println("triDoubleValue is : " + this.doubleTriggerValue);
}
}
重新编写HelloScheduler类
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
/**
* 编写 任务调度类
* @author ZhangCheng on 2017-06-26
*
*/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
// 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定
JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
.withIdentity("myjob", "jobgroup1")// 定义标识符
.usingJobData("message", "hello myjob1")
.usingJobData("floatJobValue", 3.14F)
.build();
System.out.println("jobDetail's name : " + jobDeatil.getKey().getName());
System.out.println("jobDetail's group : " + jobDeatil.getKey().getGroup());
System.out.println("jobDetail's jobClass : " + jobDeatil.getJobClass().getName());
// 创建一个 Trigger 实例,定义该 job 立即执行,并且每隔两秒重复执行一次,直到永远
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger","trigroup1")// 定义标识符
.usingJobData("message", "hello mytrigger1")
.usingJobData("doubleTriggerValue", 2.0D)
.startNow()// 定义立即执行
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
)
.build();
// 创建 Scheduler 实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
// 绑定 JobDetail 和 trigger
scheduler.scheduleJob(jobDeatil, trigger);
// 执行任务
scheduler.start();
// 打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is : " + sf.format(date));
}
}
控制台输出:
jobDetail's name : myjob
jobDetail's group : jobgroup1
jobDetail's jobClass : com.anyco.test03.HelloJob
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Current Time Is : 2017-11-30 10:54:06
Current Exec Time Is : 2017-11-30 10:54:06
My name and group are : myjob : jobgroup1
My Trigger name and group are : myTrigger : trigroup1
jobMsg is : hello myjob1
jobFloatValue is : 3.14
triMsg is : hello mytrigger1
triDoubleValue is : 2.0
jobMsg is : hello mytrigger1
jobFloatValue is : 3.14
triMsg is : hello mytrigger1
triDoubleValue is : 2.0
============================
message is : hello mytrigger1
jobFloatValue is : 3.14
triDoubleValue is : 2.0
Trigger
Trigger是什么
Quartz中的触发器用来告诉调度程序作业什么时候触发即Trigger对象时用来触发执行Job的
触发器通用属性
JobKey:表示job实例的标识,触发器被触发时,该指定的job实例会执行StartTime:表示触发器的时间表首次被触发的时间,它的值的类型是Java.util.DateEndTime:指定触发器的不再被触发的时间,它的值的类型是Java.util.Date
修改HelloJob类如下
public class HelloJob implements Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is : " + sf.format(date));
Trigger currentTrigger = context.getTrigger();
System.out.println("Start Time Is : " + sf.format(currentTrigger.getStartTime()));
System.out.println("End Time Is : " + sf.format(currentTrigger.getEndTime()));
JobKey jobKey = currentTrigger.getJobKey();
System.out.println("JobKey info : " + " jobName : " + jobKey.getName()
+ " jobGroup : " + jobKey.getGroup());
System.out.println("==================================");
}
}
修改HelloScheduler如下
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is : " + sf.format(date));
// 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定
JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
.withIdentity("myjob", "jobgroup1")// 定义标识符
.build();
// 获取距离当前时间3秒后的时间
date.setTime(date.getTime() + 3000);
// 获取距离当前时间6秒后的时间
Date endDate = new Date();
endDate.setTime(endDate.getTime() + 6000);
// 创建一个 Trigger 实例,定义该 job 立即执行,并且每隔两秒重复执行一次,直到永远
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger","trigroup1")
.startAt(date)// 定义3秒后执行
.endAt(endDate)// 定义6秒后结束
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())// 定义执行频度
.build();
// 创建 Scheduler 实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
// 绑定 JobDetail 和 trigger
scheduler.scheduleJob(jobDeatil, trigger);
// 执行任务
scheduler.start();
}
}
虽然我们使用了repeatForever,但是因为设定了Job实例的结束时间(当前时间3秒后开始,6秒后结束Job,每2秒执行一次),所以在这里Job只会执行两次。
Current Time Is : 2017-11-30 11:11:35
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Current Exec Time Is : 2017-11-30 11:11:38
Start Time Is : 2017-11-30 11:11:38
End Time Is : 2017-11-30 11:11:41
JobKey info : jobName : myjob jobGroup : jobgroup1
==================================
Current Exec Time Is : 2017-11-30 11:11:40
Start Time Is : 2017-11-30 11:11:38
End Time Is : 2017-11-30 11:11:41
JobKey info : jobName : myjob jobGroup : jobgroup1
==================================
SimpleTrigger
SimpleTrigger的作用
在一个指定时间段内执行一次作业任务或是在指定的时间间隔内多次执行作业任务
修改HelloJob类
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is : " + sf.format(date));
System.out.println("Hello World!");
}
}
修改HelloScheduler类
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is : " + sf.format(date));
// 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定
JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
.withIdentity("myjob", "jobgroup1")// 定义标识符
.build();
// 获取距离当前时间4秒钟之后的具体时间
date.setTime(date.getTime() + 4000);
// 获取距离当前时间6秒钟之后的具体时间
Date endDate = new Date();
endDate.setTime(endDate.getTime() + 6000);
// 距离当前时间4秒钟后首次执行任务,之后每隔2秒钟重复执行一次任务
// 距离当前时间6秒钟之后为止
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "trigroup1")// 定义标识符
.startAt(date)
.endAt(endDate)
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY))
.build();
// 创建 Scheduler 实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.scheduleJob(jobDeatil, trigger);
scheduler.start();
}
}
控制台输出:
Current Time Is : 2017-11-30 13:03:56
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Current Exec Time Is : 2017-11-30 13:04:00
Hello World!
Current Exec Time Is : 2017-11-30 13:04:02
Hello World!
CronTrigger
CronTrigger的作用
基于日历的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用
Cron表达式
用于配置CronTrigger实例是由7个子表达式组成的字符串,描述了时间表的详细信息格式:[秒][分][小时][日][月][周][年]
特殊符号解释
每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:
(1)*:表示匹配该域的任意值,假如在Minutes域使用*, 即表示每分钟都会触发事件。
(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。
(3)-:表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
(4)/:表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.
(5),:表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。
(6)L:表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
(7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份
(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
(9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。
Cron表达式举例
这里附上Cron表达式在线生成器链接:
http://cron.qqe2.com/
浅谈Scheduler,使用shutdown(true)和shutdown(false)
修改HelloJob类如下
public class HelloJob implements Job {
public void execute(JobExecutionContext context)
throws JobExecutionException {
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is : " + sf.format(date));
System.out.println("Hello World");
}
}
HelloScheduler如下,我们使用Scheduler的方法shutdown(true)
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException, InterruptedException {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is : " + sf.format(date));
// 创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob").build();
CronTrigger trigger = (CronTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule(
CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build();
// 创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
System.out.println("scheduled time is :"
+ sf.format(scheduler.scheduleJob(jobDetail, trigger)));
//scheduler执行3秒后挂起
Thread.sleep(3000L);
//shutdown(true)表示等待所有正在执行的job执行完毕之后,再关闭scheduler
//shutdown(false)即shutdown()表示直接关闭scheduler
scheduler.shutdown(true);
System.out.println("scheduler is shut down? " + scheduler.isShutdown());
}
}
控制台输出:
Current Time Is : 2017-11-30 16:00:36
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
scheduled time is :2017-11-30 16:00:36
Current Exec Time Is : 2017-11-30 16:00:42
Hello World
Current Exec Time Is : 2017-11-30 16:00:42
Hello World
Current Exec Time Is : 2017-11-30 16:00:43
Hello World
Current Exec Time Is : 2017-11-30 16:00:44
Hello World
Current Exec Time Is : 2017-11-30 16:00:45
Hello World
scheduler is shut down? true
shutdown(true)表示等待所有正在执行的job执行完毕之后,再关闭scheduler,在
scheduled time is :2017-11-30 16:00:36
Current Exec Time Is : 2017-11-30 16:00:42
Hello World
中间5秒的间隔,是因为HelloJob的Thread.sleep(5000)代码块,我们让程序运行3秒后就对scheduler进行shutdown(对主线程sleep3秒),但因为是shutdown(true),需要等待正在执行的job执行完毕之后,再关闭scheduler。
如果使用shutdown(false)
控制台将会输出:
Current Time Is : 2017-11-30 16:15:40
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
scheduled time is :2017-11-30 16:15:41
scheduler is shut down? true
Current Exec Time Is : 2017-11-30 16:15:46
Hello World
Current Exec Time Is : 2017-11-30 16:15:47
Hello World
Current Exec Time Is : 2017-11-30 16:15:48
Hello World
Current Exec Time Is : 2017-11-30 16:15:49
Hello World
shutdown(false)即shutdown()表示直接关闭scheduler。
阅读全文
0 0
- Quartz 学习笔记
- Quartz ---学习笔记
- quartz 学习笔记
- Quartz学习笔记
- Quartz 学习笔记
- Quartz 概要学习笔记
- Quartz学习笔记
- quartz 学习笔记
- Quartz学习笔记
- Quartz学习笔记
- quartz 学习笔记 1
- quartz学习笔记-core
- Quartz学习笔记
- Quartz学习笔记1:Quartz概述
- quartz----学习笔记(补充)
- Quartz学习笔记(1)
- Quartz学习笔记(2)
- Quartz 2D学习笔记
- Nepire的校OJ入门题解—蓝桥选拔篇(一)
- Hexo 搭建博客(成功)
- 欢迎使用CSDN-markdown编辑器
- c++rand()函数-产生随机数
- 关于第二天学习python过程中遇到的问题
- Quartz学习笔记
- 不用看,这只不过是对自己的激励而已
- 倒杨辉三角
- 京东联手腾讯升级B2B2C商业模式 重塑“互联网采购供应链”新标准
- 【观察】揭露迅雷“内讧”闹剧真相 制度性反腐依旧任重道远
- (八)接触到一些C++11的新知识
- Linux进程间通信——有名管道 FIFO 详解
- docker进程管理
- JDK中常用包及其类和功能详细剖析