`
ahua186186
  • 浏览: 562034 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

单线程锁数据单线程执行任务+单线程锁数据多线程执行任务+quartz

 
阅读更多
注:
这种锁数据的做法虽然比较稳定,但感觉有点弱智,性能也低,以后准备考虑生产数据的时候给数据分配一个机器号(随机算法即可),然后通过一个配置表配置机器号节点,消费数据的应用进程通过竞争机器号消费或处理数据相关逻辑即可。


一:单线程锁数据单线程执行任务(即当包工头和又当工人,即拉皮条又接客)



package xxx.thread;

import java.io.IOException;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import com.xxx.PropritesUtils;
import com.xx.IxxxBiz;

/**
 * <pre>
 * 发送数据
 * </pre>
 * 
 * @author jason
 * 
 */
public class  xxxThread extends Thread implements InitializingBean {

	private static final Logger logger = LoggerFactory
			.getLogger(xxxThread.class);

	private IxxxBiz xxxBiz;

	/**
	 * 是否 运行
	 */
	private boolean running;

	/**
	 * 每次加载数量,最大发送条数
	 */
	private int loadSize = 100;

	/**
	 * 最大发送次数
	 */
	private int maxSendCount = 3;

	/**
	 * 休眠时间
	 */
	private int sleepTime = 2000;

	/**
	 * 重置时间间隔
	 */
	private int resetInterval = 20000;

	/**
	 * 下一次重置时间
	 */
	private long nextResetTime;

	/**
	 * 重置多长时间之前的数据
	 */
	private int beforeTime = 30000;

	/**
	 * 初始化线程,读取配置文件
	 */
	private void initThread() {
		// 下一次重置时间
		nextResetTime = System.currentTimeMillis() + resetInterval;
	}

	@Override
	public void run() {

		// TODO Auto-generated method stub
		// 判断是否启动后台线程
		// 根据server.properties文件中配置的startup-model决定是否启动服务
		// ### 0 服务与后台线程都启动
		// ### 1 只启动服务
		// ### 2 只启动后台线程
		String startup_model = "0";
		try {
			startup_model = PropritesUtils.getValue("startup-model");
		} catch (IOException e1) {
			logger.error("读取配置文件错误!", e1);
		}
		if ("1".equals(startup_model)) {
			logger.error("\n### 不启动线程");
			return;
		}
				
		logger.info("xxxThread 线程启动...");
		this.setName("xxxThread");
		// 初始化参数
		initThread();

		while (running) {

			// 休眠
			sleepTask(0);

			try {
				execute();
			} catch (Exception exception) {
				logger.error("执行任务异常", exception);
			}

		}

		logger.info("xxxThread 线程停止...");

	}

	public void execute() {
		while (running) {

			int size = 0;
			try {
				size = xxxBiz.queryData(loadSize);
			} catch (Exception exception) {
				logger.error("xxxThread error========", exception);
			}

			// 休眠
			sleepTask(size);

			// 重置状态
			resetStatus();
		}
	}

	private void sleepTask(int i) {
		// 如果i >= loadSize,则休眠时间为最短
		// 默认有数据的时候休眠1秒,没数据的时候休眠2秒
		int time = sleepTime;
		if (i >= loadSize) {
			time = sleepTime / 2;
		}

		try {
			sleep(time);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 重置状态
	 */
	private void resetStatus() {

		if (System.currentTimeMillis() > nextResetTime) {

			nextResetTime = System.currentTimeMillis() + resetInterval;

			long btime = System.currentTimeMillis() - beforeTime;
			Date bdate = new Date(btime);

			xxxBiz.resetStatus();

		}
	}

	public void afterPropertiesSet() throws Exception {
		// 启动线程
		this.running = true;
		this.start();
	}

	// 注意对象销毁,停止线程
	public void close() {
		this.running = false;
	}

	public IxxxBiz getxxxBiz() {
		return pcustomLaxDataBiz;
	}

	public void setxxxBiz(IxxxBiz xxxBiz) {
		this.xxxBiz = xxxBiz;
	}

	public boolean isRunning() {
		return running;
	}

	public void setRunning(boolean running) {
		this.running = running;
	}

	public int getLoadSize() {
		return loadSize;
	}

	public void setLoadSize(int loadSize) {
		this.loadSize = loadSize;
	}

	public int getMaxSendCount() {
		return maxSendCount;
	}

	public void setMaxSendCount(int maxSendCount) {
		this.maxSendCount = maxSendCount;
	}

	public int getSleepTime() {
		return sleepTime;
	}

	public void setSleepTime(int sleepTime) {
		this.sleepTime = sleepTime;
	}

	public int getResetInterval() {
		return resetInterval;
	}

	public void setResetInterval(int resetInterval) {
		this.resetInterval = resetInterval;
	}

	public long getNextResetTime() {
		return nextResetTime;
	}

	public void setNextResetTime(long nextResetTime) {
		this.nextResetTime = nextResetTime;
	}

	public int getBeforeTime() {
		return beforeTime;
	}

	public void setBeforeTime(int beforeTime) {
		this.beforeTime = beforeTime;
	}

}



BIZ接口:
public interface IxxxBiz {

	/**
	 * 查询数据
	 * 
	 * @param size
	 *            最大条数
	 * 
	 * @return 
	 */
	public int queryData(int size);

	/**
	 * 重置状态
	 */
	public void resetStatus();
}



BIZ实现:

package com.xxx.biz;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 *  biz
 * 
 * @author jason
 * 
 */
public class xxxBiz implements IxxxBiz {

	private static final Logger logger = LoggerFactory
			.getLogger(xxxBiz.class);

	private IxxxDao xxxDao;


	public IxxxDao getxxxDao() {
		return xxxDao;
	}

	public void setxxxDao(
			IxxxDao xxxDao) {
		this.xxxDao = xxxDao;
	}

	public int queryData(int size) {
		List<xxx> list = xxxDao.queryAndLockT(size);
		int reSize = 0;
		if (list == null) {
			return reSize;
		}
		for (xxx  queue : list) {
			doTask();

		}
		return reSize;
	}

	public void resetStatus() {
		xxxDao.reset();
	}
	

}



DAO锁数据,重置数据,更新状态等:
package com.xxx.dao;

import java.lang.management.ManagementFactory;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

/**
 * 描述:xxx
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID   DATE            PERSON         REASON
 *  1    2015-11-09        jason         Create
 * ****************************************************************************
 * </pre>
 * 
 * @author jason
 * @since 1.0
 */
public class xxxDao extends BaseDao
		implements IxxxDao {

	private static String localIP = ManagementFactory.getRuntimeMXBean()
			.getName();
	@Override
	public List<xxxQueue> queryAndLockT(final int size) {
		final String sql = "select * from xxx_queue where "
				+ " ifsend ='F' and rownum < ? for update";

		@SuppressWarnings("unchecked")
		List<xxxQueue> list = getHibernateTemplate().executeFind(
				new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {

						SQLQuery query = session.createSQLQuery(sql);
						query.setInteger(0, size);
						query.addEntity(xxxQueue.class);
						return query.list();
					}
				});

		if (list == null || list.isEmpty()) {
			return null;
		}

		for (xxxQueue queue : list) {

			queue.setIfsend("I");;// 锁定
			queue.setLockBy(localIP);// 标志
			queue.setLockTime(new Date());// 时间

			getHibernateTemplate().update(queue);

		}

		return list;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public int reset() {
		//重置逻辑:重置数据生成时间在1天内,10分钟之前被锁定过的数据,直接写死时间,暂时不做系统配置。
		//设计解释:ifsend字段是用来锁数据的,RESULT_FLAG字段是用来重置数据的,
		//分2个字段解决数据重发问题,这里可能有点冗余,主要是考虑以后数据量很多时,方便改成乐观锁,多线程发送,不需要增加字段。
		final String sql = "update xxx_queue set ifsend= 'F' "
				+ " where (RESULT_FLAG ='2' or ifsend='I') "
				+ " and PRODUCTION_TIME > sysdate - interval '1' day "
				+ " and LOCK_TIME < sysdate - interval '600' second";

		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						SQLQuery query = session.createSQLQuery(sql);

						return query.executeUpdate();
					}
				});
	}
	@Override
	public void statusUpdate(xxxQueue queue, boolean success) {
		if(success){//更新状态,目标是保证发送失败的数据可被重置
			queue.setConsumeTime(new Date());
			queue.setConsumeFlag("1");
			queue.setResultFlag("1");
			queue.setIfsend("S");
		}else{
			queue.setResultFlag("2");
		}
		getHibernateTemplate().update(queue);
	}


	@Override
	public void saveData(List<xxxQueue> datas) {
		getHibernateTemplate().saveOrUpdateAll(datas);
	}

	
	

}



二:单线程锁数据多线程执行任务( 包工头锁数据工人执行任务)

思路1:直接用quartz(Scheduler调度线程和任务执行线程,默认1:10)

quartz线程模型理论:

在quartz里,有一个scheduler的properties文件,用于配置quartz框架运行时环境,其中有如下配置:


#============================================================================
# Configure ThreadPool
#============================================================================

org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=20
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.makeThreadsDaemons=true

如果threadCount>1,才能保证两个或多个job能并发执行,这说明threadCount确实是并发执行线程数。

思路2:多线程执行结果不需要合并场景:借鉴netty IO线程设计,直接把数据放入队列,然后异步执行即可。

思路3:多线程执行结果需要合并场景:用CountDownLatch控制任务是否执行完,增加子线程:TaskExecutor(持有CountDownLatch对象)





CountDownLatch cdl = new CountDownLatch(data.size());

如:

package com.xxx.thread;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public  class TaskExecutor extends Thread
{
  protected static Logger logger = LoggerFactory.getLogger(TaskExecutor.class);
  private List<File> taskList;
  private File bakDir;
  private File errDir;
  private CountDownLatch cdl;

  public List<File> getTaskList()
  {
    return this.taskList;
  }

  public void setTaskList(List<File> paramList)
  {
    this.taskList = paramList;
  }

  public void run()
  {
    try
    {
      execute();
    }
    catch (Exception localException)
    {
      logger.error("TaskExecutor-run", localException);
    }finally{
    	cdl.countDown();
    }
  }



  protected  void execute(){
	  List<File>  fileList = getTaskList();
	  if(fileList!=null){
		  for(File file : fileList){
			try{
				long lastMofifyTime = file.lastModified();
				long diffTime =  System.currentTimeMillis() - lastMofifyTime;
				if(diffTime > 10000){	//	获取10秒之前生成的文件。
					Map<String, String> map = getMessageType(file);
					String businessType = map.get("type").toString().trim().toUpperCase();
					String xmlStr = map.get("xml").toString();
					if("aa".equals(businessType)){
						doxxx1(xmlStr, bakDir, errDir);
					}else if("bb".equals(businessType)){
						doxxx2(xmlStr, bakDir, errDir);	
					}else if("cc".equals(businessType)){
						doxxx3(xmlStr, bakDir, errDir);
					}else{//非法报文
						moveFileToErrorPath(file, errDir);
					}
					moveFileToBackUpPath(file, bakDir);
				}
			}catch (Exception e) {
				logger.error("========="+file.getName()+":{}.",StackTraceUtil.getStackTrace(e));
				moveFileToErrorPath(file, errDir);//可以考虑不处理,让其一直等待,防止网络断开等原因写回执失败
			}
			
		  }
		}else{
			logger.info("=========fileList is null, cdl.countDown()==================cdl count:" +cdl.getCount());
		}
  }
  
/**
* <pre>
* 获取xml文件的message_type
* </pre>
* 
* @param xmlFile
*            xml文件
* @return 返回 message_type
* @throws FileNotFoundException 
* @throws DocumentException
*/
public  Map<String, String> getMessageType(File xmlFile) throws FileNotFoundException {
	Map<String, String> retMap = new HashMap<String, String>();
	SAXReader saxReader = new SAXReader();
	Document document = null;
	Element msgType =null;
	FileInputStream fis = null;
	String xmlStr ="";
	try {
		fis = new FileInputStream(xmlFile.getPath());
		//使用SAXReader的read(File file)方法时,如果xml文件异常会导致文件被服务器占用不能移动文件,建议不使用read(File file)方法而使用read(FileInputStream fis)等流的方式读取文件,异常时关闭流,这样就不会造成流未关闭,文件被锁的现象了
		document = saxReader.read(fis);
		Element root = document.getRootElement();
		msgType = root.element("head").element("businessType");
		xmlStr = document.asXML();
	} catch (DocumentException e) {
		logger.error("getMessage_type error{}.", StackTraceUtil.getStackTrace(e));
	}finally{
      try{
          if(null != fis){
              fis.close();
              Thread.sleep(10L);
          }
      }catch(Exception e){
      	logger.error("getMessage_type error{}.", StackTraceUtil.getStackTrace(e));
      }
  }
	retMap.put("type", msgType == null ? "" : msgType.getText());
	retMap.put("xml", xmlStr);
	return retMap;
}

/**
 * <pre>
 * 移动文件到错误备份目录,并重命名
 * </pre>
 * 
 * @param xmlFile
 *            需要移动的文件
 * @param errDir
 *            错误备份目录
 * @return 是否成功
 */
private boolean moveFileToErrorPath(File xmlFile, File errDir) {
	errDir.mkdir();// 创建目录

	// 重命名文件
	StringBuffer fName = new StringBuffer(
			DateUtils.getCurrDateStr(DateUtils.HMS));
	fName.append("_");
	fName.append(xmlFile.getName());

	boolean b = xmlFile.renameTo(new File(errDir, fName.toString()));
	if (!b) {
		// 避免文件重名的情况
		fName = new StringBuffer();
		// 用UUID 重命名
		fName.append(UUID.randomUUID().toString());
		fName.append("_");
		fName.append(xmlFile.getName());
		return xmlFile.renameTo(new File(errDir, fName.toString()));
	}

	return b;
}

/**
 * <pre>
 * 移动文件到备份目录,并重名
 * </pre>
 * 
 * @param xmlFile
 *            需要备份的文件
 * @param bakDir
 *            备份目录
 * @return 是否成功
 */
private boolean moveFileToBackUpPath(File xmlFile, File bakDir) {
	bakDir.mkdir();// 创建目录

	// 重命名文件
	StringBuffer fName = new StringBuffer(
			DateUtils.getCurrDateStr(DateUtils.HMS));
	fName.append("_");
	fName.append(xmlFile.getName());

	boolean b = xmlFile.renameTo(new File(bakDir, fName.toString()));
	if (!b) {
		// 避免文件重名的情况
		fName = new StringBuffer();
		// 用UUID 重命名
		fName.append(UUID.randomUUID().toString());
		fName.append("_");
		fName.append(xmlFile.getName());
		return xmlFile.renameTo(new File(bakDir, fName.toString()));
	}

	return b;
}

public File getBakDir() {
	return bakDir;
}

public void setBakDir(File bakDir) {
	this.bakDir = bakDir;
}

public File getErrDir() {
	return errDir;
}

public void setErrDir(File errDir) {
	this.errDir = errDir;
}

public CountDownLatch getCdl() {
	return cdl;
}

public void setCdl(CountDownLatch cdl) {
	this.cdl = cdl;
}


}


三:扩展思路

集成:同样是 包工头 +  工人 模式
(1)单个应用程序(单线程锁数据--任务调度方) + 多个应用程序(多线程执行任务--任务执行器)
(2)单个应用程序(多线程锁数据--任务调度方) + 多个应用程序(多线程执行任务--任务执行器)
(3) 这种锁数据的做法感觉有点弱智,性能也低,可考虑生产数据的时候给数据分配一个机器号(随机算法即可),然后通过一个配置表配置机器号节点,消费数据的应用通过竞争机器号消费或处理数据即可。

四:下一步准备写个轻量级的分布式并行计算框架用来提升大批量任务的处理速度。
分享到:
评论

相关推荐

    交互修改.rp

    交互修改

    14230-2.pdf

    ISO14230-2标准文档,定义了K线通讯方式和数据格式,对于汽车诊断非常有用

    基于python的求职招聘网站 python+django+vue搭建的求职招聘管理系统 - 毕业设计 - 课程设计.zip

    学习作者过程中,遇到问题可以咨询解决方案前台地址http://job.gitapp.cn后台地址http://job.gitapp.cn/admin后台管理帐号用户名admin123 密码admin123功能介绍平台采用B/S结构,前端采用主流的Python语言进行开发,前端采用主流的V​​ue.js进行开发。整个平台包括前台和后台两个部分。前台功能包括首页、岗位详情页、简历中心、用户设置模块。后台功能包括总览、岗位管理、公司管理、分类管理、标签管理、评论管理、用户管理、运营管理、日志管理、系统信息模块。代码结构服务器目录编号web目录是前端代码部署运行执行步骤(1)安装python 3.8(2) 安装依赖。进入server目录下,执行 pip install -r requests.txt(3)安装mysql 5.7数据库,并创建数据库,创建SQL如下CREATE DATABASE IF NOT EXISTS xxx DEFAULT CHARSET utf8 COLLATE utf8_general_ci(4)恢复

    4602-职业规划设计书PPT护理.pptx

    4602-职业规划设计书PPT护理

    非常好的SqlServer查询性能优化教程资料100%好用.zip

    非常好的SqlServer查询性能优化教程资料100%好用.zip

    基于Springboot+Vue+Python深度神经网络学习算法水质管理预测系统设计毕业源码案例设计.zip

    基于Springboot+Vue+Python深度神经网络学习算法水质管理预测系统设计毕业源码案例设计Springboot_Vue_Python_水质管理_预测基于Springboot+Vue+Python深度神经网络学习算法水质管理预测系统设计毕业源码案例设计程序开发软件Eclipse/Idea + WebStorm/VsCode + Pycharm 数据库mysql 开发技术Springboot + Vue + Python 这个是一个水质管理和预报系统,它是一个全栈Web应用程序,使用机器学习和深度神经网络算法来预测未来的水质。系统一共有2个身份包括管理员和用户。管理员登录后可以查询最新水质检测数据,也可以上报新的水质数据,可以查询管理历史水质数据,查询历史水质趋势图,训练自己的模型参数,选择一个算法模型结果预测下个月的水质信息,管理所有的用户信息用户登录后比管理员就少了个用户管理功能。管理员账号密码 admin/123 用户账号密码user1/123

    微信小程序云开发毕业设计「单词天天斗」,好友,匹配,人机对战,单词本科毕设打字稿原创微信小程序.zip

    单词天天斗 (毕业设计/实战小程序/微信小程序完整项目)介绍该项目基于「微信小程序」原生框架和「微信小程序云开发」实现单词对战类小程序,支持好友对战、随机匹配、人机对战透明不同模式的「对战模式」另外提供「每日对战」词汇」、「生词本」、「排行榜」、「设置」等功能,实现完整的业务闭环。单词库包含从小学、初中、高中、四六级、考研、雅思等常需掌握的词汇,支持自定义词库,支持自定义拓展无限本单词书。技术栈主要为微信小程序、云开发、TypeScript等,从头搭建项目,基于git管理代码版本,使用eslint作为代码格式校验,并对页面进行组件化拆分,前端和云函数均采用TypeScript。实践小程序能力,如用户信息获取、用户登录、全局状态管理、路由、wxs、npm包、播放音频、回复、转发分享、动画、云数据库等。项目提供完整设计稿,项目演示可查看微信小程序「单词天天斗」,扫码体验 ↓这些人毕设参考项目文档齐全、题目合适、技术广度大、业务闭环,包含项目解析文档和教程,这是一个非常适合作为毕设学习的小程序项目。无化部署运营无论你是想通过小程序现变,还是想给自己的「英语课程教材」

    利用ReST与ReAct自改进多步骤推理的大规模语言模型代理

    内容概要:本文提出了结合强化自我训练(ReST)和响应动作链路(ReAct)的方法来构建并改善大规模语言模型代理的性能,尤其是在需要多步骤推理以解决复杂自然语言查询的任务上。文中定义了一个能够在外部工具/ API /环境交互中表现出色的代理,并提出了一种通过迭代训练以前的轨迹来进行连续自我提升和精炼的技术路径。 适合人群:对大型语言模型研究及应用有兴趣的研究人员和工程师。 使用场景及目标:本方法主要适用于处理需要多个信息检索步骤才能完成的问题解决任务,如基于复杂开放性问答系统的发展。具体目标是在减少所需参数量的前提下提高此类系统的准确性、鲁棒性和效率。 其他说明:作者展示了仅经过两轮迭代优化,即可以从一个大的预训练模型蒸馏出性能相当但大小减少两个数量级的小型化模型。此外,在整个过程中没有使用人类标记的数据进行直接监督。

    毕业设计Android,一款水果健康百科app.zip

    毕业设计Android,一款水果健康百科app斯戈利毕业设计Android,一款水果健康百科app

    移动互联网发展和岗位分析.pptx

    移动互联网发展和岗位分析.pptx

    数控加工程序设计.pptx

    数控加工程序设计.pptx

    毕业设计基于STM32的智能停车场设计.zip

    毕业设计基于STM32的智能停车场设计基于STM32的智能停车场设计项目介绍该项目为毕业设计。基于STM32F1平台的智能停车场,板卡划分为主板、控制台指示板及场内红外检测板,支持短信定时报告停车场状态与远程控制、进出场自动电梯停车杆并播报欢迎消息、检测车位和环境温湿度并在屏幕实时显示状态。目前阶段正在进行电路验证设计与打样阶段。预计2月上旬至中旬完成电路设计并进入编码阶段。目前功能概述车辆进场与退场时,语音播报相应的欢迎语句并自动升起停车杆。待车辆完全驶入停车场后,自动降下停车杆。通过红外方式检测车位停车状态,并在门口控制台和相应车位显示停车状态。屏幕显示当前可用车票和当前温湿度每1小时通过短信报告目前停车场车位情况、1小时内车辆进出数量。短信下发控制指令。后续阶段功能车辆停车计费功能。冲卡检测并自动报警功能。加入实时时钟,通过短信安排时间。用户使用场景功能列表模块 功能 商品分类STM32F103VET6 微型系统板 毕业设计使用的开发板 单片机F103VESIM800L模块 支持GPRS短信收发的功能 12864液晶屏

    基于SpringBoot+Vue.js的轻小说在线阅读网站前后端分离全部资料+详细文档.zip

    【资源说明】 基于SpringBoot+Vue.js的轻小说在线阅读网站前后端分离全部资料+详细文档.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    “腾达”游戏分享网站的设计与实现_97c7a2s2.zip

    “腾达”游戏分享网站的设计与实现_97c7a2s2

    大数据与会计 (9).docx

    大数据与会计 (9)

    数学建模matlabppt课件市公开课一等奖百校联赛特等奖课件.pptx

    数学建模matlabppt课件市公开课一等奖百校联赛特等奖课件.pptx

    城市轨道交通通信信号技术_.docx

    城市轨道交通通信信号技术_

    【毕业设计+开题答辩】-基于JAVA_JSP电子书下载系统-【源代码+截图+数据库+论文+视频讲解】

    本文中的项目资源均整理自互联网,若侵犯了您的权益,请及时联系博主,博主会及时处理。 项目资源中使用的技术和系统用处不一定准确和全面,我只是大致的浏览了一下,具体使用技术建议参考代码和视频讲解。 资源中的各内容不一定每一个都非常的完美,可能会有少许错误,建议多看几个,选其中一个自己觉得不错的,用来做毕设或者开题等等。 资源中所列论文可以参考,但是不建议且强烈不建议直接照搬照抄,因为毕竟要查重,避免引起不必要的麻烦。

    压力表计算机软件及应用it计算机专业资料.pptx

    压力表计算机软件及应用it计算机专业资料.pptx

    钢材器材破损铁锈检测69-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar

    钢材器材破损铁锈检测69-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar钢重用-V4 2024-03-27 5:01 PM ============================= *与您的团队在计算机视觉项目上合作 *收集和组织图像 *了解和搜索非结构化图像数据 *注释,创建数据集 *导出,训练和部署计算机视觉模型 *使用主动学习随着时间的推移改善数据集 对于最先进的计算机视觉培训笔记本,您可以与此数据集一起使用 该数据集包括1094张图像。 钢元素以可可格式注释。 将以下预处理应用于每个图像: *像素数据的自动取向(带有Exif-Arientation剥离) *调整大小为416x416(拉伸) 应用以下扩展来创建每个源图像的3个版本: *水平翻转的50%概率 *以下90度旋转之一的同等概率:无,顺时针,逆时针方向 * -15%至+15%之间的随机BRIGTHNESS调整 * 0到0.8像素之间的随机高斯模糊

Global site tag (gtag.js) - Google Analytics