当前位置: 首页 > news >正文

C#百万数据处理

C#百万数据处理

在我们经验的不断增长中不可避免的会遇到一些数据量很大操作也复杂的业务
这种情况我们如何取优化如何去处理呢?一般都要根据业务逻辑和背景去进行合理的改进。


文章目录

  • C#百万数据处理
  • 前言
  • 一、项目业务需求和开发背景
    • 项目开发背景
    • 数据量计算
    • 业务需求
    • 业务分析
  • 二、老代码分析
    • 运行逻辑
    • 代码展示
    • 伪代码展示
    • 分析性能低原因
  • 三、优化后的代码分析
    • 运行逻辑
    • 代码展示
    • 伪代码展示
    • 优化了那些问题
  • 总结


前言

这里我给大家带来一个我自己所经历的百万数据处理案例,该案例中会拿优化前和优化后的代码进行对比,让大家更直观的感受优化给项目带来的效率提升。该项目优化用到了:线程同步,多线程,sqlSugar,异步,委托等知识。


一、项目业务需求和开发背景

在这里插入图片描述

项目开发背景

随着连锁门店数量的不断增加,门店商品的库存数据和商品信息的维护业务压力不断增加。数据量越来越大。

数据量计算

假如数据如下:

  • 门店数量:160家
  • 门店商品数量:6000+
  • 还需要更新商品对码信息:6000+
  • 数据接口最多每页查询1000条
  • 那么按以上数据要处理的数据最少就为:966000条

业务需求

  1. 新的商品要做插入操作
  2. 旧的商品要做更新操作(更新库存信息和商品编码厂家等信息)
  3. 门店库存数据变更要在半小时内完成

业务分析

按以上条件我们可以分析出:需要有Insert和Update操作。其中经验丰富的程序员就会发现,其实像这种业务一般 Insert操作最多只占所有业务的20%,Update操作占80%。
注意:
很多小白程序员都是不进行业务分析就直接撸代码,这种方式是不可取的,等你撸完代码之后你就会发现效率根本就不行。后面又花大量时间去优化,还如不体现分析了再进行开发。

二、老代码分析

运行逻辑

老代码的操作流程如下

  1. 查询出所有门店
  2. 循环门店,将门店数据传入操作函数中
  3. 操作函数中再根据传入的门店信息循环去调用接口
  4. 当传入的这个门店的数据拉取完成之后再去操作数据库

代码展示

代码如下:

//查询所有门店商品信息List<StoreCheckCodeDO> storeInfos = b_Stores.GetStoreCheckCodes();//这里是用于更新对码的信息List<ProductInfoDO> infoDOs = new List<ProductInfoDO>();foreach (var storeInfo in storeInfos ){//GetProductInfo的作用是调用总部接口获取并更新商品数据InventoryHelper.GetProductInfo(storeInfo , ref infoDOs );}if(infoDOs.count>0){//更新对码信息InventoryHelper.ChangeProductCheckCode(infoDOs);}

GetProductInfo 的具体实现:

public static bool GetProductInfo(string orgid, ref List<ProductInfoDO> infoDOs, string goodsNo = "", string goodsName = ""){bool rel = false;int pageSize = 1000;int pageNum = 1;List<DslStoreStockDO> list =根据门店ID查询它的商品库存信息Console.WriteLine("开始更新门店:{0}", orgid);//定义个集合来存储拉取到的数据List<StoreStockDO> Stores = new List<StoreStockDO>();while (true){try{DslERPRes<QueryStockRes> res3 =调用总部数据接口每页查询1000条,返回的数据if (res3 != null && res3.code == 0){if (res3.data != null && res3.data.list != null){if (res3.data.total > 0){#region 模型转换//循环总部返回的数据集合,并转成我们需要的DO是实体foreach (var product in res3.data.list){DslStoreStockDO dsl = new DslStoreStockDO();把总部数据转为我们需要的实体存储我们的集合中dslStores.Add(dsl);ProductInfoDO infoDO = 根据总部商品ID查询本地对码表返回商品对码信息实体if (infoDO == null){//如果没有则new一个对象infoDO = new ProductInfoDO();infoDO.LocalSku = product.goodsNo.ToString();}//如果有这个商品就对其数据更新,没有就用新的对象存储后续做新增操作infoDO.Name = product.goodsName;infoDO.DslSku = product.goodsNo.ToString();infoDO.goodsType = product.goodsType;infoDO.proarea = product.prodArea;infoDO.barcode = product.barcode;infoDO.CreateTime = DateTime.Now;infoDO.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");infoDO.Operator = "系统自动更新";infoDO.IsDelete = false;//查询集合中已存在的该商品ProductInfoDO b_there = infoDOs.Where(t => t.DslSku == product.goodsNo.ToString()).FirstOrDefault();if (b_there != null){//如果有则更新为现在从总部拉取到的商品信息if (infoDO.goodsType != b_there.goodsType){b_there.goodsType = infoDO.goodsType;}if (infoDO.proarea != b_there.proarea){b_there.proarea = infoDO.proarea;}if (infoDO.barcode != b_there.barcode){b_there.barcode = infoDO.barcode;}}else{//插入实体集合中infoDOs.Add(infoDO);}}#endregion//判断该门店商品信息是否拉完if (res3.data.pages == pageNum){//利用list的 Except 方法进行数据筛选var different = list.Except(dslStores, new StoreStockDOComparer()).ToList();//找到没拉到库存的different.ForEach(goodsInfo =>{//把没有从总部拉到商品的库存数据变更为0goodsInfo.goodsQty = 0;goodsInfo.warehouseGoodsQty = 0;});//清除容器内数据从新插入信息变更数据//list 这个list就是我们开头根据门店id查询该门店所有商品库存信息的数据,//所以要清空重新写入我们调整好的数据list = new List<DslStoreStockDO>();list.AddRange(dslStores);list.AddRange(different);//获取完毕,正常结束Console.WriteLine("请稍等正在提交事务...");//_BulkCopyModel方法是做insertOrUpadate操作的。//根据后面传入的主键【goodsNo,placePointNo 】去操作数据库的数据int count = _sqlsugar_DSL._BulkCopyModel(list, "门店库存表", t => new { t.goodsNo, t.placePointNo });rel = count > 0;Console.WriteLine("门店:{0}数据更新成功,操作数据条数:{1}", orgid, count);break;}pageNum++;}else{Console.WriteLine("未查询到更新数据");break;}}else{///获取完毕,正常结束Console.WriteLine("门店:{0}第{1}页数据拉取失败", orgid, pageNum.ToString());break;}}else{//获取异常,强制结束Console.WriteLine("门店:{0}第{1}页数据发起请求失败:{2}", orgid, pageNum.ToString(), res3.msg);break;}}catch (Exception ex){Console.WriteLine("门店:{0}第{1}页数据处理失败:{2}", orgid, pageNum.ToString(), ex.Message);break;}}return rel;}

伪代码展示

上述代码还是比较复杂很长,不太能直观的一眼看到问题所在下面我就写一段伪造代码来给大家展示一下逻辑

代码如下(示例):

门店集合=查询到所有门店商品对码信息收集集合 =new List<T>();foreach (var 单个门店实体 in 门店集合 ){//GetProductInfo的作用是调用总部接口获取并更新商品数据InventoryHelper.GetProductInfo(门店ID, ref 商品对码信息收集集合 );}GetProductInfo(门店ID,ref 门店对码信息收集集合){List<库存数据实体> 旧库存数据=根据门店ID获取库存信息(门店ID);List<库存数据实体> 新库存数据=new  List<库存数据实体>();while(true){页码=1;每页查询数量=1000;总部数据返回数据集合=请求总部数据接口(页码,每页查询数量)foreach (var 数据返回数据实体 in 总部数据返回数据集合 ){数据返回数据实体 转为 库存数据实体 新库存数据.add(库存数据实体)数据返回数据实体数据 取出所需数据组成 商品对码实体门店对码信息收集集合.add(商品对码实体)}if(页码=总部返回数据集合.总页数){新库存数据 做Insert OR Update 操作break;}页码++;}}

分析性能低原因

  • 单线程,需要一个门店一个门店的处理
  • 每处理一个门店都需要去操作一次数据库,做Insert OR Update 操作
  • 单线程请求总部接口线程要等待接口返回才继续往下处理没有达到效率最大化
  • 每次都要去查询门店的所有商品库存,导致不必要的查询开销。

三、优化后的代码分析

运行逻辑

  • 查询出所有门店,根据传入线程数做分组
  • 多线程异步获取总部接口库存数据
  • 当分组的总部数据获取完成后以组为单位更新数据库数据

代码展示

代码如下:

 public static void GetProductInfo(List<DslStoreCheckCodeDO> orgids, int ThreadNumber = 1){if (ThreadNumber > orgids.Count){ThreadNumber = 1;}string startTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");List<List<DslStoreCheckCodeDO>> groupedLists = orgids.Select((value, index) => new { Index = index, Value = value }).GroupBy(x => x.Index / (orgids.Count() / ThreadNumber)).Select(x => x.Select(v => v.Value).ToList()).ToList();List<ProductInfoDO> outval = new List<ProductInfoDO>();int _ThreadCount = groupedLists.Count();int finishcount = 0;object locker = new object();foreach (var dslStores in groupedLists){new Thread(async () =>{string TID = Thread.CurrentThread.ManagedThreadId.ToString("00");int count = 0;List<ProductInfoDO> productInfos = new List<ProductInfoDO>();List<DslStoreStockDO> dslStock = new List<DslStoreStockDO>();foreach (var StoreInfo in dslStores){count++;Console.WriteLine("线程ID[{0}]剩余【{1}/{2}】", TID, dslStores.Count, count);string orgid = StoreInfo.DslStoreNo;List<ProductS> products = await GetProductInfo(orgid);#region 模型转换foreach (var product in products){DslStoreStockDO dsl = new DslStoreStockDO();dsl.placePointNo = orgid;dsl.goodsNo = product.goodsNo;dsl.goodsId = product.goodsId;dsl.goodsName = product.goodsName;dsl.goodsType = string.IsNullOrWhiteSpace(product.goodsType) ? "无" : product.goodsType;dsl.prodArea = product.prodArea ?? "无";dsl.barcode = string.IsNullOrWhiteSpace(product.barcode) ? "无" : product.barcode;dsl.goodsQty = product.goodsQty;dsl.warehouseGoodsQty = product.warehouseGoodsQty ?? 0;dsl.purPrice = product.purPrice ?? 0;dsl.retailPrice = product.retailPrice;dsl.salesTaxRate = product.salesTaxRate;dsl.cretime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");dsl.isChange = true;dslStock.Add(dsl);ProductInfoDO infoDO = dSL_ERP.GetCodeCahe(product.goodsNo.ToString());if (infoDO == null){infoDO = new ProductInfoDO();infoDO.LocalSku = product.goodsNo.ToString();}infoDO.Name = product.goodsName;infoDO.DslSku = product.goodsNo.ToString();infoDO.goodsType = product.goodsType;infoDO.proarea = product.prodArea;infoDO.barcode = product.barcode;infoDO.CreateTime = DateTime.Now;infoDO.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");infoDO.Operator = "系统自动更新";infoDO.IsDelete = false;productInfos.Add(infoDO);}#endregion}if (count == dslStores.Count){   //分配的门店处理完成后再同一操作数据库List<string> SotoreIds = dslStores.Select(t => t.DslStoreNo).ToList();List<DslStoreStockDO> Oldstocks = _sqlsugar_DSL.GetModelList<DslStoreStockDO>("StoreStock", t => SotoreIds.Contains(t.placePointNo)); List<DslStoreStockDO> newStocks = dslStock.Except(Oldstocks, new StoreStockDOComparer()).ToList();List<DslStoreStockDO> commonStocks = dslStock.Except(newStocks, new StoreStockDOComparer()).ToList();try{if (Oldstocks.Count > 0){var diffent = Oldstocks.Except(dslStock, new StoreStockDOComparer()).ToList();diffent.ForEach(goodsInfo =>{goodsInfo.goodsQty = 0;goodsInfo.warehouseGoodsQty = 0;});commonStocks.AddRange(diffent);}Console.WriteLine("请稍等正在提交...");int InsNumber = 0;if (newStocks.Count > 0){InsNumber = await _sqlsugar_DSL.AsynBulkCopyModel(newStocks, "StoreStock", t => new { t.goodsNo, t.placePointNo });}int UpdNumber = await _sqlsugar_DSL.AsynBulkUpdateModel(commonStocks, "StoreStock", new string[] { "goodsNo", "placePointNo" }, new string[] { "placePointNo", "goodsNo", "goodsId", "goodsName", "goodsType", "prodArea", "barcode", "goodsQty", "warehouseGoodsQty", "purPrice", "retailPrice", "salesTaxRate", "cretime", "isChange" });Console.WriteLine("提交成功,更新{0}条数据,插入{1}条数据", UpdNumber, InsNumber);}catch (Exception ex){Console.WriteLine("线程{0}内部报错:{1}", TID, ex.Message);}}lock (locker){outval.AddRange(productInfos);finishcount++;Monitor.Pulse(locker); //完成,通知等待队列,告知已完,执行下一个。}}).Start();}lock (locker){while (finishcount != _ThreadCount){Monitor.Wait(locker);//等待}}IEnumerable<ProductInfoDO> infoDOs = outval.OrderByDescending(x => x.UpdateTime).GroupBy(x => new { x.DslSku, x.barcode }).Select(y => y.First());Console.WriteLine("开始更新商品对码表,待更新数:{0}", infoDOs.Count());if (infoDOs.Count() > 0){Console.WriteLine("正在提交...");ChangeProductCheckCode(infoDOs.ToList());Dictionary<string, string> pairs = new Dictionary<string, string>();pairs.Add("JsonStr", CommonFun.Base64Encode(JsonConvert.SerializeObject(infoDOs)));string rel = HttpHelper.HttpPost("...", pairs);Console.WriteLine("商品对码表跟新成功,商品信息表更新:{0}", rel);}Console.WriteLine("【全量更新所有门店】执行完毕线程挂起24小时...[Start:{0}|End:{1}]", startTime, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));#region 异步获取商品信息async Task<List<ProductS>> GetProductInfo(string orgid){List<ProductS> products = new List<ProductS>();string res = await Task.Run(() =>{int pageNum = 1;int pageSize = 1000;while (true){QueryStockReq req3 = new QueryStockReq();req3.goodsno = "";req3.goodsName = "";req3.pageNum = pageNum;req3.pageSize = pageSize;req3.placePointNo = orgid;Console.WriteLine("门店【{1}】开始获取第{0}页数据-线程ID【{2}】", req3.pageNum.ToString(), orgid, Thread.CurrentThread.ManagedThreadId.ToString("00"));DslERPReq dslERP23 = new DslERPReq(req3);DslERPRes<QueryStockRes> res3 = dSL_ERP.queryStock(dslERP23);if (res3 != null && res3.code == 0){if (res3.data != null && res3.data.list != null){if (res3.data.total > 0){products.AddRange(res3.data.list);if (res3.data.pages == pageNum){break;}pageNum++;}else{Console.WriteLine("未查询到更新数据,返回数据{0},数据JSON:【{1}】", res3.msg, JsonConvert.SerializeObject(res3));break;}}else{Console.WriteLine("门店:{0}第{1}页数据拉取失败返回信息{2}", orgid, req3.pageNum.ToString(), res3.msg);break;}}else{Console.WriteLine("门店:{0}第{1}页数据发起请求失败:{2}", orgid, req3.pageNum.ToString(), res3.msg);}}return "";});return products;}#endregion}

伪代码展示

 public static void GetProductInfo(List<门店信息实体> 门店信息实体集合, int 处理线程数量= 1){if (处理线程数量 > 门店信息实体集合.Count){处理线程数量 = 1;}string startTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");List<List<门店信息实体>> 门店分组集合= 门店信息实体集合.Select((value, index) => new { Index = index, Value = value }).GroupBy(x => x.Index / (门店信息实体集合.Count() / 处理线程数量)).Select(x => x.Select(v => v.Value).ToList()).ToList();List<商品对码实体> outval = new List<商品对码实体>();int _ThreadCount = 门店分组集合.Count();int finishcount = 0;object locker = new object();//线程锁foreach (var 门店实体集合 in 门店分组集合){new Thread(async () =>{string TID = Thread.CurrentThread.ManagedThreadId.ToString("00");int count = 0;List<ProductInfoDO> productInfos = new List<ProductInfoDO>();List<库存数据实体> 总部库存数据集合= new List<库存数据实体>();foreach (var StoreInfo in 门店实体集合){count++;Console.WriteLine("线程ID[{0}]剩余【{1}/{2}】", TID, 门店实体集合.Count, count);string orgid = StoreInfo.门店ID;//这里是异步从总部库存信息接口获取商品库存信息List<ProductS> products = await GetProductInfo(orgid);#region 模型转换foreach (var product in products){库存数据实体dsl = new 库存数据实体();dsl.placePointNo = orgid;dsl.goodsNo = product.goodsNo;dsl.goodsId = product.goodsId;dsl.goodsName = product.goodsName;dsl.goodsType = string.IsNullOrWhiteSpace(product.goodsType) ? "无" : product.goodsType;dsl.prodArea = product.prodArea ?? "无";dsl.barcode = string.IsNullOrWhiteSpace(product.barcode) ? "无" : product.barcode;dsl.goodsQty = product.goodsQty;dsl.warehouseGoodsQty = product.warehouseGoodsQty ?? 0;dsl.purPrice = product.purPrice ?? 0;dsl.retailPrice = product.retailPrice;dsl.salesTaxRate = product.salesTaxRate;dsl.cretime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");dsl.isChange = true;总部库存数据集合.Add(dsl);ProductInfoDO infoDO = dSL_ERP.GetCodeCahe(product.goodsNo.ToString());if (infoDO == null){infoDO = new ProductInfoDO();infoDO.LocalSku = product.goodsNo.ToString();}infoDO.Name = product.goodsName;infoDO.DslSku = product.goodsNo.ToString();infoDO.goodsType = product.goodsType;infoDO.proarea = product.prodArea;infoDO.barcode = product.barcode;infoDO.CreateTime = DateTime.Now;infoDO.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");infoDO.Operator = "系统自动更新";infoDO.IsDelete = false;productInfos.Add(infoDO);}#endregion}//注意这里我为什么要用count来判断这组是否执行完成,因为我们操作数据库的语句优化为了异步的//而Look语句内是不支持await 语句的,所有利用组合里的门店数和已处理数来判断if (count == 门店实体集合.Count){   //分配的门店处理完成后再同一操作数据库List<string> SotoreIds = 门店实体集合.Select(t => t.门店ID).ToList();// 查询出这个批次里所有门店的老的库存数据List<库存数据实体> Oldstocks = _sqlsugar_DSL.GetModelList<库存数据实体>("StoreStock", t => SotoreIds.Contains(t.门店ID)); //List<库存数据实体> newStocks = 总部库存数据集合.Except(Oldstocks, new StoreStockDOComparer()).ToList();List<库存数据实体> commonStocks = 总部库存数据集合.Except(newStocks, new StoreStockDOComparer()).ToList();try{if (Oldstocks.Count > 0){var diffent = Oldstocks.Except(总部库存数据集合, new StoreStockDOComparer()).ToList();diffent.ForEach(goodsInfo =>{goodsInfo.goodsQty = 0;goodsInfo.warehouseGoodsQty = 0;});commonStocks.AddRange(diffent);}Console.WriteLine("请稍等正在提交...");int InsNumber = 0;if (newStocks.Count > 0){InsNumber = await _sqlsugar_DSL.AsynBulkCopyModel(newStocks, "StoreStock", t => new { t.goodsNo, t.placePointNo });}int UpdNumber = await _sqlsugar_DSL.AsynBulkUpdateModel(commonStocks, "StoreStock", new string[] { "goodsNo", "placePointNo" }, new string[] { "placePointNo", "goodsNo", "goodsId", "goodsName", "goodsType", "prodArea", "barcode", "goodsQty", "warehouseGoodsQty", "purPrice", "retailPrice", "salesTaxRate", "cretime", "isChange" });Console.WriteLine("提交成功,更新{0}条数据,插入{1}条数据", UpdNumber, InsNumber);}catch (Exception ex){Console.WriteLine("线程{0}内部报错:{1}", TID, ex.Message);}}lock (locker){outval.AddRange(productInfos);finishcount++;Monitor.Pulse(locker); //完成,通知等待队列,告知已完,执行下一个。}}).Start();}lock (locker){while (finishcount != _ThreadCount){Monitor.Wait(locker);//等待}}IEnumerable<ProductInfoDO> infoDOs = outval.OrderByDescending(x => x.UpdateTime).GroupBy(x => new { x.DslSku, x.barcode }).Select(y => y.First());Console.WriteLine("开始更新商品对码表,待更新数:{0}", infoDOs.Count());if (infoDOs.Count() > 0){Console.WriteLine("正在提交...");ChangeProductCheckCode(infoDOs.ToList());Dictionary<string, string> pairs = new Dictionary<string, string>();pairs.Add("JsonStr", CommonFun.Base64Encode(JsonConvert.SerializeObject(infoDOs)));string rel = HttpHelper.HttpPost("...", pairs);Console.WriteLine("商品对码表跟新成功,商品信息表更新:{0}", rel);}Console.WriteLine("【全量更新所有门店】执行完毕线程挂起24小时...[Start:{0}|End:{1}]", startTime, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));#region 异步获取商品信息async Task<List<ProductS>> GetProductInfo(string orgid){List<ProductS> products = new List<ProductS>();string res = await Task.Run(() =>{int pageNum = 1;int pageSize = 1000;while (true){QueryStockReq req3 = new QueryStockReq();req3.goodsno = "";req3.goodsName = "";req3.pageNum = pageNum;req3.pageSize = pageSize;req3.placePointNo = orgid;Console.WriteLine("门店【{1}】开始获取第{0}页数据-线程ID【{2}】", req3.pageNum.ToString(), orgid, Thread.CurrentThread.ManagedThreadId.ToString("00"));DslERPReq dslERP23 = new DslERPReq(req3);DslERPRes<QueryStockRes> res3 = dSL_ERP.queryStock(dslERP23);if (res3 != null && res3.code == 0){if (res3.data != null && res3.data.list != null){if (res3.data.total > 0){products.AddRange(res3.data.list);if (res3.data.pages == pageNum){break;}pageNum++;}else{Console.WriteLine("未查询到更新数据,返回数据{0},数据JSON:【{1}】", res3.msg, JsonConvert.SerializeObject(res3));break;}}else{Console.WriteLine("门店:{0}第{1}页数据拉取失败返回信息{2}", orgid, req3.pageNum.ToString(), res3.msg);break;}}else{Console.WriteLine("门店:{0}第{1}页数据发起请求失败:{2}", orgid, req3.pageNum.ToString(), res3.msg);}}return "";});return products;}#endregion}

优化了那些问题

  • 从总部取数据变为了异步多线程避免了线程阻塞
  • 门店按组合处理减小了数据库操作次数
  • 操作数据库改为异步避免阻塞

总结

以上就是我个人所经历的大数据处理,虽然优化的并不算完美但是还是总结出了不少经验,也从中学习到了很多,比如,单线程和多线程的运用以及委托和线程同步等知识。

相关文章:

C#百万数据处理

C#百万数据处理 在我们经验的不断增长中不可避免的会遇到一些数据量很大操作也复杂的业务 这种情况我们如何取优化如何去处理呢&#xff1f;一般都要根据业务逻辑和背景去进行合理的改进。 文章目录 C#百万数据处理前言一、项目业务需求和开发背景项目开发背景数据量计算业务需…...

windows端口占用

1.查看当前端口被哪个进程占用了&#xff08;进入到CMD中&#xff09; netstat -ano|findstr "8990"输出结果为&#xff1a; TCP 127.0.0.1:8990 0.0.0.0:0 LISTENING 2700 我们发现8990端口被2700进程占用了 2.基于进程号找进程名称 tasklist|findstr "2700&qu…...

如何理解Diffusion

Diffusion算法可以有多个角度进行理解&#xff0c;不同的理解方式只是对目标函数进行了不同的解释。其主体思想是不变的&#xff0c;可以归纳为&#xff1a; 训练时通过图片逐步添加噪声&#xff0c;变为一个纯噪声。然后学习每一步的噪声。推理时给定一个随机噪声图片&#x…...

自然语言处理从入门到应用——LangChain:模型(Models)-[聊天模型(Chat Models):使用少量示例和响应流式传输]

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 使用少量示例 本部分的内容介绍了如何在聊天模型&#xff08;Chat Models&#xff09;中使用少量示例。关于如何最好地进行少量示例提示尚未形成明确的共识。因此&#xff0c;我们尚未固定任何关于此的抽象概念&#…...

Java在线OJ项目(三)、前后端交互API模块

Java在线OJ项目&#xff08;三&#xff09;、前后端交互API模块 1. 客户端向服务器请求所有题目 或者 单个题目前端获取所有题目获取一个题目 后端 2. 后端读取前端提交的代码&#xff0c;进行编译运行&#xff0c;返回结果前端提交代码后端处理 1. 客户端向服务器请求所有题目…...

项目——负载均衡在线OJ

目录 项目介绍开发环境所用技术项目宏观结构编写思路1. 编写compile_server1.1 编译模块编写1.2 运行功能1.3compile_runner 编译与运行1.4 编写compile_server.cpp调用compile_run模块&#xff0c;形成网络服务 2. 编写基于MVC的oj_server2.1 oj_server.cpp的编写2.2 oj_model…...

idea连接远程服务器上传war包文件

idea连接远程服务器&上传war包 文章目录 idea连接远程服务器&上传war包1. 连接服务器2.上传war包 1. 连接服务器 选择Tools -> Start SSH Session 添加配置 连接成功 2.上传war包 Tools -> Deployment -> Browse Remote Host 点击右侧标签&#xff0c;点击&…...

使用PyGWalker可视化分析表格型数据

大家好&#xff0c;可以想象一下在Jupyter Notebook中拥有大量数据&#xff0c;想要对其进行分析和可视化。PyGWalker就像一个神奇的工具&#xff0c;能让这项工作变得超级简单。它能获取用户的数据&#xff0c;并将其转化为一种特殊的表格&#xff0c;可以与之交互&#xff0c…...

Visual C++中的虚函数和纯虚函数(以外观设计模式为例)

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天来说说Visual C中的虚函数和纯虚函数。该系列帖子全部使用我本人自创的对比学习法。也就是当C学不下去的时候&#xff0c;就用JAVA实现同样的代码&#xff0c;然后再用对比的方法把C学会。 直接说虚函数…...

电子元器件选型与实战应用—01 电阻选型

大家好, 我是记得诚。 这是《电子元器件选型与实战应用》专栏的第一篇文章,今天的主角是电阻,在每一个电子产品中,都少不了电阻的身影,其重要性不言而喻。 文章目录 1. 入门知识1.1 基础1.2 常用品牌1.3 电阻的种类2. 贴片电阻标识2.1 三位数标注法2.2 四位数标注法2.3 小…...

javascript 模板引擎

使用场景 在实际开发中&#xff0c;一般都是使用动态请求数据来更新页面&#xff0c;服务器端通常返回json格式的数据&#xff0c;正常操作是我们手动的去拼装HTML&#xff0c;但麻烦且容易出错&#xff0c;因此出现了一些用模版生成HTML的的框架叫js模板引擎如&#xff1a;jq…...

【数据结构】带头+双向+循环链表(DList)(增、删、查、改)详解

一、带头双向循环链表的定义和结构 1、定义 带头双向循环链表&#xff0c;有一个数据域和两个指针域。一个是前驱指针&#xff0c;指向其前一个节点&#xff1b;一个是后继指针&#xff0c;指向其后一个节点。 // 定义双向链表的节点 typedef struct ListNode {LTDataType dat…...

接口自动化测试平台

下载了大神的EasyTest项目demo修改了下<https://testerhome.com/topics/12648 原地址>。也有看另一位大神的HttpRunnerManager<https://github.com/HttpRunner/HttpRunnerManager 原地址>&#xff0c;由于水平有限&#xff0c;感觉有点复杂~~~ 【整整200集】超超超…...

【物联网】微信小程序接入阿里云物联网平台

微信小程序接入阿里云物联网平台 一 阿里云平台端 1.登录阿里云 阿里云物联网平台 点击进入公共实例&#xff0c;之前没有的点进去申请 2.点击产品&#xff0c;创建产品 3.产品名称自定义&#xff0c;按项目选择类型&#xff0c;节点类型选择之恋设备&#xff0c;联网方式W…...

PKG内容查看工具:Suspicious Package for Mac安装教程

Suspicious Package Mac版是一款Mac平台上的查看 PKG 程序包内信息的应用&#xff0c;Suspicious Package Mac版支持查看全部包内全部文件&#xff0c;比如需要运行的脚本&#xff0c;开发者&#xff0c;来源等等。 suspicious package mac使用简单&#xff0c;只需在选择pkg安…...

第16节:R语言医学分析实例:肺切除手术的Apriori关联规则分析

关联规则 肺切除手术的Apriori关联规则分析。 分析的目的是确定患有肺癌并需要接受肺切除术的患者的共病症状。 了解哪些症状是共病的可以帮助改善患者护理和药物处方。 分析类型是关联规则学习,通过探索变量之间的关联或频繁项集,尝试在大型数据集中找到见解和隐藏关系(H…...

ChatGPT+MidJourney 3分钟生成你的动画故事

chatgpt是真的火了&#xff0c;chatgpt产生了一个划时代的意义——自chatgpt起&#xff0c;AI是真的要落地了。 chatgpt能做的事情太多了&#xff0c;多到最初开发模型的程序员自己&#xff0c;也没法说得清楚chatgpt都能做啥&#xff0c;似乎只要你能想得到&#xff0c;它都有…...

在CSDN学Golang云原生(Kubernetes Pod调度)

一&#xff0c;NodeSelector定向调度 在 Kubernetes 中&#xff0c;可以使用 NodeSelector 字段来指定 Pod 调度到哪些节点上运行。NodeSelector 是一个键值对的 map&#xff0c;其中键是节点的标签名&#xff0c;值是标签值。具体步骤如下&#xff1a; 在节点上添加标签 首…...

Rust vs Go:常用语法对比(七)

题图来自 Go vs Rust: Which will be the top pick in programming?[1] 121. UDP listen and read Listen UDP traffic on port p and read 1024 bytes into buffer b. 听端口p上的UDP流量&#xff0c;并将1024字节读入缓冲区b。 import ( "fmt" "net&qu…...

【HarmonyOS】API6使用storage实现轻量级数据存储

写在前面 本篇内容基于API6 JS语言进行开发&#xff0c;通过结合轻量级数据存储开发指导的文档&#xff0c;帮助大家完成一个实际的代码案例&#xff0c;通过这个小案例&#xff0c;可以实现简单数据的存储。 参考文档&#xff1a;文档中心 1、页面布局 首先我们编写一个简单…...

Python Flask构建微信小程序订餐系统 (十二)

🔥 创建切换商品分类状态的JS文件 🔥 ; var food_act_ops={init:function(){this.eventBind();},eventBind:function(){//表示作用域var that = this;$(".wrap_search select[name=status]").change(function(){$(".wrap_search").submit();});$(&qu…...

C++——模板的作用2:特例化

目录 模板的形式&#xff1a; 一.模板的多参数应用&#xff1a; 例&#xff1a; 错误使用1&#xff1a;使用不标准的模板形参表 ​编辑 错误使用2&#xff1a;使用变量作为实参传递给函数模板 二.模板的特例化&#xff1a; 类模板&#xff1a; 针对模板的特化步骤&am…...

Python Web开发技巧VII

目录 装饰器inject_serializer 装饰器atomic rebase git 清理add的数据 查看git的当前工作目录 makemigrations文件名称 action(detailTrue, methods["GET"]) 如何只取序列化器的一个字段进行返回 Response和JsonResponse有什么区别 序列化器填表和单字段如…...

LaTex4【下载模板、引入文献】

下载latex模板&#xff1a;&#xff08;模板官网一般都有&#xff0c;去找&#xff09; 我这随便找了一个&#xff1a; 下载得到一个压缩包&#xff0c;然后用overleaf打开&#x1f447;&#xff1a; (然后改里面的内容就好啦) 另外&#xff0c;有很多在线的数学公式编辑器&am…...

【VSCode部署模型】导出TensorFlow2.X训练好的模型信息

参考tensorflow2.0 C加载python训练保存的pb模型 经过模型训练及保存&#xff0c;我们得到“OptimalModelDataSet2”文件夹&#xff0c;模型的保存方法(.h5或.pb文件)&#xff0c;参考【Visual Studio Code】c/c部署tensorflow训练的模型 其中“OptimalModelDataSet2”文件夹保…...

windows环境下,安装elasticsearch

目录 前言准备安装 jdk 安装nodejsElasticSearch下载ElasticSearch-head 下载 安装ElasticSearch安装ElasticSearch-head插件设置用户名密码访问ElasticSearch 默认用户名和密码参考 前言 win10elasticsearch 8.9.0 准备 安装 jdk ElasticSearch 是基于lucence开发的&#…...

Elasticsearch入门笔记(一)

环境搭建 Elasticsearch是搜索引擎&#xff0c;是常见的搜索工具之一。 Kibana 是一个开源的分析和可视化平台&#xff0c;旨在与 Elasticsearch 合作。Kibana 提供搜索、查看和与存储在 Elasticsearch 索引中的数据进行交互的功能。开发者或运维人员可以轻松地执行高级数据分析…...

记一次安装nvm切换node.js版本实例详解

最后效果如下&#xff1a; 背景&#xff1a;由于我以前安装过node.js&#xff0c;后续想安装nvm将node.js管理起来。 问题&#xff1a;nvm-use命令行运行成功&#xff0c;但是nvm-list显示并没有成功。 原因&#xff1a;因为安装过node.js&#xff0c;所以原先的node.js不收n…...

生态共建丨YashanDB与构力科技完成兼容互认证

近日&#xff0c;深圳计算科学研究院崖山数据库系统YashanDB V22.2与北京构力科技有限公司BIMBase云平台完成兼容性互认证。经严格测试&#xff0c;双方产品完全兼容、运行稳定。 崖山数据库系统YashanDB是深算院自主研发设计的新型数据库系统&#xff0c;融入原创理论&#xf…...

React从入门到实战-react脚手架,消息订阅与发布

创建项目并启动 全局安装 npm install -g create-react-app切换到想创建项目的目录&#xff0c;使用命令&#xff1a;create-react-app 项目名称 ​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存中…(iQ6hEUgAABpQAAAD1CAYAAABeIRZoAAAAAXNSR0IArs4c6QAAIABJREFUe…...

设立网站/百度开户推广多少钱

我明明 重定向了fputc 函数 但是无法在串口助手 输出内容 最后发现 不只是需要重定向fputc 函数 还需要配置魔术棒 需要勾选这个Use Micro LIB 然后重新编译 下载进去 串口助手就能正常显示我的数据了...

青岛做网站的/营销 推广

本题解不一定正确&#xff0c;欢迎大家指正 A&#xff1a;2023 【问题描述】 请求出在 12345678 至 98765432 中&#xff0c;有多少个数中完全不包含 2023 。 完全不包含 2023 是指无论将这个数的哪些数位移除都不能得到 2023 。 例如 20322175&#xff0c;33220022 都完全不包…...

网做 网站有哪些功能/农产品推广方案

用awk将文件中的几行合并为一行awk { printf ("%s ", $0)} END {printf ("\n") } 转载于:https://blog.51cto.com/maocong/1616687...

网站制作建设有哪些/软文客

写在最前&#xff1a;该篇文章还未完成&#xff0c;待进一步更新...。。一、初始 MycatMHALVS1、为什么选择 Mycat&#xff1f;互联网的高速发展使分布式技术兴起&#xff0c;当系统的压力越来越大时&#xff0c;人们首先想到的解决方案就是想上扩展(scale up)&#xff0c;简单…...

宽城区网站建设/免费seo营销软件

近日使用VMware fushion 8 centos 7.0时&#xff0c;无法使用共享功能&#xff0c;所以必须安装vmtools。但是安装过程中有2个错误需要解决。 1、gcc错误 Searching for GCC... The path "" is not valid path to the gcc binary. 2、内核头文件问题 Searching for …...

网易企业邮箱登录入口登录入口/seo是什么职位缩写

引言在可观察性领域&#xff0c;Metrics&#xff0c;Tracing 和 Logging 的介绍由来已久。三种之间的边界越来越模糊。OpenTracing 中已经支持 LogEvent&#xff0c;OpenTelemetry 已经把 OpenMetric 和 OpenTracing 整合到一块。今天我们要介绍的链路追踪的业务分析功能&#…...