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

C#上位机序列10: 批量读写+点对点更新+数据类型处理

一、源码结构

二、运行效果

三、源码解析

PLC批量读写+点对点更新+数据类型处理

优点:根据数据类型,判定监听的地址范围(40120_int 监听两个word:40120 40121;40130_long 监听四个word:40130 40131 40132 40133),添加到UI字典中,PLC批量读取,判定数据变化,查找控件集合,点对点更新,效率高

实现流程:
1. 读取配置文件及创建变量信息(点位名称,地址,数据类型(bool/short/int/float/long/double))

2. 自定义控件绑定参数,用UI字典存储,通过属性get方式,如果是bool类型,直接取Bool字典的点位数据;如果是Word类型,根据数据类型拼装Word字典中的word数据,得到对应数据类型的点位数据;通过set方式,加入到写队列。

复制代码

using PLCBind.CustomControls;
using PLCBind.Service;
using PLCBind.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;namespace PLCBind
{public partial class MainForm : Form{ public MainForm(){InitializeComponent();}private void MainForm_Load(object sender, EventArgs e){CommonMethods.LoadVar();// 读取配置文件及创建变量信息(点位名称,地址,类型)PLCService.Init();      // 读任务&写任务,数据有变化时事件广播通知(自定义控件预先绑定事件)BindControlParamModel();// 为按钮绑定参数}/// <summary>/// 为控件绑定参数/// </summary>private void BindControlParamModel(){InitControlTag(); SetControlParamModel();}/// <summary>/// 绑定控件变量/// </summary>void InitControlTag(){// 左皮带lblYX1.Tag = ucBeltLeft1.Tag = "00101";// 启动lblZS1.Tag = "40101";// 转速lblDY1.Tag = "40120";// 电压lblDL1.Tag = "40130";// 电流 }/// <summary>/// 赋值控件参数/// </summary>void SetControlParamModel(){foreach (Control item in this.pnlMain.Controls){if (item is ITransferUI objItem){var address = item.Tag.ToString();var common = CommonMethods.HomeVariables.Where(obj => obj.PLCAddress == address).FirstOrDefault();if (common != null){objItem.ParamModel = common;List<string> lstAddress = null;switch (common.DataType){case DataType.Bool:lstAddress = PLCService.RangeAddress(common.PLCAddress, 0);break;case DataType.Short:lstAddress = PLCService.RangeAddress(common.PLCAddress, 0);break;case DataType.Int:case DataType.Float:lstAddress = PLCService.RangeAddress(common.PLCAddress, 2);// 40120 监听两个word:40120 40121break;case DataType.Long:case DataType.Double:lstAddress = PLCService.RangeAddress(common.PLCAddress, 4);// 40130 监听四个word:40130 40131 40132 40133break;} foreach (var range in lstAddress){  CommonMethods.AddControl(CommonMethods.DicHomeControl, range, item);}  }}}}private void tabControl1_SelectedIndexChanged(object sender, EventArgs e){var index = tabControl1.SelectedIndex;switch (index){case 0:this.ucParameter1.RemoveParams();break;case 1:// 参数设置this.pnlSet.Controls.Clear();this.pnlSet.Controls.Add(ucParameter1);this.ucParameter1.ListParams = CommonMethods.SetVariables.Where(s => s.Group == "顺序启动参数").ToList();break;}} }
}

复制代码

复制代码

using PLCBind.Service;namespace PLCBind.UIForm
{public class BaseParams{/// <summary>/// 描述/// </summary>public string Description { get; set; }/// <summary>/// PLC地址, 多个输入时,用";"分隔开/// </summary>public string PLCAddress { get; set; } /// <summary>/// 数据类型/// </summary>public DataType DataType { get; set; }/// <summary>/// 数据分组/// </summary>public string Group { get; set; }/// <summary>/// 单位/// </summary>public string Unit { get; set; }/// <summary>/// 设置与获取PLC值/// </summary>public object PLCValue{get{object obj = null; switch (DataType){case DataType.Bool:obj = PLCService.GetBool(PLCAddress);break;case DataType.Short:obj = PLCService.GetShort(PLCAddress);break;case DataType.Int:obj = PLCService.GetInt(PLCAddress);break;case DataType.Float:obj = PLCService.GetFloat(PLCAddress);break;case DataType.Long:obj = PLCService.GetLong(PLCAddress);break;case DataType.Double:obj = PLCService.GetDouble(PLCAddress);break;} return obj;}set{PLCService.AddWriteVariable(PLCAddress, value, DataType);}} }
}

复制代码

3. 异步任务处理:读任务&写任务,将读到的数据存到Data字典中,判断数据是否有发生变化,如果数据有变化,通过UI字典获取控件集合,调用更新方法

复制代码

using HslCommunication;
using HslCommunication.Core;
using HslCommunication.ModBus;
using PLCBind.CustomControls;
using PLCBind.Util;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
using UtilHelper;namespace PLCBind.Service
{public class PLCService{ public static ConcurrentDictionary<string, bool> DicBoolData = new ConcurrentDictionary<string, bool>();public static ConcurrentDictionary<string, Word> DicWordData = new ConcurrentDictionary<string, Word>();public static ConcurrentDictionary<string, Word> DicWordChange = new ConcurrentDictionary<string, Word>();//static ModbusTcpNet client = null;static IByteTransform byteTransform;static ConcurrentQueue<PLCModel> queueWrite = new ConcurrentQueue<PLCModel>();// UI通知static void NoticeUI(string address, ConcurrentDictionary<string, List<Control>> dicControl){dicControl.TryGetValue(address, out List<Control> lstControl);if (null != lstControl){foreach (var item in lstControl){if (item is ITransferUI objItem){objItem.NoticeChange();}}}}/// <summary>/// 事件触发/// </summary> public static void DataChange(string address){Task.Run(() => NoticeUI(address, CommonMethods.DicHomeControl));Task.Run(() => NoticeUI(address, CommonMethods.DicSetControl));}/// <summary>/// 自定义控件内接收到数据变化事件,根据传入address,以及DataType查询监听地址所需要的监听范围(40120_int 监听两个word:40120 40121;40130_long 监听四个word:40130 40131 40132 40133),判断是否属于本控件监听/// </summary>public static List<string> RangeAddress(string address, int length){List<string> lstaddress = new List<string>();if (0 == length){lstaddress.Add(address);}else{for (int i = 0; i < length; i++){lstaddress.Add(FillAddress((DataHelper.Obj2Int(address) + i).ToString()));}}return lstaddress;}/// <summary>/// 读取时,按位补充0/// </summary>public static string FillAddress(string val, int length = 5){return val.PadLeft(length, '0');}/// <summary>/// 写入时,格式化地址,如:40101 -> 101/// </summary> public static string FormatAddress(string val){if (val.Length < 5) return val;return val.Substring(1, val.Length - 1);}/// <summary>/// 初始化plc通信,开启读写任务/// </summary>public static void Init(){client = new ModbusTcpNet(CommonMethods.PLCConfig.HostAddress, CommonMethods.PLCConfig.PortNumber);client.AddressStartWithZero = false;client.DataFormat = DataFormat.CDAB;byteTransform = client.ByteTransform;TskPlcRead();TskPlcWrite();}/// <summary>/// 获取bool(bool类型)/// </summary>/// <param name="address"></param>/// <returns></returns>public static bool GetBool(string address){ try{bool exist = DicBoolData.TryGetValue(address, out var value);// 字典存储if (!exist){Logger.Info($"[Error] PLCService,GetBool,errmsg:查无点位数据({address})");}return value;}catch (Exception ex){Logger.Info("[Error] PLCService,GetBool,errmsg:" + ex.Message);}return false;}/// <summary>/// 获取word(1个word,2个字节)/// </summary> static Word GetAddressWord(string address, int add){address = FillAddress((Convert.ToInt32(address) + add).ToString());bool exist = DicWordData.TryGetValue(address, out var value);if (!exist){Logger.Info($"[Error] PLCService,GetAddressWord,errmsg:查无点位数据({address})");}return value;}/// <summary>/// 拼接字节(多个word)/// </summary> static byte[] JoinAddressWord(string address, DataType datatype){byte[] ret = null;switch (datatype){ case DataType.Short:{ var buff = GetAddressWord(address, 0);ret = new byte[2] { buff.Byte1, buff.Byte2 };}break;case DataType.Int:case DataType.Float:{var buff1 = GetAddressWord(address, 0);var buff2 = GetAddressWord(address, 1);ret = new byte[4] { buff1.Byte1, buff1.Byte2, buff2.Byte1, buff2.Byte2 };} break;case DataType.Long: case DataType.Double:{var buff1 = GetAddressWord(address, 0);var buff2 = GetAddressWord(address, 1);var buff3 = GetAddressWord(address, 2);var buff4 = GetAddressWord(address, 3);ret = new byte[8] { buff1.Byte1, buff1.Byte2, buff2.Byte1, buff2.Byte2, buff3.Byte1, buff3.Byte2, buff4.Byte1, buff4.Byte2 };} break;}return ret;}public static ushort GetShort(string address){try{ var buff = JoinAddressWord(address, DataType.Short);return byteTransform.TransUInt16(buff, 0); }catch (Exception ex){Logger.Info("[Error] PLCService,GetShort,errmsg:" + ex.Message);}return 0;}public static uint GetInt(string address){try{var buff = JoinAddressWord(address, DataType.Int);return byteTransform.TransUInt32(buff, 0);}catch (Exception ex){Logger.Info("[Error] PLCService,GetInt,errmsg:" + ex.Message);}return 0;}public static float GetFloat(string address){try{var buff = JoinAddressWord(address, DataType.Float);return byteTransform.TransSingle(buff, 0);}catch (Exception ex){Logger.Info("[Error] PLCService,GetFloat,errmsg:" + ex.Message);}return 0;}public static ulong GetLong(string address){try{var buff = JoinAddressWord(address, DataType.Long);return byteTransform.TransUInt64(buff, 0);}catch (Exception ex){Logger.Info("[Error] PLCService,GetLong,errmsg:" + ex.Message);}return 0;}public static double GetDouble(string address){try{var buff = JoinAddressWord(address, DataType.Double);return byteTransform.TransDouble(buff, 0);}catch (Exception ex){Logger.Info("[Error] PLCService,GetDouble,errmsg:" + ex.Message);}return 0;}/// <summary>/// 定时读取/// </summary>static void TskPlcRead(){Task.Factory.StartNew(async () =>{var start_c = CommonMethods.PLCConfig.ReadStart_Coil;var start_h = CommonMethods.PLCConfig.ReadStart_Holding;bool[] temp_c = null; bool init_c = false;byte[] temp_h = null; bool init_h = false;while (!CommonMethods.CTS.IsCancellationRequested){try{DicWordChange.Clear();var array_c = (await client.ReadBoolAsync(start_c, (ushort)CommonMethods.PLCConfig.ReadCount_Coil)).Content;var array_h = (await client.ReadAsync(start_h, (ushort)(CommonMethods.PLCConfig.ReadCount_Holding * 2))).Content;// ushort占两个字节if (null != array_c){// bool类型只占1位,数据有变化直接通知if (null == temp_c){init_c = true;temp_c = new bool[array_c.Length];}CheckBoolChange("0", start_c, temp_c, array_c, init_c); init_c = false;Array.Copy(array_c, temp_c, array_c.Length);}if (null != array_h){// word类型数据位(2,4,8),所以要先读取全部的数据,再通知变化if (null == temp_h){init_h = true;temp_h = new byte[array_h.Length];}CheckWordChange("4", start_h, temp_h, array_h, init_h); init_h = false;Array.Copy(array_h, temp_h, array_h.Length);if (DicWordChange.Count > 0){foreach (var item in DicWordChange){DataChange(item.Key);}}}}catch (Exception ex){Logger.Info("[Error] PLCMgr,TskPlcRead,errmsg" + ex.Message);}await Task.Delay(100);}}, TaskCreationOptions.LongRunning);}/// <summary>/// 检查数据是否有变化(bool类型)/// </summary> public static void CheckBoolChange(string flg, string start, bool[] oldbuffer, bool[] newbuffer, bool init){for (int i = 0; i < newbuffer.Length; i++){// 00101string address = flg + FillAddress((i + Convert.ToInt32(start)).ToString(), 4); bool value = newbuffer[i];DicBoolData.AddOrUpdate1(address, value); if (init || oldbuffer[i] != value){ DataChange(address);}}}/// <summary>/// 检查数据是否有变化(word类型)/// </summary> public static void CheckWordChange(string flg, string start, byte[] oldbuffer, byte[] newbuffer, bool init){int index = 0;for (int i = 0; i < newbuffer.Length; i = i + 2){// 40101string address = flg + FillAddress((index + Convert.ToInt32(start)).ToString(), 4); index++; byte byte1 = newbuffer[i];byte byte2 = newbuffer[i + 1];Word buff = new Word() { Byte1 = byte1, Byte2 = byte2 };DicWordData.AddOrUpdate1(address, buff);if (init || (oldbuffer[i] != byte1 || oldbuffer[i + 1] != byte2)){DicWordChange.AddOrUpdate1(address, buff);}}}/// <summary>/// 添加写入值/// </summary> public static void AddWriteVariable(string address, object value, DataType datatype){queueWrite.Enqueue(new PLCModel() { Address = address, Value = value, PLCDataType = datatype });//加载值进队列} /// <summary>/// 定时写入/// </summary>static void TskPlcWrite(){ Task.Factory.StartNew(async () =>{while (!CommonMethods.CTS.IsCancellationRequested){try{if (!queueWrite.IsEmpty){PLCModel model = null; OperateResult result = null;queueWrite.TryDequeue(out model);var dataype = model.PLCDataType;switch (dataype){case DataType.Bool:result = await client.WriteAsync(FormatAddress(model.Address), Convert.ToBoolean(model.Value));break;case DataType.Short:result = await client.WriteAsync(FormatAddress(model.Address), Convert.ToUInt16(model.Value)); break;case DataType.Int:result = await client.WriteAsync(FormatAddress(model.Address), Convert.ToUInt32(model.Value));break;case DataType.Float:result = await client.WriteAsync(FormatAddress(model.Address), Convert.ToSingle(model.Value));break;case DataType.Long:result = await client.WriteAsync(FormatAddress(model.Address), Convert.ToUInt64(model.Value));break;case DataType.Double:result = await client.WriteAsync(FormatAddress(model.Address), Convert.ToDouble(model.Value));break;}if (!result.IsSuccess){Logger.Info("[Error] PLCMgr,TskPlcWrite,errmsg:写入失败," + result.Message);}}}catch (Exception ex){ Logger.Info("[Error] PLCMgr,TskPlcWrite,errmsg:" + ex.Message);} await Task.Delay(100);}}, TaskCreationOptions.LongRunning);}}
}

复制代码

4. 主界面控件都是静态加载,参数设置的控件是动态加载(点击进入,动态加载变量并监听;离开,移除不监听)

复制代码

using PLCBind.Util;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;namespace PLCBind.UIForm
{public partial class ucParameter : UserControl{public ucParameter(){InitializeComponent();} /// <summary>/// 参数集合/// </summary>public object ListParams{set{ RemoveParams();if (value is List<BaseParams> Parameters){AddParams(Parameters);}}}/// <summary>/// 移除参数/// </summary>public void RemoveParams(){foreach (Control item in this.tableLayoutPanel1.Controls){if (item is ucTextSetting ctrText){CommonMethods.RemoveControl(CommonMethods.DicSetControl, ctrText.Address);// 移除集合}}this.tableLayoutPanel1.Controls.Clear(); // 移除控件}/// <summary>/// 添加参数/// </summary> void AddParams(List<BaseParams> objParams){ var pamramCount = objParams.Count;var pamrammIndex = 0;for (int columnIndex = 0; columnIndex < tableLayoutPanel1.ColumnCount; columnIndex++){for (int rowIndex = 0; rowIndex < tableLayoutPanel1.RowCount; rowIndex++){if (pamramCount > pamrammIndex){var common = objParams[pamrammIndex];var address = common.PLCAddress;ucTextSetting ucLbText = new ucTextSetting();ucLbText.Anchor = ((((AnchorStyles.Top | AnchorStyles.Bottom) | AnchorStyles.Left)));ucLbText.ParamModel = common;ucLbText.Address = address;CommonMethods.AddControl(CommonMethods.DicSetControl, address, ucLbText);// 添加集合tableLayoutPanel1.Controls.Add(ucLbText, columnIndex, rowIndex);// 添加控件 pamrammIndex++;}}}}private void TableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e){if (e.Row % 2 == 1)e.Graphics.FillRectangle(Brushes.White, e.CellBounds);elsee.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(192, 224, 248)), e.CellBounds);}}
}

复制代码

注意事项:
1. 字典类型
Data字典:ConcurrentDictionary<string, bool> DicBoolData;ConcurrentDictionary<string, Word> DicWordData;Word:byte1,byte2
UI字典:ConcurrentDictionary<string, List<Control>> DicHomeControl;ConcurrentDictionary<string, List<Control>> DicSetControl
2. bool类型只占1位,数据有变化直接通知
3. word类型数据位(short:2,int/float:4,long/double:8),所以要先读取全部的数据,再通知变化
4. 自定义控件继承ITransferUI类(属性:ParamModel,方法:NoticeChange),赋值属性ParamModel,其中PLCValue get:通过不同的数据类型,获取字典中的word数据,并拼接合成相应的数据类型;set:传入地址(写入时格式化地址,如:40101->101)及类型

相关文章:

C#上位机序列10: 批量读写+点对点更新+数据类型处理

一、源码结构 二、运行效果 三、源码解析 PLC批量读写点对点更新数据类型处理 优点&#xff1a;根据数据类型&#xff0c;判定监听的地址范围&#xff08;40120_int 监听两个word&#xff1a;40120 40121&#xff1b;40130_long 监听四个word&#xff1a;40130 40131 40132 4…...

MySQL 概述 数据库表操作 数据增删改

目录 MySQL概述前言安装与配置MySQL登录与卸载 数据模型概述SQL简介SQL通用语法简介SQL分类 数据库设计(数据库操作)-DDL数据库操作查询数据库 show databases、select database()创建数据库 create database使用数据库 use删除数据库 drop database 图形化工具连接数据库操作数…...

存储器概述

一、存储系统基本概念...

Fabric.js 使用自定义字体

本文简介 点赞 关注 收藏 学会了 如果你使用 Fabric.js 做编辑类的产品&#xff0c;有可能需要给用户配置字体。 这次就讲讲在 Fabric.js 中创建文本时怎么使用自定义字体、在项目运行时怎么修改字体、以及推荐一个精简字体库的工具。 学习本文前&#xff0c;你必须有一点…...

【C++项目】高并发内存池第七讲性能分析

目录 1.测试代码2.代码介绍3.运行结结果 1.测试代码 #include"ConcurrentAlloc.h" #include"ObjectPool.h" #include"Common.h" void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds) {std::vector<std::thread> vthread(…...

【JavaScript】快速学习JS

JS区分大小写&#xff0c;后面的分号可有可无&#xff1b; 输出语句 window.alter() // 写入警告框&#xff1b;在浏览器中的警告弹窗输出 document.write() // 写入html输出&#xff1b;在html页面中输出 console.log() // 写入浏览器控制台&#xff1b;在控制台输出 变量…...

控制输入流,从控制台打印到文件中,更改输出的位置

public static void main(String[] args) throws IOException {PrintStream printStream System.out;//在默认情况下&#xff0c;PrintStream 输出数据的位置 标准输出&#xff0c;即显示器printStream.print("Tom,hello");/*public void print(String s) {if (s n…...

计算线阵相机 到 拍摄产品之间 摆放距离?(隐含条件:保证图像不变形)

一物体被放置在传送带上&#xff0c;转轴的直径为100mm。已知线阵相机4K7u&#xff08;一行共4096个像素单元&#xff0c;像素单元大小7um&#xff09;&#xff0c;镜头35mm&#xff0c;编码器2000脉冲/圈。保证图像不变形的条件下&#xff0c;计算相机到产品之间 摆放距离&…...

【网络】详解http协议

目录 一、认识URLurlencode和urldecode 二、HTTP协议HTTP协议格式HTTP的方法HTTP的状态码HTTP常见Header 一、认识URL URL叫做统一资源定位符&#xff0c;也就是我们平时俗称的网址&#xff0c;是因特网的万维网服务程序上用于指定信息位置的表示方法。 urlencode和urldecode …...

1819_ChibiOS的互斥信号与条件变量

全部学习汇总&#xff1a; GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 1. 关于会吃信号与条件变量的全局配置提供了4个配置信息&#xff0c;分别是互斥信号的使能、互斥信号的递归支持、条件变量的使能、条件变量的超时使…...

CSDN学院 < 华为战略方法论进阶课 > 正式上线!

目录 你将收获 适用人群 课程内容 内容目录 CSDN学院 作者简介 你将收获 提升职场技能提升战略规划的能力实现多元化发展综合能力进阶 适用人群 主要适合公司中高层、创业者、产品经理、咨询顾问&#xff0c;以及致力于改变现状的学员。 课程内容 本期课程主要介绍华为…...

电商接口api数据比价接口推荐

当前&#xff0c;受诸多因素的影响&#xff0c;经济下行&#xff0c;在日趋激烈的市场竞争中&#xff0c;很多企业也都面临着越来越大的生存压力&#xff0c;企业的盈利空间也逐渐被压缩。因此&#xff0c;越来越多的企业在控制成本方面更下功夫&#xff0c;这也就对企业采购提…...

读取Excel的工具类——ExcelKit

文章目录 ExcelKit工具类1、准备工作1.1、SheetInfoVo1.2、BizException 2、读取xlsx3、读取xls4、完整的ExcelKit.java源码 ExcelKit工具类 1、准备工作 1.1、SheetInfoVo import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import …...

vscode连接服务器一直retry

解决方法 打开vscode控制面板&#xff0c;输入命令remote-ssh: kill vs code server on host 选择一直连接不上的服务器端口 重新连接...

Spring Cloud Sentinel整合Nacos实现配置持久化

sentinel配置相关配置后无法持久化&#xff0c;服务重启之后就没了&#xff0c;所以整合nacos&#xff0c;在nacos服务持久化&#xff0c;sentinel实时与nacos通信获取相关配置。 使用上一章节Feign消费者服务实现整合。 版本信息&#xff1a; nacos:1.4.1 Sentinel 控制台 …...

STM32F4VGT6-DISCOVERY:uart1驱动

对于这款板子&#xff0c;官方并没有提供串口例程&#xff0c;只能自行添加。 一、PA9/PA10复用成串口1功能不可用 驱动测试代码如下&#xff1a; main.c: #include "main.h" #include <stdio.h>void usart1_init(void) {GPIO_InitTypeDef GPIO_InitStruct…...

C语言之 结构体,枚举,联合

目录 1.结构体 1.1结构的基础知识 1.2结构的声明 1.3 特殊的声明 1.4 结构的自引用 1.5 结构体变量的定义和初始化 1.6 结构体内存对齐 1.7 修改默认对齐数 1.8 结构体传参 2. 位段 2.1 什么是位段 2.2位段的内存分配 2.3 位段的跨平台问题 3. 枚举 3.1 枚举类型…...

红米电脑硬盘剪切

Redmi R14 2023版固态硬盘剪切 工具准备操作结尾语 首先要说明&#xff0c;本文所说的操作不一定适合你的电脑&#xff0c;因为电子产品更新换代过快&#xff0c;你的硬盘不一定能剪切&#xff0c;在操作前一定要仔细观察硬盘的型号&#xff0c;是否为同款&#xff0c;我上了图…...

微信小程序在线预览PDF文件

需求&#xff1a;微信小程序在线预览PDF合同文件&#xff0c;加载完成后强制阅读10秒才可点击同意按钮 H5代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" cont…...

Android 工厂模式增加Type-A功能测试

Android 工厂模式增加Type-A功能测试 收到客户需求想要增加Type-A测试项来验证Type-A功能&#xff0c;具体功能实现参照如下&#xff1a; /vendor/freeme/packages/apps/FreemeFactoryTest/src/com/freeme/factory/usb/TypeAUSB.java package com.freeme.factory.usb;i…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...