第二篇我们主要介绍了Quartz引入Spring框架的基本配置,这一篇直接开始对定时任务进行动态操控

一、 创建相关实体类

(1)定时任务参数
(2)存储TriggerName 的类,主要用来防重

(3)定时任务参数类的请求与返回

(4)调用任务实体类

package com.test.pojo.job;import java.lang.reflect.Method;import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;/*** 功能说明:任务实体类<br>* 注意事项:<br>* 系统版本:version 1.0<br>* 开发人员:renzw26782<br>* 开发时间:2020年8月3日<br>*/
@DisallowConcurrentExecution
public class QuartzJob extends QuartzJobBean {private static final Logger logger = LoggerFactory.getLogger(QuartzJob.class);private UseJobDto useJobDto;protected void executeInternal(JobExecutionContext context) throws JobExecutionException {// 调用余额对账定时服务this.execute(useJobDto.getFunctionId());}public UseJobDto getUseJobDto() {return useJobDto;}public void setUseJobDto(UseJobDto useJobDto) {this.useJobDto = useJobDto;}private void execute(String url) {try {if (logger.isDebugEnabled()) {logger.debug("调用服务[" + url + "]调用开始!");}String[] arr = url.split("#");String useJobMethod = arr[1].trim();// 通过反射调用服务String useJob = arr[0].trim();String useJobName = useJob.substring(0, 1).toUpperCase() + useJob.substring(1);@SuppressWarnings("rawtypes")Class c = Class.forName("com.test.job." + useJobName);Object obj = c.newInstance();Method jobMethod = obj.getClass().getMethod(useJobMethod);jobMethod.invoke(obj);System.out.println("执行成功");} catch (Exception e) {logger.debug("调用服务[" + url + "]失败", e);System.out.println("执行失败");} finally {if (logger.isDebugEnabled()) {logger.debug("调用服务[" + url + "]调用结束!");}}}}

二、 各处理层逻辑处理

直接上代码吧
(1)controller控制层

package com.test.controller.job;import java.util.List;import org.apache.maven.surefire.shade.org.apache.maven.shared.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import com.test.enums.UseJobExecutePathEnum;
import com.test.enums.UseJobStatusEnum;
import com.test.pojo.job.BaseResp;
import com.test.pojo.job.UseJob;
import com.test.pojo.job.UseJobReq;
import com.test.pojo.job.UseJobResp;
import com.test.service.common.CommonService;
import com.test.service.job.UseJobService;@Controller
@RequestMapping(value = "/useJop")
public class UseJobController {@ModelAttributeprotected void initData(Model model) {// 1、定时任务状态model.addAttribute("useJobStatusMap", UseJobStatusEnum.toMap());model.addAttribute("useJobExecutePathMap", UseJobExecutePathEnum.toMap());model.addAttribute("aaa", "111");}@RequestMapping(value = "/toJobPage")public String totoJobPage() {return "WEB-INF/job/jobPage";}@RequestMapping(value = "/addJobPage")public String toAddJobPage(UseJob useJob, Model model) {if (useJob != null && StringUtils.isNotBlank(useJob.getJobId())) {UseJobReq req = new UseJobReq(useJob);UseJobResp resp = useJobService.getUseJodInfoById(req);model.addAttribute("job", resp.getItem());}return "WEB-INF/job/addJobPage";}@Autowiredprivate UseJobService useJobService;@AutowiredCommonService commonService;@RequestMapping(value = "/queryJobList.do")@ResponseBodypublic List<UseJob> queryUseJobList(String jobName, String jobState) {UseJob job = new UseJob();if (StringUtils.isBlank(jobState)|| StringUtils.equals(jobState.trim(), UseJobStatusEnum.PLEASE_SELECT.getCode())) {job.setJobState("");} else {job.setJobState(jobState.trim());}if (StringUtils.isBlank(jobName)) {job.setJobName("");} else {job.setJobName(jobName.trim());}UseJobReq useJobReq = new UseJobReq(job);UseJobResp useJobResp = null;useJobResp = useJobService.queryUseJobList(useJobReq);return useJobResp.getItems();}@RequestMapping("/addUseJob.do")@ResponseBodypublic void addUseJob(UseJob useJob) {UseJobReq req = new UseJobReq(useJob);BaseResp baseResp = null;if (StringUtils.isBlank(useJob.getJobId())) {Long nowDate = commonService.getNowDate();Long nowTime = commonService.getNowTime();useJob.setJobId(nowDate.toString() + nowTime.toString());baseResp = useJobService.addUseJob(req);} else {baseResp = useJobService.updateUseJob(req);}}/*** 启动定时任务* * @param info* @return*/@RequestMapping("/startJob.do")@ResponseBodypublic String startUseJob(String jobId, String functionId) {UseJob object = new UseJob();object.setFunctionId(functionId);object.setJobId(jobId);UseJobReq req = new UseJobReq(object);BaseResp resp = useJobService.startUseJob(req);String message = "启动任务成功";if (resp.getErrorNo() != 0) {message = "启动任务失败" + resp.getErrorInfo();}return message;}/*** 启动定时任务* * @param info* @return*/@RequestMapping("/stopJob.do")@ResponseBodypublic String stopUseJob(String jobId, String functionId) {UseJob object = new UseJob();object.setFunctionId(functionId);object.setJobId(jobId);UseJobReq req = new UseJobReq(object);BaseResp resp = useJobService.stopUseJob(req);String message = "启动任务成功";if (resp.getErrorNo() != 0) {message = "启动任务失败" + resp.getErrorInfo();}return message;}/*** 删除定时任务* * @param info* @return*/@RequestMapping("/delJob.do")@ResponseBodypublic String delUseJob(String jobId, String functionId) {UseJob object = new UseJob();object.setFunctionId(functionId);object.setJobId(jobId);UseJobReq req = new UseJobReq(object);BaseResp resp = useJobService.delUseJob(req);String message = "删除任务成功";if (resp.getErrorNo() != 0) {message = "删除任务失败" + resp.getErrorInfo();}return message;}}

(2) service服务层

package com.test.service.job;import java.util.List;import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.test.logic.job.UseJobLogic;
import com.test.pojo.job.BaseResp;
import com.test.pojo.job.UseJob;
import com.test.pojo.job.UseJobDto;
import com.test.pojo.job.UseJobReq;
import com.test.pojo.job.UseJobResp;
import com.test.utils.BeanUtils;
import com.test.utils.StringUtils;@Service("jobFactory")
public class UseJobServiceImpl implements UseJobService {private Logger logger = Logger.getLogger(UseJobServiceImpl.class);@Autowiredprivate UseJobLogic useJobLogic;@Overridepublic UseJobResp queryUseJobList(UseJobReq req) {UseJobResp resp = new UseJobResp();List<UseJob> ls = null;try {ls = useJobLogic.queryJobs(req.getObject());} catch (Exception e) {resp.setErrorId("999999");resp.setErrorInfo("查询定时任务失败,请联系相关技术人员!");}resp.setItems(ls);return resp;}@Overridepublic BaseResp addUseJob(UseJobReq req) {BaseResp resp = new BaseResp();UseJobDto job = new UseJobDto();try {UseJob object = req.getObject();BeanUtils.copyProperties(job, object);// 1-参数校验resp = validateJobDto(job);if (resp.getErrorNo() > 0) {return resp;}// 2-校验任务是否存在if (useJobLogic.isExistJob(job)) {resp.setErrorNo(999999);resp.setErrorInfo("待新增的任务已存在");return resp;}// 2-添加任务useJobLogic.addJob(job);// 记录操作日志try {} catch (Exception e) {}} catch (Exception e) {resp.setErrorNo(999999);resp.setErrorInfo("新增定时任务失败,请联系相关技术人员!");logger.error(resp.getErrorInfo(), e);}return resp;}/*** 描述:校验入参<br>* 参数:@param job 参数:@return<br>* 返回值:BaseResp<br>* * @throws Exception*/private BaseResp validateJobDto(UseJobDto job) throws Exception {BaseResp resp = new BaseResp();if (job == null) {resp.setErrorNo(999999);resp.setErrorInfo("任务对象不能为空");return resp;}if (StringUtils.isBlank(job.getJobId())) {resp.setErrorNo(999999);resp.setErrorInfo("批次信息不能为空");return resp;}if (StringUtils.isBlank(job.getFunctionId())) {resp.setErrorNo(999999);resp.setErrorInfo("服务路径不能为空");return resp;}if (StringUtils.isBlank(job.getJobName())) {resp.setErrorNo(999999);resp.setErrorInfo("任务名称不能为空");return resp;}if (StringUtils.isBlank(job.getExpression())) {resp.setErrorNo(999999);resp.setErrorInfo("时间间隔表达式不能为空");return resp;}return resp;}@Overridepublic BaseResp startUseJob(UseJobReq req) {BaseResp resp = new BaseResp();UseJobDto job = new UseJobDto();try {UseJob object = req.getObject();BeanUtils.copyProperties(job, object);// 1-校验任务是否存在if (!useJobLogic.isExistJob(job)) {resp.setErrorNo(999999);resp.setErrorInfo("该任务不存在");return resp;}if (!useJobLogic.isPausedJob(job)) {return resp;}useJobLogic.startUseJob(job);} catch (Exception e) {resp.setErrorNo(999999);resp.setErrorInfo("启动定时任务失败,请联系相关技术人员!");logger.error(resp.getErrorInfo(), e);}return resp;}@Overridepublic BaseResp stopUseJob(UseJobReq req) {BaseResp resp = new BaseResp();UseJobDto job = new UseJobDto();try {UseJob object = req.getObject();BeanUtils.copyProperties(job, object);// 1-校验任务是否存在if (!useJobLogic.isExistJob(job)) {resp.setErrorNo(999999);resp.setErrorInfo("该任务不存在");return resp;}if (useJobLogic.isPausedJob(job)) {return resp;}useJobLogic.stopUseJob(job);// 记录操作日志} catch (Exception e) {resp.setErrorNo(999999);resp.setErrorInfo("暂停定时任务失败,请联系相关技术人员!");logger.error(resp.getErrorInfo(), e);}return resp;}@Overridepublic BaseResp delUseJob(UseJobReq req) {BaseResp resp = new BaseResp();UseJobDto job = new UseJobDto();try {UseJob object = req.getObject();BeanUtils.copyProperties(job, object);// 1-校验任务是否存在if (!useJobLogic.isExistJob(job)) {resp.setErrorNo(999999);resp.setErrorInfo("所删除的任务不存在");return resp;}// 2-校验当前任务状态是否是暂停状态if (!useJobLogic.isPausedJob(job)) {resp.setErrorNo(999999);resp.setErrorInfo("所删除的任务必须处于暂停状态");return resp;}// 3-删除任务useJobLogic.deleteJob(job);// 记录操作日志} catch (Exception e) {resp.setErrorNo(999999);resp.setErrorInfo("删除定时任务失败,请联系相关技术人员!");logger.error(resp.getErrorInfo(), e);}return resp;}@Overridepublic UseJobResp getUseJodInfoById(UseJobReq req) {UseJobResp resp = new UseJobResp();UseJobDto job = new UseJobDto();try {UseJob object = req.getObject();BeanUtils.copyProperties(job, object);// 1-校验任务是否存在if (!useJobLogic.isExistJob(job)) {resp.setErrorNo(999999);resp.setErrorInfo("所查看的任务不存在");return resp;}// 2-添加任务UseJob item = useJobLogic.getUseJodInfo(job);resp.setItem(item);} catch (Exception e) {resp.setErrorNo(999999);resp.setErrorInfo("查看定时任务失败,请联系相关技术人员!");logger.error(resp.getErrorInfo(), e);}return resp;}@Overridepublic BaseResp updateUseJob(UseJobReq req) {BaseResp resp = new BaseResp();UseJobDto job = new UseJobDto();try {UseJob object = req.getObject();BeanUtils.copyProperties(job, object);// 1-参数校验resp = validateJobDto(job);if (resp.getErrorNo() > 0) {return resp;}// 2-校验任务是否存在if (!useJobLogic.isExistJob(job)) {resp.setErrorNo(999999);resp.setErrorInfo("所修改的任务不存在");return resp;}// 3-校验当前任务状态是否是暂停状态if (!useJobLogic.isPausedJob(job)) {resp.setErrorNo(999999);resp.setErrorInfo("所修改的任务必须处于暂停状态");return resp;}// 4-修改任务useJobLogic.updateJob(job);// 记录操作日志} catch (Exception e) {resp.setErrorNo(999999);resp.setErrorInfo("新增定时任务失败,请联系相关技术人员!");logger.error(resp.getErrorInfo(), e);}return resp;}}

(3)logic逻辑层

package com.test.logic.job;import java.util.ArrayList;
import java.util.List;
import java.util.Set;import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.utils.Key;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;import com.chinabond.core.exception.BusinessException;
import com.test.pojo.job.QuartzJob;
import com.test.pojo.job.UseJob;
import com.test.pojo.job.UseJobDto;
import com.test.utils.StringUtils;@Component
public class UseJobLogic {private static final String GROUP_NAME_DEFAULT = Key.DEFAULT_GROUP;@Autowired(required = false)private SchedulerFactoryBean schedulerFactory;/*** 获取线程调度器* * @return*/private Scheduler getScheduler() {Scheduler scheduler = schedulerFactory.getScheduler();if (scheduler == null) {throw new BusinessException("999999", "定时任务调度器为空,请确认是否开启定时任务功能!");}return scheduler;}public List<UseJob> queryJobs(UseJob useJob) throws SchedulerException {List<UseJob> ls = new ArrayList<UseJob>();Set<TriggerKey> triggerKeys = getScheduler().getTriggerKeys(GroupMatcher.triggerGroupEquals(GROUP_NAME_DEFAULT));for (TriggerKey triggerKey : triggerKeys) {Trigger trigger = getScheduler().getTrigger(triggerKey);TriggerState triggerState = getScheduler().getTriggerState(triggerKey);UseJobDto useJobDto = (UseJobDto) getScheduler().getJobDetail(trigger.getJobKey()).getJobDataMap().get("useJobDto");if (useJobDto == null) {// 只处理新增的continue;}useJobDto.setJobState(triggerState.toString());useJobDto.setNextFireTime(trigger.getNextFireTime());ls.add(useJobDto);}// 条件查询CollectionUtils.filter(ls, new Predicate() {@Overridepublic boolean evaluate(Object object) {if (object == null || !(object instanceof UseJob)) {return false;}UseJob temp = (UseJob) object;if (StringUtils.isNotBlank(useJob.getJobName()) && !temp.getJobName().contains(useJob.getJobName())) {return false;}if (StringUtils.isNotBlank(useJob.getJobState())&& !StringUtils.equals(useJob.getJobState(), temp.getJobState())) {return false;}return true;}});return ls;}/*** 判断任务是否存在* * @param job* @return* @throws SchedulerException*/public boolean isExistJob(UseJobDto job) throws SchedulerException {TriggerKey triggerKey = TriggerKey.triggerKey(job.getTriggerKey(), GROUP_NAME_DEFAULT);CronTrigger trigger = (CronTrigger) getScheduler().getTrigger(triggerKey);return trigger != null;}/*** <pre>* addJob(这里用一句话描述这个方法的作用)   * 创建人:任智伟* 创建时间:2020年9月18日 上午9:51:36    * 修改人:任智伟      * 修改时间:2020年9月18日 上午9:51:36    * 修改备注: * @param job* @throws SchedulerException* </pre>*/public void addJob(UseJobDto job) throws SchedulerException {TriggerKey triggerKey = TriggerKey.triggerKey(job.getTriggerKey(), GROUP_NAME_DEFAULT);CronTrigger trigger = (CronTrigger) getScheduler().getTrigger(triggerKey);if (trigger == null) {/** Trigger不存在,则新建 */JobDataMap jobDataMap = new JobDataMap();job.setJobState(TriggerState.NORMAL.toString());jobDataMap.put("useJobDto", job);// 新建任务JobKey jobKey = new JobKey(job.getJobDetailKey(), GROUP_NAME_DEFAULT);JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class).setJobData(jobDataMap).withIdentity(jobKey).requestRecovery(true).storeDurably(true).build();// 表达式调度构建器CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getExpression());// 构建触发器trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();// 装配任务System.out.println("暂停ing-------------");getScheduler().scheduleJob(jobDetail, trigger);getScheduler().pauseTrigger(triggerKey);}}/*** <pre>* isPausedJob(判断任务状态是否已执行)   * 创建人:任智伟* 创建时间:2020年9月24日 上午10:31:01    * 修改人:任智伟      * 修改时间:2020年9月24日 上午10:31:01    * 修改备注: * @param job  定时任务* @return 暂停 :true ,其他 :false* </pre>* * @throws SchedulerException*/public boolean isPausedJob(UseJobDto job) throws SchedulerException {TriggerState triggerState = getScheduler().getTriggerState(TriggerKey.triggerKey(job.getTriggerKey()));return triggerState.toString().equals(TriggerState.PAUSED.toString());}/*** <pre>* startUseJob(启动定时任务)   * 创建人:任智伟* 创建时间:2020年9月24日 上午10:36:42    * 修改人:任智伟      * 修改时间:2020年9月24日 上午10:36:42    * 修改备注: * @param job 定时任务* </pre>* * @throws SchedulerException*/public void startUseJob(UseJobDto job) throws SchedulerException {getScheduler().resumeTrigger(TriggerKey.triggerKey(job.getTriggerKey()));getScheduler().resumeJob(JobKey.jobKey(job.getJobDetailKey()));}/*** <pre>* stopUseJob(停止定时任务)   * 创建人:任智伟* 创建时间:2020年9月24日 上午11:10:47    * 修改人:任智伟      * 修改时间:2020年9月24日 上午11:10:47    * 修改备注: * @param job* </pre>* * @throws SchedulerException*/public void stopUseJob(UseJobDto job) throws SchedulerException {getScheduler().pauseJob(JobKey.jobKey(job.getJobDetailKey()));getScheduler().pauseTrigger(TriggerKey.triggerKey(job.getTriggerKey()));}/*** <pre>* deleteJob(删除定时任务)   * 创建人:任智伟* 创建时间:2020年9月24日 下午4:54:57    * 修改人:任智伟      * 修改时间:2020年9月24日 下午4:54:57    * 修改备注: * @param job* @throws SchedulerException* </pre>*/public void deleteJob(UseJobDto job) throws SchedulerException {if (getScheduler().checkExists(JobKey.jobKey(job.getJobDetailKey()))) {getScheduler().deleteJob(JobKey.jobKey(job.getJobDetailKey()));}}/*** <pre>* getUseJodInfo(修改回显查询数据)   * 创建人:任智伟* 创建时间:2020年9月29日 下午2:49:09    * 修改人:任智伟      * 修改时间:2020年9月29日 下午2:49:09    * 修改备注: * @param job* @return* </pre>* * @throws SchedulerException*/public UseJob getUseJodInfo(UseJobDto job) throws SchedulerException {TriggerKey triggerKey = TriggerKey.triggerKey(job.getTriggerKey());Trigger trigger = getScheduler().getTrigger(triggerKey);TriggerState triggerState = getScheduler().getTriggerState(triggerKey);UseJobDto jobDto = (UseJobDto) getScheduler().getJobDetail(JobKey.jobKey(job.getJobDetailKey())).getJobDataMap().get("useJobDto");jobDto.setJobState(triggerState.toString());jobDto.setNextFireTime(trigger.getNextFireTime());return jobDto;}/*** <pre>* updateJob(修改定时任务)   * 创建人:任智伟* 创建时间:2020年10月12日 上午9:44:29    * 修改人:任智伟      * 修改时间:2020年10月12日 上午9:44:29    * 修改备注: * @param job* </pre>* * @throws SchedulerException*/public void updateJob(UseJobDto job) throws SchedulerException {deleteJob(job);addJob(job);}}

三、完成后效果



关联时间表达式的js代码逻辑较为复杂,这里就不展示了,有需要的小伙伴可以私我

定时任务(三)动态配置定时任务相关推荐

  1. springboot整合Quartz实现动态配置定时任务

    版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/liuchuanhong1/article/details/60873295 前言 在我们日常的开发中,很多 ...

  2. Spring Boot 整合 Quartz 实现 Java 定时任务的动态配置

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 首先说下这次主题,动态配置.没接触过定时任务的同学可以先看 ...

  3. Springboot2 Quartz实现JAVA定时任务的动态配置

    动态配置Quartz.没接触过定时任务的同学可以先看下此篇:JAVA定时任务实现的几种方式 文章目录 一.需求背景 1. 问题现象 2. 问题分析 3. 解决方案 二.需求背景 2.1. maven依 ...

  4. 动态配置定时任务(Spring Boot + quartz 的整合)

    在整个项目规划中,有的时候需要定时的去执行某一段代码,触发时间能随时修改,并且不影响项目的整体运行.所以,定时器的设计就必须要灵活,能随时的增,删,改定时任务. 数据库设计 CREATE TABLE ...

  5. python定时任务contrib_django+celery配置(定时任务+循环任务)

    下面介绍一下django+celery的配置做定时任务 1.首先介绍一下环境和版本 python==2.7 django == 1.8.1 celery == 3.1.23 django-celery ...

  6. mysql定时任务每天凌晨三点钟醒来_LINUX 配置定时任务,每天凌晨1点定时备份数据库...

    一.安装定时任务 如果本地没有安装包,在能够连网的情况下可以在线安装 yum install vixie-cron yum install crontabs 查看crond服务是否运行: pgrep ...

  7. java动态设置定时任务

    由于业务需求,需要提供一个能够让用户动态配置定时任务的入口,定时去同步数据 1.简单的业务处理,直接使用@Scheduled注解就能开启定时任务,例如在方法上@Scheduled(cron = &qu ...

  8. 定时任务——@Scheduled注解做定时任务

    一.这是springboot中配置静态定时任务的注解 1. 在启动类上面加上 @EnableScheduling 注解开启定时任务 import org.springframework.boot.Sp ...

  9. Spring Boot 实现定时任务的动态增删启停

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:jianshu.com/p/0f68936393fd 添加执 ...

最新文章

  1. 计算机为什么会出现网络用户,告诉你电脑显示无internet访问权限怎么办
  2. 第29节 专业英语1
  3. CodeForces - 1284C New Year and Permutation(组合数学+思维)
  4. 李洋疯狂C语言之用递归解决李白喝酒问题(二)
  5. java基础问题集锦一
  6. DNS解释问题:java.net.UnknownHostException
  7. linux查看usb设备名称,Linux系统下查看USB设备名及使用USB设备
  8. Kindle电子书资源网站汇总
  9. mate40怎么用鸿蒙系统,怎么使用鸿蒙系统?
  10. 理论力学知识要点归纳(一)
  11. Python基础复习09_面向对象特性
  12. 怎么在Arcgis中提取多个坐标点的dem值(高程)
  13. 几何画板绘制三棱锥的教程
  14. 四、移植 JZ2440 开发板
  15. Java游戏编程---第一章 2D图形和动画
  16. zynq linux开发环境,手记1:构建Zynq开发环境
  17. python分支结构——if语句
  18. python类型判断的函数_Python
  19. iOS - 版面实现记录二
  20. CMS整站程序整理(转)

热门文章

  1. 【考研数学】考研数学一的相关课本电子版资源分享
  2. 反素数(反转拼写的素数)
  3. 高性能 低功耗Cortex-A53核心板 | i.MX8M Mini
  4. 手机号正则表达式校验,兼容+86,空格和-分隔符等常规手机格式
  5. 基于CC2530的zIgbee传感器无线数据采集系统开发(部分关键源码)
  6. 求给定正整数m以内的素数之和
  7. C#中MemoryStream类的介绍
  8. ODI(Oracle Data Integrator)基本使用教程(1)
  9. Docker Volume 使用
  10. Android之GestureDetector-简单手势操作及通过手势缩放图片,我离职后面试收割小米等大厂offer