const array = [ { type: 11111, }, { type: 11111, }, { type: 11111, }, ]; 如上数据进行去重,用以下方法
form = [...new Set(array.map(item => item.type))].map(id => ({ type: id })); form得到的数据就是去重之后的数据
2023.11.12 周六 19:05
补充一下关于以太网查找设备,如果设置如下: 然后点击测试: 点击ping
如果设置如下: 测试和ping和上图一样。
这就设计的有点不大好了!
另外关于今天的ping,如果是电脑重启后首次ping,那么前两帧是ping不通的。
另外电脑重启后,首次点击弹出的框又明显的晃了一下。
USB试一试=== 按照文档
USB不支持的地方显示了暗黑色: 也可以实现:
我原先还以为是USB转232呢!因为点击帮助->帮助手册 文档写的:
可能大概也许H5U是用USB虚拟的串口。
编程实例: 根据照葫芦画瓢,
文档给出的例子是梯形图的例子:
为什么不给安装的时候不直接提供demo最好ST和梯形图分别给个demo。文档仅仅给个梯形图的例子,对我来说一时半会不大容易看懂啊。
啊 怎么出来这样的
双击M8弹出选择然后确定,
哦M8002大概是个指令,看看指令手册:找到了
所以说刚开始应该这么输入:
后面的指令输入也不大容易搞。所以还是想办法找个ST的例子。
找到
还得微信扫一扫,最后找到这些仅有几十秒的课程,很大一部分属于宣传片了:
不过也算有收获,原来不用写任何程序,也是可以程序下载的。
那么就试试固件烧录和升级吧。相关介绍在《编程与应用手册》的附录里。烧录需要断开,并且需要。估计是把PLC当成一个U盘了。
固件烧录感觉有点冒险,先不搞了!
固件升级写的是
有点吓人,就是说搞不好,可能成为板砖。
找了一下官网,也没发现升级包,这个版本是8月的。现在是11月,估计没有升级包。安装路径下也没发现。所以固件升级也不打算搞了!
-----------------------------------------------------
Boost型Ladrc控制双闭环电路
双闭环控制
(1)电压外环采用简化Ladrc控制器,简化线性自抗扰控制,采用PD控制+三阶LESO状态观测器,
(2)电流内环采用pi控制
其中ladrc控制器可以用于其他模型如电机控制、光伏发电、风力发电中替换pi控制器,相当于创新
有参考资料
Boost型Ladrc控制双闭环电路
随着电气化的深度发展,各种电子设备的应用越来越广泛。而这些电子设备的电路控制是很关键的一环。在实际应用中,如果电压和电流控制不好,就会对设备的正常使用和寿命产生不利影响。因此,如何控制电压和电流,成为了电子电路设计的重点。本文重点介绍了Boost型Ladrc控制双闭环电路的实现方法和优势。
一、Ladrc控制器的原理
Ladrc控制器是一种基于线性自抗扰控制的控制器,它可以有效地控制电气设备的电压和电流。Ladrc控制器主要由状态观测器、CC(中间电容)电压计算器、误差计算器、控制器和补偿器等组成。通过对这些元件的控制,就能够实现对电气设备的控制。
二、Boost型Ladrc控制器的实现方法
电压外环控制 电压外环采用简化Ladrc控制器,其中PD控制器的作用是提高系统的稳定性,而三阶LESO状态观测器,则是根据估计的CC电容电压调整输出电流,从而实现对电气设备的控制。
电流内环控制 电流内环控制采用pi控制,通过对输出电流进行二次采样,计算误差并进行反馈控制。
在Boost型Ladrc控制器的实现中,电压外环和电流内环的协同控制起到了关键的作用。电压外环控制可以实现对电气设备电压的调节,从而保证电气设备的工作稳定性;而电流内环控制可以实现对电气设备输出电流的控制,从而保证电气设备的输出质量。这种双闭环控制的方法,能够有效地提高电气设备的控制精度和稳定性。
三、Ladrc控制器的应用
Boost型Ladrc控制器不仅仅可以用于电气设备的电压和电流控制,还可以用于其他模型的控制,例如电机控制、光伏发电和风力发电等。在实际应用中,Ladrc控制器的优势主要体现在以下几个方面:
稳定性高:Ladrc控制器可以有效地降低电气设备的振荡,从而提高电气设备的稳定性。
控制精度高:Ladrc控制器采用状态观测器和误差计算器等元件,能够实现对电气设备的精细控制。
适用范围广:Ladrc控制器不仅仅适用于电气设备的控制,还可以适用于其它模型的控制,例如电机控制、光伏发电和风力发电等。
总之,Boost型Ladrc控制双闭环电路在电气设备的控制中有着广泛的应用,其应用优势主要体现在稳定性高、控制精度高和适用范围广等方面。在实际应用中,需要根据具体情况进行选择和应用。
相关代码,程序地址:http://lanzouw.top/660684564532.html
一、AI工程师未来前景如何? AI工程师的未来前景非常广阔。
随着人工智能技术的不断发展和应用,AI工程师的需求将会持续增加,越来越多的企业开始注重AI技术的引入和研发,因此AI工程师的就业机会大大增加。你可以在互联网公司、金融机构、科技企业、研究机构等多个领域找到AI工程师的就业岗位。
市场需求增长:随着人工智能技术在各个行业的广泛应用,AI工程师的市场需求将会不断增长。无论是互联网公司、金融机构、医疗机构还是制造业企业,都需要AI工程师来帮助他们实现智能化升级。
技术创新驱动:人工智能技术正处于快速发展阶段,不断涌现出新的算法、模型和应用场景。AI工程师作为技术创新的驱动力,将会在这个过程中发挥核心作用。
跨界融合机会:人工智能技术与各行各业的融合将为AI工程师提供丰富的跨界融合机会。例如,AI与医疗、金融、教育、交通等领域的融合,将创造出众多新的就业岗位和商业模式。
薪资水平提高:由于AI工程师的市场需求大,且技术含量高,所以AI工程师的薪资水平普遍较高,并且有望在未来继续提高。
发展空间广阔:随着人工智能技术的不断发展,AI工程师的职业发展空间也将更加广阔。他们可以通过不断学习和实践,提升自己的技能水平,从而在职业生涯中取得更高的成就。
二、Java工程师转AI开发工程师的优势 通俗地说,Java软件工程师转型为AI开发工程师时,他们已经具备了很多重要的技能和经验。
不仅懂得如何编写代码,还知道如何组织和管理大型项目。因此,他们可以快速适应AI开发的工作,并发挥出自己的特长,为AI项目做出更大的贡献。
编程基础扎实:Java软件工程师通常具有扎实的编程基础,包括数据结构、算法和面向对象编程等。这些基础知识在AI开发中同样非常重要。
熟悉软件开发流程:Java软件工程师往往熟悉软件开发的全流程,包括需求分析、设计、编码、测试和部署等。这种经验可以帮助他们在AI开发项目中更好地协作和交付。
了解计算机底层知识:相比于一些其他编程语言,Java更接近于底层,所以Java工程师往往对计算机底层知识有更深入的了解,这有助于他们更好地理解和优化AI算法。
强大的学习能力和适应性:Java软件工程师通常具有强大的学习能力和适应性,他们能够快速学习新的编程语言和工具,这有助于他们快速上手AI开发。
丰富的实际应用经验:Java是一种非常流行的编程语言,广泛应用于各个行业。这使得Java软件工程师在解决实际问题时,可以借鉴以往的经验,更高效地完成AI开发任务。
三、需要加强学习的地方 Java软件工程师转型为AI开发工程师时,需要继续学习的内容主要包括以下几个方面:
机器学习和深度学习知识:这是AI开发的核心内容,需要深入理解机器学习和深度学习的原理、算法和应用。包括监督学习、无监督学习、神经网络等基本概念和原理。
Python编程语言:Python是AI领域最常用的编程语言之一。作为Java工程师,你可能已经掌握了Java,但为了更好地进行AI开发,学习Python编程语言会很有帮助。
数据处理和分析技能:AI开发中,数据处理和分析是非常重要的一环。需要学习如何处理和清洗数据,以及如何从数据中提取有用的特征。
深度学习框架:如TensorFlow、PyTorch等。这些框架是构建深度学习模型的基础工具,需要熟悉并掌握其使用方法。
实践项目和比赛:通过参与实践项目和比赛,可以更好地应用所学知识,提升自己的实战能力,同时也有助于积累经验、提升求职竞争力。
请注意,上述学习内容仅供参考,具体的学习内容可能会根据个人的具体情况和转型后的工作需求有所调整。
一个点图层想按一个数值为百分比的字段出个图,结果到properties - symbology - quantities里面发现找不到这个字段。
原因:这个字段是在外面excel里算好,然后通过表连接过来的,在excel里就是百分数的形式,进gis以后字段类型变成字符串了,所以想按数值出图时候找不到这个字段。
解决方法:
方法1、嫌字段计算器麻烦的话,直接在excel里把百分比形式变成正常的数值形式,再连接进gis,这样应该能识别为数值类型。
方法2、把字符串类型转成数值类型,要用到字段计算器。
先把表连接后的图层重新导出一个shp,如果不重新导的话后面做字段计算器的时候可能会出问题。
新建一列,字段类型按实际需求选成一种数值类型,我这里选float。
新建的这列用字段计算器,语言选python,字符串里的表达式就输入eval(原字符串字段)就好了。我这里避免麻烦想直接把百分号去掉,于是写成eval(原字符串字段.rstrip('%')),然后计算。
新的列就是数值类型了,用这个新字段就可以正常出图。
TMS320F28034学习笔记(一) TMS320F28034工程模板建立及LED测试程序编写 文章目录 TMS320F28034学习笔记(一)TMS320F28034工程模板建立及LED测试程序编写 前言一、TMS320F28034是什么?二、所做准备工作1、所需软硬件(1)Code Composer Studio 7.2.0(2)TMS320F28034核心板或开发板 2、所需配置文件(1)TI官方提供的配置文件 三、操作流程1、打开CCS进行工程建立(1)工程建立(路径应当不包含中文)①路径选择②新建工程③工程配置 (2)工程模板配置①文件夹建立②文件导入③工程选项配置④最后需要更改下下载.cmd文件⑤在main.c文件写入程序 (3)编写LED测试程序①文件夹建立②工程中.c、.h文件建立③LED.c、LED.h程序编写LED.c文件代码LED.h文件代码main.c文件代码 四、实验现象五、问题1、还不太明白main.c文件中RAM部分代码是不是为了在外接RAM后可以断电保存程序使用,在使用F28335时因为有RAM可以使用,我焊的这块板子没有RAM,是不是不需要这部分代码断电也可以保存程序。2、刚烧入程序LED灯闪烁频率和断电以后再上电闪烁频率不一致,不知道是什么原因导致。 总结 前言 在对学习F28034过程中发现网上很少有对其工程模板配置以及使用F28034驱动其他模块的教程。并且考虑创建一个F28034通用的CCS工程模板,以简化新项目的创建过程。通过制作一个模板,可以节省时间和减少繁琐的工程搭建步骤。在需要新项目时,只需复制模板并进行相应配置即可快速启动开发工作。所以笔者在这对F28034工程模板的配置进行记录并且使用F28034点亮LED进行程序测试。
(本文仅供学习交流,如有错误或有更好的解决方案,欢迎相互交流讨论。)
一、TMS320F28034是什么? TMS320F28034指的是德州仪器(Texas Instruments)推出的一款数字信号处理器(Digital Signal Processor,DSP)型号(后称F28034)。它属于TI的C2000系列,是专门设计用于实时控制应用的DSP芯片。
F28034具有高性能、低功耗、丰富的外设接口等特点,适用于各种需要高精度实时控制的场合,比如电机控制、逆变器、电源管理等应用领域。它采用了先进的处理器内核和数字信号处理器技术,具备强大的计算能力和灵活的控制功能。
这款DSP通常会配合TI提供的开发工具和软件库来进行程序开发和调试,以满足各种实时控制系统的需求。
二、所做准备工作 1、所需软硬件 (1)Code Composer Studio 7.2.0 (2)TMS320F28034核心板或开发板 2、所需配置文件 (1)TI官方提供的配置文件 三、操作流程 1、打开CCS进行工程建立 (1)工程建立(路径应当不包含中文) ①路径选择 路径选择好了以后点击OK。
②新建工程 点击File→New→CCS Project或者键盘按下快捷键Shift+Alt+N→CCS Project效果一样
③工程配置 按照如图①-⑤顺序进行选择,其中①②③型号尽量选对,这里开发板我以TMS320F28034芯片,仿真器以Texas Instruments XDS100v2 USB Debug Probe型号为例。
⑤可以选择带有main.c的那个选项(Empty Project(with main.c))
然后点击Finish。(这里我已经建立过工程,所以Finish无法点击)
(2)工程模板配置 ①文件夹建立 在前文创建的工程文件夹F28034_Learn下建立一个文件夹F28034_Lib(也可以是其他英文字符组成的名字)
在F28034_Lib文件夹下创建文件夹cmd、include、source(也可以是其他英文字符组成的名字)。其中,include放.h文件、source放.c文件。
在工程中可以看到已经有该文件夹。
②文件导入 将提供的DSP2803x_headers文件夹下的cmd文件夹中的DSP2803x_Headers_nonBIOS.cmd文件放入我们创建的cmd文件夹中。
打开DSP2803x_headers、DSP2803x_common文件夹中的include文件夹,选中所有的.h文件导入我们创建的include文件夹中,总共31个.h文件。
同样,选中DSP2803x_headers、DSP2803x_common文件夹中的source文件夹将,其中所有的.c文件导入我们创建的source文件夹中,总共25个.c文件。
③工程选项配置 鼠标右击工程F28034_Learn→Properties
按照图片中在最左侧选中Include Options→…→选中include(导入放.h文件的文件夹路径)按照图片步骤进行最后点击OK
④最后需要更改下下载.cmd文件 和③一样鼠标右击工程F28034_Learn→Properties
选中General→在Linker command file选中DSP型号,我这里需要下到Flash中所以选中F28034.
需求:生成从地铁站步行10分钟可达的范围面图层。
线图层预处理 在精度要求不是很高的情况下,可采用OSM路网,从中剔除不允许步行的道路类型:高速公路、快速路。
在路网图层中新增一个字段“步行时间”,用字段计算器,时间=距离/速度,算出这个数值。
生成网络数据集 在Arcmap中,customize - extensions,勾选network analyst,然后关闭这个对话框。这步是激活网络分析这个功能。
点catalog那个图标,从中选择路网图层(线图层),右键,new network dataset,输入网络数据集的名称,然后点击下一页。
这里有个小问题,如果对话框底部的下一页按钮被底下任务栏挡住显示不出来,就在电脑的设置里,系统-屏幕-缩放与布局,把大小设成100%,就能正常显示了。
然后应该是Do you want to model turns...就选yes,然后下一页。
点connectivity,选any vertex(我感觉应该是选这个,想了解具体内容可以查看官方文档,下同)
然后应该是Using Z... 选择None,然后下一页。
这里到了很关键的一步,要设置cost和restriction。如果你有单向交通的要求就在这里设置,我这里考虑到是步行就无所谓。但我的需求是10分钟可达性,也就是说cost是时间,所以我这里add new attribute,名称就起成time,类型是cost,单位是minutes。
双击新加的time那行,出来的框里有两行内容,一个from-to,一个to-from,这俩在type里都选field,value里选之前自己算好的时间字段。其实也可以这里用字段表达式:时间=距离/速度,但放在前面算好应该更方便。设置好了的话time这行前面的小感叹号应该会消失。
默认列出来的原来两个length和oneway我这里用不上就先删掉了。
下一页travel mode,我之前还自己设了一下,不过感觉设不设置都行,应该可以直接下一页。
下一页设置方向,你有设置方向的需求就去官方文档好好看下咋设,我这里就选no了。
下一页是summary,可以看一下之前设置的内容都对不对,然后finish。
然后弹出来对话框yes就好,就是确认建立网络数据集、把网络数据集加入图层。
服务区分析 customize - toolbars - network analyst,出现网络分析的工具框,点network analyst - new service area,会发现左侧table of contents栏里多出了一堆东西,这就对了。
点框里network analyst右边的小图标(一个窗口前面一个小旗子),也就是network analyst window,左侧又出现一栏,最上面有个facilities(0),右键,load locations,load from里面选你要做可达性分析的那个点图层,我这里就选择地铁站图层。然后ok。发现facilities(0)里面的0变成了点图层里面的要素个数。
最左侧service area一栏,右上有个方形的小图标,点一下,出现layer properties对话框。点analysis settings。
impedance(阻抗)就选择刚才设置好的time(minutes),default breaks我想做10分钟的等时线,就写10,你也可以同时做多个时间(比如5、10、15)的等时线。
对话框里的其他设置可以自己看一眼,应该不用改。确定。
layer properties里面的polygon generation里还有关于生成的面图层的形式设置,可以自己看看。
然后在network analyst里面点左数第4个小图标(solve),等时线就生成了,是个面图层。
说明 由于环境限制,需要同时连接PG、opengauss、gaussdb,使用psycogp2连接由于使用的libpq的版本不同导致无法使用。所以就通过pyodbc来解决。
配置ODBC 下载、上传驱动 下载gaussdb官方的odbc驱动,地址:
https://dbs-download.obs.cn-north-1.myhuaweicloud.com/GaussDB/1660794000209/GaussDB_opengauss_client_tools.zip
找到对应版本的odbc驱动
将odbc里面的四个文件和python压缩包里的lib文件夹内的so文件一同复制到一个单独文件夹内
如下:
[root@test80 psycopg2-2.9.1]# ll /usr/local/lib/ total 10052 -rw-r--r-- 1 root root 18904 Jun 9 09:31 libcom_err_gauss.so.3 -rw-r--r-- 1 root root 3210056 Jun 9 09:31 libcrypto.so.1.1 -rw-r--r-- 1 root root 107032 Jun 9 09:31 libgcc_s.so.1 -rw-r--r-- 1 root root 478216 Jun 9 09:31 libgssapi_krb5_gauss.so.2 -rw-r--r-- 1 root root 161368 Jun 9 09:31 libgssrpc_gauss.so.4 -rw-r--r-- 1 root root 304856 Jun 9 09:31 libk5crypto_gauss.so.3 -rw-r--r-- 1 root root 1225928 Jun 9 09:31 libkrb5_gauss.
ClickHouse数据导入和导出 ClickHouse是一个高性能、列式存储的分布式数据库,广泛应用于实时数据分析、大数据处理等场景。本文将详细介绍如何在ClickHouse中导入和导出数据,包括使用命令行工具、HTTP接口和第三方工具(如Kafka、Hadoop等)。
1. 使用命令行工具导入和导出数据 ClickHouse提供了一个名为clickhouse-client的命令行工具,可以方便地导入和导出数据。
1.1 导入数据 要使用clickhouse-client导入数据,您可以使用以下命令:
clickhouse-client --query="INSERT INTO table_name FORMAT CSV" < input.csv 这个命令将input.csv文件中的数据导入到table_name表中。您可以根据需要更改数据格式,如TSV、JSONEachRow等。
1.2 创建表 在导入数据之前,您需要先创建一个表。以下是一个创建表的示例:
CREATE TABLE test_table ( id UInt32, name String, age UInt8 ) ENGINE = MergeTree() ORDER BY id; 您可以使用clickhouse-client命令行工具执行此SQL语句:
clickhouse-client --query="CREATE TABLE test_table (id UInt32, name String, age UInt8) ENGINE = MergeTree() ORDER BY id;" 1.3 准备数据文件 准备一个包含数据的CSV文件,例如input.csv:
1,John Doe,30 2,Jane Doe,28 3,Jim Smith,35 1.4 导入数据 使用以下命令将input.csv文件中的数据导入到test_table表中:
clickhouse-client --query="INSERT INTO test_table FORMAT CSV"
1.钟差的基本概念:接收机时间,存在误差,比如,我认为我接受到信号的时间是a时,时间我后面pvt算出来我接受到信号的真实时刻其实是b,即算出来钟爱是(a-b),要注意的是我应该让接收机时间尽可能的准,应用时一般控制钟差在±0.5ms内。
2.钟差的组成:
考虑情况一:假设现在时间是2023年,射频电缆很长,长1光年,我接收机时间,加上钟差后,算出来的时间,是2022年,这2022年就是我天线接受到信号的时间。没有问题。这里的钟差,就很简单,可以认为是,我设置的接收机时间与实际真实的时间差,设置的接收机时间是由发射时间大致得来的,显然发射时间是2022年左右,那么钟差是一个很小值,不包含1光年。
情况二,仍然假设现在是2023年,某些原因,信号进入天线前,所有卫星的伪距都变化了1光年,比如说光速因为穿越介质变了,信号实际上是2022年从卫星上发射的,。这里,我们是不知道所有卫星伪距都变化了1光年的,那么此时,pvt解算的所有输入与情况1完全一样,解算出来的时间,也是2022年,而现在,天线接受到信号的时间是2023年(假设射频电缆等天线后端的长度为0),那么也就是说,接收机时间错了。这种情况,接收机时间是发射时间2022年,钟差小值,不包含1光年。
情况三,假设现在是2022年,某些原因,gps信号在我们接收机滤波器里群延时1光年,即gps卫星的伪距较gal卫星\bds卫星的伪距多了1光年,gps的接收机时间与gal的接收机时间我们设置的时间是一样的,都是发射时刻附近,发射时刻即是当前真实时间2022年附近,那么此时gps钟差与gal钟差就有一个1光年的时间差,gal钟差是小值,不包含1光年,gps钟差为1光年,接收机时间补钟差后,gal的时间是2022年,gps的时间是2023年。此时,我们不知道是gps的伪距上我们加了一光年的偏差,我们怎样去判断该信谁呢?现在到底是2022年还是2023年呢?结论是,信gps,那么我们就错了,符合先验条件,信gal,我们就对了,符合先验条件。一般情况伪距只会多不会少,所以一般就会去信gal。
情况四,还是gps卫星多了1光年的偏差,不过这1光年的偏差是在传播过程中,即接收天线之前引入的,那么算出来的gps钟差,gal钟差与情况3是一样的。结论也是一样的。
综上,如果我们认为接收机时间减去钟差后的时间是天线接受到信号的时间的话,那么接收天线前不能有公共误差。另外,接收机钟差中不会有电缆长度,但会有群延时。
下一个问题,Pps时间,上述4种情况,对pps的影响是怎样的呢。
pps时间,要求1hz的上升沿完全对准整秒时间,这个整秒时刻是大家规定好的一种时间,比如gps时间。用来保证大家的上升沿是同时的。
不管怎样,不管我们认为的结果里有没有误差,正确与否,我们都会得到一个接收机天线接受到信号的时间。我们只有这一个时间信息,没有办法,只能信他。有了这个时间,那我pps脉冲的发射时间是多少呢?需要天线接受到信号的时间加上一个时间差。这个时间差,我们可以认为是射频电缆延时,加上其他等等。如果是情况2,进入天线前有个误差,导致的是接收机时间错了,那没办法,pps时间一定不对。如果是情况1,接收机内部有个延时,这个延时,我们可以提前统计出来的话,例如分成电缆长度多长,射频延迟多长,群延迟多长,等等,(这里面没有pvt计算延时这一说,pvt计算的是接收机时间,你放一年后计算算出来的接收机时间也是一样的)提前知道的话,就可以在接收机时间加上这个固定的时间差得到pps时间了。
pps时间,其实就是要得到现在的时间,我们也只能是通过天线接受到信号的时间来估计现在的时间,因为我只有天线接受到信号的时间这一个时间信息。如情况一,如果能提前统计出来这个延时为1光年,那pps时间就尽最大可能准了。
ClickHouse聚合和窗口函数 ClickHouse是一个高性能、列式存储的分布式数据库,广泛应用于实时数据分析、大数据处理等场景。在ClickHouse中,聚合函数和窗口函数是两类非常重要的函数,它们可以帮助我们对数据进行汇总、统计和分析。本文将详细介绍ClickHouse中的聚合函数(如count、sum、avg等)和窗口函数(如row_number、rank、dense_rank等)以及其他高级功能进行高级数据分析。
1. 聚合函数 聚合函数用于对一组值进行汇总和计算,返回一个单一的结果。以下是ClickHouse中常用的聚合函数:
1.1 COUNT COUNT函数用于计算表中的记录数或满足特定条件的记录数。
语法:
COUNT([DISTINCT] expression) 示例:
-- 计算表中的记录数 SELECT COUNT(*) FROM table_name; -- 计算满足特定条件的记录数 SELECT COUNT(*) FROM table_name WHERE condition; -- 计算不同值的数量 SELECT COUNT(DISTINCT column_name) FROM table_name; 1.2 SUM SUM函数用于计算表中某列值的总和。
语法:
SUM(expression) 示例:
-- 计算某列值的总和 SELECT SUM(column_name) FROM table_name; -- 计算满足特定条件的某列值的总和 SELECT SUM(column_name) FROM table_name WHERE condition; 1.3 AVG AVG函数用于计算表中某列值的平均值。
语法:
AVG(expression) 示例:
-- 计算某列值的平均值 SELECT AVG(column_name) FROM table_name; -- 计算满足特定条件的某列值的平均值 SELECT AVG(column_name) FROM table_name WHERE condition; 1.
Java 8中的stream在项目开发中被同学们用的风生水起,当然大家也踩了不少坑。下面我就来说说Collections.toMap在项目使用中踩的坑,避免大家重复被坑。
一.介绍Collectors.toMap Collectors.toMap 是 Java 8 中的一个收集器,它可以将流中的元素转换为 Map 对象,其中每个元素的 key 由指定的函数生成。
当我们使用 Collectors.toMap 方法时,可能会遇到重复的 key 问题,这是因为我们在将元素转化为 Map 对象时,如果两个元素具有相同的 key,则会发生冲突,抛出异常。
还可能会遇到value为null的问题,这是因为我们在将元素转化为 Map 对象时,toMap最终是调用了Map.merge方法,merge方法不允许value为null 导致的异常抛出。
二.问题复现与分析以及解决方案 1、Collectors.toMap的key重复问题 问题复现: public static void main(String[] args) { List<BenefitModel> benefitModelList = new ArrayList<>(); benefitModelList.add(new BenefitModel("123", "积分权益")); benefitModelList.add(new BenefitModel("123", "现金权益")); Map<String, String> benefitMap = benefitModelList.stream().collect(Collectors.toMap(BenefitModel::getBenefitId, BenefitModel::getBenefitName)); System.out.println(JSON.toJSONString(benefitMap)); } 运行结果: 原因分析: 查看Collectors.toMap源码如下,
toMap最终是调用了Map.merge方法,传入的mergeFunction是throwingMerger直接抛出异常,日志信息使用的是第一个参数u。传入的mapSupplier是HashMap对象(HashMap::new)。所以最终会调用到HashMap.merge。
而在HashMap.merge中,对于mergeFunction的应用如下:
在HashMap.merge的语义中,mergeFunction用于合并value,比如对于key的计数,可以使用map.merge(key, 1, Integer::sum)。若不存在则置1,存在则+1。这里的入参是oldValue和newValue。
所以最终传递给throwingMerger的两个参数就不是k-v了。所以报错的所谓Duplicate key其实是oldValue。
解决方案: 保证toMap的key不重复调用重载方法,主动指定当key重复时,需要做的合并操作(合并规则可以根据业务需要,自定义) 于是上面重复key的代码优化后为:(合并规则:重复key出现时,取后面的,前面的丢弃)
public static void main(String[] args) { List<BenefitModel> benefitModelList = new ArrayList<>(); benefitModelList.
主要功能: 快速查看安卓设备信息 (手机屏幕分辨率,手机型号,设备id, 可用内存等等)各类开发过程中常用代码及效果 Demo, 分别有列表, 容器,对话框,动画,翻页,图表,编码及算法,多媒体,传感器,实用工具等 官方网站 http://www.yinghuofei.com/
应用宝下载链接 https://a.app.qq.com/o/simple.jsp?pkgname=com.lujianfei.phoneinfo
小程序版本 在微信小程序搜索码农宝,里面介绍了小程序的应用 demo
界面展示 首页 默认展示手机系统的相关信息,点击某一个 Item , 可以查看相关实现源码
这里是点击 “屏幕分辨率” 显示的源码介绍, 右上角展开还可以 [复制/转发] 代码,是不是很贴心(为码农操碎了心, 有木有)
功能大类一览 里面很多在安卓开发的过程中常用的 demo,可以在体验的过程中查看代码,实际项目中或许会用到哦
所有功能目录一览 列表类 垂直 RecyclerView
多列 RecyclerView
瀑布流 RecyclerView
聊天界面列表
索引列表
吸附标题列表
左滑删除列表
下拉刷新列表
自定义下拉列表
Vlayout用法展示
RecyclerView滚动修改透明度
对话框类 自定义Dialog 按钮和容器类 流式布局
可缩放 ImageView
显示 html 图片的 TextView
WebView js 和 Android 相互调用
图片倒影效果
图像合成处理
验证码输入框
带清空输入框
RadioGroup实现下划线单选
验证码倒计时TextView
圆盘按钮菜单
遮罩滤镜展示
Modbus TCP是走网口的,也可以在同一时间内有多个从站访问主站,并且通过Modbus事务处理标识来区分同一时刻的不同Modbus事务,这是区别于Modbus ASCII和Modbus RTU的地方。
1、访问模式: Modbus客户端通常输入Modbus服务器的IP地址和端口号来建立TCP连接,然后根据从站地址来确定具体访问哪个从站设备。
2、地址分配规则 Modbus从站地址有255种,但是0用于广播地址,1到247用于从站地址,其余地址保留。
3、Modbus TCP格式 3.1 MBAP报文头含义 MBAP报文头是加载Modbus帧开始的报文,总共包含7个字节,分别如下:
1)事务处理标志符
这两个字节用于区分在同一时刻发送的多个Mobus请求,所以可以采用自增的方式,每次发送一个Modbus请求都将该值加1,然后一直到最大值,然后再次将该值变为1,循环往复即可。
2)协议标志符
这两个字节值就是0,0代表的就是Modbus协议
3)长度
这两个字节代表的是单元标志符(从站地址)以及后面的所有数据所占的字节总数
4)单元标志符
也就是从站地址
3.4 功能码 功能码的作用就是指定主站访问从站的具体目的,是读取数据还是写入数据或者其它,功能码分为三种,公共功能码、用于定义功能码、保留功能码,我们在上位机开发过程中遇到的一般都是公共功能码,公共功能码的值的范围如下图:
关于每个功能码在Modbus TCP中的应用,详细内容如下:
1、C# Modbus通信从入门到精通(22)——Modbus TCP(0x01功能码)
2、C# Modbus通信从入门到精通(23)——Modbus TCP(0x02功能码)
3、C# Modbus通信从入门到精通(24)——Modbus TCP(0x03功能码)
4、C# Modbus通信从入门到精通(25)——Modbus TCP(0x04功能码)
5、C# Modbus通信从入门到精通(26)——Modbus TCP(0x05功能码)
6、C# Modbus通信从入门到精通(27)——Modbus TCP(0x06功能码)
7、C# Modbus通信从入门到精通(28)——Modbus TCP(0x0F功能码)
8、C# Modbus通信从入门到精通(29)——Modbus TCP(0x10功能码)
3.5 数据 数据会根据不同的功能码而发生变化,详细内容如下:
1、C# Modbus通信从入门到精通(22)——Modbus TCP(0x01功能码)
2、C# Modbus通信从入门到精通(23)——Modbus TCP(0x02功能码)
3、C# Modbus通信从入门到精通(24)——Modbus TCP(0x03功能码)
4、C# Modbus通信从入门到精通(25)——Modbus TCP(0x04功能码)
5、C# Modbus通信从入门到精通(26)——Modbus TCP(0x05功能码)
6、C# Modbus通信从入门到精通(27)——Modbus TCP(0x06功能码)
环境 名称版本操作系统Windows10(64位)AndroidStudio2022.3.1 Patch 2 前言 最近更新了AndroidStudio编写程序的时候发现gradle时老是报read time out错误提示
分析 当出现这个警告时,你应该猜到这是一个连接不上的问题(Connect to repo.maven.apache.org:443),连接错误的原因是因为没有正确上网导致的maven相关的资源拉不下来,没有梯子,就使用国内的开源网址
因为Apache 的服务器不在国内,可能会因为某个原因导致连接不上http://repo.maven.apache.org refused,所以现在就是要解决连接问题:
解决 国内的阿里技术很厉害 为我们提供了国内的镜像,增加仓库源
打开文件 $project/settings.gradle
pluginManagement { repositories { google() mavenCentral() gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } rootProject.name = "My Application" include ':app' 修改如下:
pluginManagement { repositories { maven{ url 'https://maven.aliyun.com/repository/google'} //修改 maven{ url 'https://maven.aliyun.com/repository/gradle-plugin'} //修改 maven{ url 'https://maven.aliyun.com/repository/public'} //修改 maven{ url 'https://maven.aliyun.com/repository/jcenter'} //修改 google() mavenCentral() gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.
相信2022年的伙伴在学习谷粒学院P201时,都会遇到这个错误
我们需要把端口号改为8160
然后重定向地址改为http://localhost:8160/api/ucenter/wx/callback就行了
🎬 鸽芷咕:个人主页 🔥 个人专栏:《速学C语言》《数据结构篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言💬 scanf( ) 函数的介绍💬 scanf( )的俩种用法🌱示例一:⛳️输入控制符⛳️ 输入参数 🌱示例二: 💬 scanf( )的返回值📖 EOF的含义 💬scanf( )的三种多组输入方式⛳️ 利用返回值多组输入⛳️ 利用EOF多组输入⛳️ 利用 ~ 按位取反操作符多组输入 🎬 多组输入的牛客网链接总结 前言 🌈hello! 各位宝子们大家好啊,相信大家都多多少少了用过scanf语句吧,但是对scanf函数没有全面的认识仅仅只是知道可以输入。
⛳️今天博主就给大家介绍一下scanf函数,以及在《牛客网》写题时遇到的多组输入该如何解决?
📚本期文章收录在《C语言初阶篇》,大家有兴趣可以看看呐!
⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!
💬 scanf( ) 函数的介绍 📜说明:
🔥 关于scanf( )我们在C++官网看一下
📚 注:关于scanf的参数类型官网上描述太复杂了,所以博主就不截取了。
由博主给大家讲解讲解讲解关键点 scanf 的功能用一句话来概括就是“通过键盘给程序中的变量赋值”。
✅ 函数的原型为:
# include <stdio.h> int scanf(const char *format, ...); 💬 scanf( )的俩种用法 🌱示例一: scanf(“输入控制符”, 输入参数);
如何跳转系统授权管理页? 跳转APP应用授权设置页面
文章目录 如何跳转系统授权管理页?效果图打开系统App的权限设置界面 效果图 例:Android
打开系统App的权限设置界面 App端:打开系统App的权限设置界面微信小程序:打开系统微信App的权限设置界面 uni.openAppAuthorizeSetting({ success: (res) => { console.log('success') } })
Handler 的主要使用场景 子线程完成耗时操作的过程中,通过 Handler 向主线程发送消息 Message,用来更新 UI 界面。因为 Android 是在主线程中更新 UI 的,在主线程出现耗时操作时,就会导致用户界面卡顿,所以我们一般都把耗时的操作(网络请求、IO 等)放到子线程中,然后通过 Handler 的方式让主线程更新 UI。
new Handler() 如果是无参构造器,其中调用了重载的构造方法并分别传入 null 与 false。并在构造方法中给两个全局变量赋值,两者都是通过 Looper 来获取。
@UnsupportedAppUsage final Looper mLooper; final MessageQueue mQueue; @UnsupportedAppUsage final Callback mCallback; final boolean mAsynchronous; public Handler(@Nullable Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "