✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信。
🍎个人主页:海神之光
🏆代码获取方式:
海神之光Matlab王者学习之路—代码获取方式
⛳️座右铭:行百里者,半于九十。
更多Matlab仿真内容点击👇
Matlab图像处理(进阶版)
路径规划(Matlab)
神经网络预测与分类(Matlab)
优化求解(Matlab)
语音处理(Matlab)
信号处理(Matlab)
车间调度(Matlab)
⛄一、粒子群算法简介 1 引言
自然界中的鸟群和鱼群的群体行为一直是科学家的研究兴趣所在。生物学家Craig Reynolds在1987年提出了一个非常有影响的鸟群聚集模型,在他的仿真中,每一个个体都遵循:避免与邻域个体相撞:匹配邻域个体的速度;飞向鸟群中心,且整个群体飞向目标。仿真中仅利用上面三条简单的规则,就可以非常接近地模拟出鸟群飞行的现象。1990年, 生物学家Frank Heppner也提出了鸟类模型, 它的不同之处在于:鸟类被吸引飞到栖息地。在仿真中,一开始每一只鸟都没有特定的飞行目标,只是使用简单的规则确定自己的飞行方向和飞行速度,当有一只鸟飞到栖息地时,它周围的鸟也会跟着飞向栖息地,最终整个鸟群都会落在栖息地。
1995年, 美国社会心理学家James Kennedy和电气工程师RussellEberhart共同提出了粒子群算法(ParticleS warm Optimization, PSO) , 该算法的提出是受对鸟类群体行为进行建模与仿真的研究结果的启发。他们的模型和仿真算法主要对Frank Heppner的模型进行了修正,以使粒子飞向解空间并在最优解处降落。粒子群算法一经提出,由于其算法简单,容易实现,立刻引起了进化计算领域学者们的广泛关注, 形成一个研究热点。2001年出版的J.Kennedy与R.Eberhart合著的《群体智能》将群体智能的影响进一步扩大[] , 随后关于粒子群优化算法的研究报告和研究成果大量涌现,继而掀起了国内外研究热潮[2-7]。
粒子群优化算法来源于鸟类群体活动的规律性,进而利用群体智能建立一个简化的模型。它模拟鸟类的觅食行为,将求解问题的搜索空间比作鸟类的飞行空间,将每只鸟抽象成一个没有质量和体积的粒
子,用它来表征问题的一个可能解,将寻找问题最优解的过程看成鸟类寻找食物的过程,进而求解复杂的优化问题。粒子群优化算法与其他进化算法一样,也是基于“种群”和“进化”的概念,通过个体间
的协作与竞争,实现复杂空间最优解的搜索。同时,它又不像其他进化算法那样对个体进行交叉、变异、选择等进化算子操作,而是将群体中的个体看作在l维搜索空间中没有质量和体积的粒子,每个粒子以一定的速度在解空间运动, 并向自身历史最佳位置P best和邻域历史最佳位置g best聚集, 实现对候选解的进化。粒子群算法具有很好的生物社会背景而易于理解,由于参数少而容易实现,对非线性、多峰问题均具有较强的全局搜索能力,在科学研究与工程实践中得到了广泛关注。目前,该算法已广泛应用于函数优化、神经网络训练、模式分类、模糊控制等领域。
2 粒子群算法理论
2.1粒子群算法描述
鸟类在捕食过程中,鸟群成员可以通过个体之间的信息交流与共享获得其他成员的发现与飞行经历。在食物源零星分布并且不可预测的条件下,这种协作机制所带来的优势是决定性的,远远大于对食物
的竞争所引起的劣势。粒子群算法受鸟类捕食行为的启发并对这种行为进行模仿,将优化问题的搜索空间类比于鸟类的飞行空间,将每只鸟抽象为一个粒子,粒子无质量、无体积,用以表征问题的一个可行解,优化问题所要搜索到的最优解则等同于鸟类寻找的食物源。粒子群算法为每个粒子制定了与鸟类运动类似的简单行为规则,使整个粒子群的运动表现出与鸟类捕食相似的特性,从而可以求解复杂的优化问题。
粒子群算法的信息共享机制可以解释为一种共生合作的行为,即每个粒子都在不停地进行搜索,并且其搜索行为在不同程度上受到群体中其他个体的影响[8],同时这些粒子还具备对所经历最佳位置的记
忆能力,即其搜索行为在受其他个体影响的同时还受到自身经验的引导。基于独特的搜索机制,粒子群算法首先生成初始种群,即在可行解空间和速度空间随机初始化粒子的速度与位置,其中粒子的位置用于表征问题的可行解,然后通过种群间粒子个体的合作与竞争来求解优化问题。
2.2粒子群算法建模
粒子群优化算法源自对鸟群捕食行为的研究:一群鸟在区域中随机搜索食物,所有鸟知道自己当前位置离食物多远,那么搜索的最简单有效的策略就是搜寻目前离食物最近的鸟的周围区域。粒子群算法
利用这种模型得到启示并应用于解决优化问题。在粒子群算法中,每个优化问题的潜在解都是搜索空间中的一只鸟,称之为粒子。所有的粒子都有一个由被优化的函数决定的适应度值,每个粒子还有一个速度决定它们飞翔的方向和距离。然后,粒子们就追随当前的最优粒子在解空间中搜索[9]。
粒子群算法首先在给定的解空间中随机初始化粒子群,待优化问题的变量数决定了解空间的维数。每个粒子有了初始位置与初始速度,然后通过迭代寻优。在每一次迭代中,每个粒子通过跟踪两个“极值”来更新自己在解空间中的空间位置与飞行速度:一个极值就是单个粒子本身在迭代过程中找到的最优解粒子,这个粒子叫作个体极值:另一个极值是种群所有粒子在迭代过程中所找到的最优解粒子,这个粒子是全局极值。上述的方法叫作全局粒子群算法。如果不用种群所有粒子而只用其中一部分作为该粒子的邻居粒子,那么在所有邻居粒子中的极值就是局部极值,该方法称为局部粒子群算法。
2.3粒子群算法的特点
粒子群算法本质是一种随机搜索算法,它是一种新兴的智能优化技术。该算法能以较大概率收敛于全局最优解。实践证明,它适合在动态、多目标优化环境中寻优,与传统优化算法相比,具有较快的计
算速度和更好的全局搜索能力。
(1)粒子群算法是基于群智能理论的优化算法,通过群体中粒子间的合作与竞争产生的群体智能指导优化搜索。与其他算法相比,粒子群算法是一种高效的并行搜索算法。
(2)粒子群算法与遗传算法都是随机初始化种群,使用适应值来评价个体的优劣程度和进行一定的随机搜索。但粒子群算法根据自己的速度来决定搜索,没有遗传算法的交叉与变异。与进化算法相比,粒子群算法保留了基于种群的全局搜索策略,但是其采用的速度-位移模型操作简单,避免了复杂的遗传操作。
(3)由于每个粒子在算法结束时仍保持其个体极值,即粒子群算法除了可以找到问题的最优解外,还会得到若干较好的次优解,因此将粒子群算法用于调度和决策问题可以给出多种有意义的方案。
(4)粒子群算法特有的记忆使其可以动态地跟踪当前搜索情况并调整其搜索策略。另外,粒子群算法对种群的大小不敏感,即使种群数目下降时,性能下降也不是很大。
3 粒子群算法种类
3.1基本粒子群算法
3.2标准粒子群算法
引入研究粒子群算法经常用到的两个概念:一是“探索”,指粒子在一定程度上离开原先的搜索轨迹,向新的方向进行搜索,体现了一种向未知区域开拓的能力,类似于全局搜索;二是“开发”,指粒子在一定程度上继续在原先的搜索轨迹上进行更细一步的搜索,主要指对探索过程中所搜索到的区域进行更进一步的搜索。探索是偏离原来的寻优轨迹去寻找一个更好的解,探索能力是一个算法的全局搜索能力。开发是利用一个好的解,继续原来的寻优轨迹去搜索更好的解,它是算法的局部搜索能力。如何确定局部搜索能力和全局搜索能力的比例, 对一个问题的求解过程很重要。1998年, Shi Yuhui等人提出了带有惯性权重的改进粒子群算法[10],由于该算法能够保证较好的收敛效果,所以被默认为标准粒子群算法。其进化过程为:
在式(6.7)中,第一部分表示粒子先前的速度,用于保证算法的全局收敛性能;第二部分、第三部分则使算法具有局部收敛能力。可以看出,式(6.7)中惯性权重w表示在多大程度上保留原来的速度:W
较大,则全局收敛能力较强,局部收敛能力较弱;w较小,则局部收敛能力较强,全局收敛能力较弱。
当w=1时,式(6.7)与式(6.5)完全一样,表明带惯性权重的粒子群算法是基本粒子群算法的扩展。实验结果表明:w在0.8~1.2之间时,粒子群算法有更快的收敛速度;而当w>1.2时,算法则容易陷入局部极值。
只列举了常用的,具体的还需要去查看帮助手册
内网信息收集 工作组信息收集 用户信息 #查看本机用户列表 net user #获取本地管理员信息 net localgroup administrators #查看当前在线用户 quser query user query user || qwinsta #查当前用户在目标系统中的具体权限 whoami /all #查看当前权限 whoami && whoami /priv #查当前机器中所有的组名,了解不同组的职能,如,IT,HR,ADMIN,FILE net localgroup 系统信息 #查询网络配置信息。进行IP地址段信息收集 ipconfig /all #查询操作系统及软件信息 systeminfo /fo list systeminfo | findstr "主机名" systeminfo | findstr /B /C:"OS Name" /C:"OS Version" systeminfo | findstr /B /C:"OS 名称" /C:"OS 版本" #查看当前系统版本 ver wmic os list brief wmic os get Caption,CSDVersion,OSArchitecture,Version #查看系统体系结构 echo %PROCESSOR_ARCHITECTURE% #查询本机服务信息 wmic service list brief #查看安装的软件的版本、路径等 wmic product get name, version powershell "
报错内容 在用swat进行水文分析时,点击DEM-based下的自动生成河网时出现报错Unhandled exception has occurred in a component in yourapplication. If you click Continue, the application willignore this error and attempt to continue.
"esriDataSourcesRaster.GdalDriver") Failed to copyraster datasetERROR 010240: Could not save raster dataset toC:\User\AppData Local withoutput format GRID
同时,对于error-2147467259也有可能解决
Error number: -2147467259
Error message: Error HRESULT E_FAIL has been returned from a call to a COM component.
Module name: mAGUtil
Function name: lyr_create
Procedure (error line or description): 3
Java内部类(匿名内部类) 一、内部类二、静态内部类三、成员内部类四、局部内部类(了解即可)五、匿名内部类(重要) 一、内部类 1、概述
内部类就是一个定义在一个类里面的类,里面的类可以理解为(寄生),外部类可以理解成(宿主)。
public class People{ //内部类 public class start{ } } 2、内部类的使用场景、作用
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构可以选择使用内部类来设计。内部类结构通常可以方便访问外部类的成员,包括私有的成员内部类提供了更好的封装性,内部类本身就可以用private protected等修饰,封装性可以做更多控制。 3、内部类的分类
静态内部类成员内部类(非静态内部类)局部内部类匿名内部类 二、静态内部类 1、什么是静态内部类?
有static修饰,属于外部类本身。
它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别人里面而已。
public class Outer{ //静态内部类 public static class Inner{ } } 2、静态内部类创建对象的格式:
格式:外部类名.内部类名 对象名 = new 外部类.内部类构造器;
范例:
Outer.Inner in = new Outer.Inner(); 3、静态内部类的访问拓展
静态内部类中是否可以直接访问外部类的静态成员?
可以,外部类的静态成员只有一份,可以被共享访问。
静态内部类中是否可以直接访问外部类的实例成员?
不可以,外部类的实例成员必须要用外部类对象访问。
4、静态内部类的使用场景、特点、访问总结
如果一个类中包含了一个完整的成分,如汽车中的发动机类。
特点、使用与普通类是一样的,类有的成分它都有,只是位置在别人里面而已
可以直接访问外部类的静态成员,不可以直接访问外部类的实例成员
注意:开发中实际上用的还是比较少。
三、成员内部类 1、什么是成员内部类?
无 static 修饰,属于外部类的对象
JDK16之前,成员内部类中不能定义静态成员,JDK 16开始也可以定义静态成员了。
public class Outer{ //成员内部类 public class Inner{ } } 2、成员内部类创建对象的格式
报错:RuntimeError: CUDA error: invalid device ordinal
CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.
代码:
parser.add_argument('--gpu', type=int, default=3) args = parser.parse_args() os.environ["CUDA_VISIBLE_DEVICES"] = str(args.gpu) torch.cuda.set_device(args.gpu) gpu设为0运行压根没任何问题
明明有8个卡,只是gpu = 3为什么一直报这个错???
gpt告诉的原因:
确保你正在使用的CUDA版本与PyTorch版本兼容。有时CUDA版本与PyTorch版本不兼容会导致这种错误。
确保你的设备索引值在正确的范围内。有时候设备索引值超出了范围,会引发这个错误。
尝试使用CUDA_LAUNCH_BLOCKING=1。你可以在运行脚本之前设置这个环境变量来启用CUDA的同步错误检测。这样可以使得CUDA错误被立即报告,并且堆栈跟踪是正确的,有助于更好地进行调试。
这三个原因肯定都不是。
又问了一遍,它说:
确认你的系统中有多少个可用的CUDA设备。
所以进一步认为:总不能是代码识别不到那些卡之类的原因?那能识别几张卡?
一开始这状态是没有这左边的2的,加了下面那行代码才是下图的状态——
parser.add_argument('--gpu', type=int, default=3) args = parser.parse_args() **print(torch.cuda.device_count())** os.environ["CUDA_VISIBLE_DEVICES"] = str(args.gpu) torch.cuda.set_device(args.gpu) 加了一行
print(torch.cuda.device_count())看看能识别几张卡,结果
为什么又突然可以在第三张卡运行了??
而且就像是突然又激活了这几张卡一样
具体原因仍不清楚…有大佬知道为什么吗?
opencv4.0之前版本和部分4.0版本的putText仅支持英文,如果中文会乱码,可以用下面方法构造函数解决:
头文件如下:
#pragma once #ifndef PUTTEXT_H_ #define PUTTEXT_H_ #include <windows.h> #include <string> #include <opencv2/opencv.hpp> using namespace cv; void GetStringSize(HDC hDC, const char* str, int* w, int* h); void putTextHusky(Mat &dst, const char* str, Point org, Scalar color, int fontSize, const char *fn = "Arial", bool italic = false, bool underline = false); #endif // PUTTEXT_H_ 源文件如下:
#include "putText.h" void GetStringSize(HDC hDC, const char* str, int* w, int* h) { SIZE size; GetTextExtentPoint32A(hDC, str, strlen(str), &size); if (w !
✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信。
🍎个人主页:海神之光
🏆代码获取方式:
海神之光Matlab王者学习之路—代码获取方式
⛳️座右铭:行百里者,半于九十。
更多Matlab仿真内容点击👇
Matlab图像处理(进阶版)
路径规划(Matlab)
神经网络预测与分类(Matlab)
优化求解(Matlab)
语音处理(Matlab)
信号处理(Matlab)
车间调度(Matlab)
⛄一、轴承故障分析简介 1 研究背景
滚动轴承故障占旋转机械故障的大约30%,现阶段主要采用信号分析来进行故障识别。探究形成机械设备故障尤其是滚动轴承的理论和诊断手段及方法是广大科学家们共同追求的目标,无论是在工程实际还是故障分析理论上都有着重大的意义和应用价值。
1.1 轴承诊断背景
(1)滚动轴承
图1 托辊实物图
滚动轴承是当前工业生产中应用频率最高的轴承,可以极大地有效的减少机械机构运转之间的摩擦损失,摩擦损失对于整个机械运转架构来说是很大的无效能,会造成很大的资源浪费,使得整个设计出的机械运转效率下降,增大使用成本。对于滚动轴承来说,滚动体的外形与尺寸及个数对滚动轴承的性能及使用寿命有着很大的影响,滚动轴承有着节能效果明显、维修简便,质量可靠等优点。同时采用滚动轴承维修量大大减少,有着维修简便的优点。
(2)轴承诊断
滚动轴承的故障诊断始于60年代,1966年瑞典SKF公司发明了用冲击脉冲仪检测轴承损伤,滚动轴承的故障诊断水平得到了很大的提高。
滚动轴承若故障会引起一定的的冲击振动,是由冲击点为原点以球面形式向外扩散,然后逐步通过相应机构如一些零件轴承座等传到箱体和机架。需要注意的是,因冲击产生的振动的为高频振动,在通过轴承构件传递振动时,会有比较明显的能量损失。因此,在轴承故障诊断中,所选取的试验点即测点应尽可能减少中间所经过的轴承构件,所选取的测试点离轴承外圈也就是冲击点的距离越小越好。根据通过产生异响和温度升高等异常现象,初步推断故障产生在轴承上,故布置3个测点位置如图,得到三段正常信号,三段故障信号。
表1 设备的一般参数
图2 测点布置图
通过查阅资料及经验推断,因设备故障发出的“沙沙”声,初步确定托辊故障发生在轴承上,滚动轴承安装在托辊内主要用以减少托辊的运行阻力及减少胶带的磨损。
根据给出的轴承信号,查到轴承基本信息如下表。
表2 SKF308/309轴承基本参数
(3)滚动轴承故障诊断方法
滚动轴承故障是运行过程中机械设备故障的主要原因之一。滑动轴承的失效形式有磨损失效,疲劳失效,腐蚀失效和气蚀失效。
常用的对滚动轴承进行故障诊断的方式一般有时域分析,用时域参数对早期故障的敏感性,对滚动轴承进行定期检测,得到其峭度、峰值因子、以及振动频率有效值趋势曲线等,幅值或有效值的变化曲线或规律可以对滚动轴承故障有一个初步的诊断,或是频域分析,利用快速傅里叶变换获得振动信号的频谱图,了解频率成分。通过计算轴承故障频率与时域分析结果对比确定故障位置。
2 时域分析
2.1 时域波形分析
时域波形分析是指经过各种专业仪器采集记录并显示的被测设备信号与时间相对应的波形信号,如振动、噪声、温度、压力等进行分析,进而得到得到待测对象的时间历程的分析方法。信号在时域上的分析所包含的特征量较多,且视觉上更能明显看到规律,趋势也易于让人领会,是轴承故障诊断方面的重要依据。
表4 信号时域信息统计
通过对三个测点正常和故障的信号进行时域分析可以看出,故障信号的均值较正常信号均值要大,说明滚动体在滚道上运动的时候,不规则运动较大,轴承磨损程度大。故障信号较正常信号的方差值要大十倍左右,说明故障信号的数据波动程度很大。
每个测点的故障信号峰峰值比正常高很多,说明故障时机构振动、能量都很大。峭度对早期信号故障有较高的敏感性可以看出故障信号峭度比正常信号峭度大,说明轴承有一定程度的损伤。在一段故障信号中取三个幅值相同的点,w1信号周期约为0.4s,频率为2.5Hz,与滚动体故障频率接近。w2周期约为0.2s,频率约为5Hz与外圈故障频率接近。w3周期约为0.6s,频率为1.6Hz,与滚动体故障频率接近。
3 频谱分析
3.1 倒谱分析
倒谱分析就是将原始波形的傅里叶变换结进行对数求解,最后再将对数求解后的结果再进行傅里叶逆变换。倒谱分析在信轴承故障诊断方面具有较大的实用意义。倒谱分析可以将波形数据卷积后的多个信号进行分离,进而将波形数据中较为明显突出的特征量即特征信号分离出来,方便后面的对轴承的故障诊断分析,并将倒谱分析后的数据或波形特征与时域、频域等其他分析手段相结合进而达到对滚动轴承进行故障诊断的依据。
图5 第二段信号倒谱分析图
4 诊断结果与改进意见
通过对三个测点时域和频域的分析,由时域的周期性及计算出的轴承各部件故障频率分析,由时域分析总结分析出的故障信号特性及由频域分析对比总结出的的与轴承滚动体及外圈的故障数据特性相似性较大,初步推断是轴承滚动体和外圈由于点蚀、磨损等原因出现了裂纹等表面损伤性故障。
最后通过对轴承的拆解,发现轴承滚动体出现了磨损,轴承外圈出现了少部分点蚀,与本文诊断结果大致相符。
4.2 改进意见
为了预防轴承滚动体和外圈出现故障,应注意以下方面:
(1)注意在轴承装配之前的裂纹检查工作,若其装配前存在微裂纹、生锈等现象会导致轴承内各部件磨损过快,出现故障。
(2)注意轴承间各部件的润滑,控制润滑脂用量以达到最好的润滑效果。
⛄二、部分源代码 % ********** 内圈故障300r/min **********
clear;
clc;
文章目录 前言一、httpd1.安装1.1 源码编译安装1.2 yum安装 二、nginx三、haproxy四、lvs 前言 工作中使用过各种代理软件,有基于4层代理的,有基于7层代理的,现在大多的企业都上云了,云上有成熟的产品供我们使用,如阿里云SLB、华为云的ELB,腾讯云的CLB等都可以实现4层、7层的代理,由于云厂商成本的考虑,我们没法在云上使用4层代理软件,因此我们使用7层代理的产品比较多。软件比较多,配置繁杂,在这里做个总结备忘。有些步骤忘记了或者命令太长了,参考了不少文章和视频,感谢你们。
机器环境:
一、httpd 由于生产中通常使用nginx,以下步骤仅供参考:
Apache HTTP Server(简称Apache)是Apache软件基金会的一个开放源码的网页服务器软件,可以在大多数电脑操作系统中运行。由于其跨平台和安全性[注 1],被广泛使用,是最流行的Web服务器软件之一。它快速、可靠并且可通过简单的API扩展,将Perl/Python等解释器编译到服务器中。----《维基百科》
1.安装 1.1 源码编译安装 参考1: https://blog.csdn.net/carefree2005/article/details/122652021
参考2: https://blog.csdn.net/leshami/article/details/50144179
# 创建必要的目录 mkdir -p /apps/httpd # 下载必要的软件 wget https://dlcdn.apache.org/httpd/httpd-2.4.58.tar.gz wget https://archive.apache.org/dist/apr/apr-1.7.4.tar.gz wget http://archive.apache.org/dist/apr/apr-util-1.1.2.tar.gz # 编译安装 # 安装apr: tar xf apr-1.7.4.tar.gz cd apr-1.7.4 ./configure --prefix=/apps/apr make make install # 说明:编译时报错提示 rm: cannot remove `libtoolT': No such file or directory # 解决:直接打开 configure,把 "cfgfile" 那行删除掉,重新再运行 ./configure 就可以了。 # 安装apr-util tar xf apr-util-1.
目录
一、什么是 TypeScript以及为什么使用TypeScript?
二、TypeScript基础
三、高级TypeScript 四、TypeScript和React的结合
五、ts常见面试题
一、什么是 TypeScript以及为什么使用TypeScript? TypeScript是JavaScript的超级,可以编译为js。相比js添加了静态类型和其他一些新特性。例如:
ts通过引入静态类型,开发人员可以在编译时就捕获一些常见的错误,例如类型不匹配以及变量未定义等,这可以减少在运行时出现的错误,提高代码的可读性和可维护性。ts提供了强大的开发工具支持(代码补全、代码导航等),可以提高开发效率,并帮助开发人员更好的理解和修改代码。ts支持模块化开发,可以将代码分割成多个模块,提供更好的代码组织和可维护性。Ts 还支持面向对象编程的概念,如类、接口、继承等,可以更好地组织和抽象代码。TypeScript 是 JavaScript 的超集,这意味着现有的 JavaScript 代码可以逐步迁移到 TypeScript,而无需一次性重写整个代码库。这种渐进式采用使得 TypeScript 在现有项目中的集成更加容易。 二、TypeScript基础 1、ts的基本类型(Boolean, Number, String, Array, Tuple(元组), Enum(枚举值), Any, Void, Null , Undefined, Never)
2、ts中的变量声明、类型注解以及类型推断
变量声明:在ts中,跟在js一样,可以使用let和const来声明变量。类型注解:类型注解是指在变量或函数参数后面使用(:)来指定变量的类型,例如let aa:number = 1。类型注解可以帮助ts编译器检查代码的类型正确性类型推断:可以根据变量的赋值表达式自动推出变量的类型,而无需显式指定类型注解,例如let num = 10会自动推断num为number类型。 类型注解可以提供更明确的类型信息,增强代码的可读性和可维护性,而类型推断则可以简化代码,减少不必要的类型注解
3、接口(interface):TypeScript 支持接口,用于定义对象的结构。接口可以描述对象的属性、方法和索引签名,并可以被类、函数和其他接口实现。
//定义一个接口 interface aa { num:number, boo:boolean, ... } 4、别名(type):我们可以使用type为复杂的类型定义一个新的名称,使代码更具可读性。type可用于原始类型、联合类型、交叉类型、元祖、字面量类型等。type不能创建一个新的类型,它只是为已存在的类型定义一个新的名称。
//1、为原始类型定义别名 type Name = string; //2、为复杂类型定义别名 type User = { name: string; age: number; } //3、为联合类型定义别名 type StringOrNumber = string | number; //4、为交叉类型定义别名 type TallAndHandsome = Tall & Handsome; //5、为元组定义别名 type Point = [number, number]; //6、为字面量类型定义别名 type YesOrNo = 'yes' | 'no'; 5、可选参数:ts支持可选参数,用问号(?
以海康威视为例:
1、首先,在采集控制(AcquisitionControl)中把行触发模式(LineStart)打开,并在触发源(TriggerSource)设置选项下选择变频器(FrequencyConverter)。
2、其次,在变频器控制(FrequencyConverterControl)设置选项下的输入源(InputSource)中选择编码器模块输出(EncoderModuleOutput)。
3、最后,在编码器控制(EncoderControl)选项中设置编码器选择器(EncoderSelector)为Encoder0,编码器源A(EncoderSourceA)选择Line0,编码器源B(EncoderSourceB)选择Line1,如果产品有反转时拍照的需求,编码器触发模式(EncoderTriggerMode)可选择任意方向(AnyDirection),编码器计数模式(EncoderCounterMode)选择遵循方(FollowDirection)。
做后台管理系统的同学们,想必对Cascader级联选择器不会感到陌生,这个组件大多数会与树关联结合,实现对部门人员的分配等操作!这个操作前端的难点大多数是在Cascader与树的回显部分!
一般新增给后端传值的时候,保存当前人员的value或者唯一标识,而编辑回显的时候后端基本上也是将我们保存的值通过节后返回,这个时候我们就要通过返回的Id或者唯一标识,拿到当前树的节点及其祖先级节点,通过处理数据的方式,将值转化为el-Cascader的所需要回显的值!
话不多说直接上代码!
<template> <new-container> <el-cascader size="small" readonly filterable :props="{ multiple: true, }" ref="auditCascader" v-model="auditArr" :options="DeptTree" :show-all-levels="false" clearable ></el-cascader> </new-container> </template> <script> export default { name: "", data() { return { //树的值 DeptTree: [ { value: "1", label: "目录1", children: [ { value: "1.1", label: "目录1.1", children: [ { value: "1.1.2", label: "目录1.1.2", title: "三级目录", }, { value: "1.1.1", label: "目录1.1.1", title: "三级目录", }, ], title: "二级目录", }, { value: "
有个需求是根据时间把一个df进行拆分成几部分数据 首先是根据单位时间,例如每天,每分钟,每个月这种,就可以直接使用下面的代码就可以了,只需要改变dt.date变成你需要的单位
import pandas as pd import datetime as dt df = pd.read_csv("test.csv") date_col = "raw_timestamp" df[date_col] = pd.to_datetime(df[date_col]) groups = df.groupby(df[date_col].dt.date) for date, group in groups: file_name = f"./date/{date}.csv" group.reset_index(drop=True).to_csv(file_name, index=False) 但是如果不是单位时间而是半小时之内的呢,就需要使用这样 import pandas as pd import datetime as dt df = pd.read_csv("test.csv") date_col = "raw_timestamp" df[date_col] = pd.to_datetime(df[date_col]) df ['half_hour'] = df [date_col].dt.floor( '30min') for half_hour , group in final_df.groupby('half_hour'): file_name = f"./date/{half_hour}.csv" group.drop('half_hour', axis=1).reset_index(drop=True).to_csv(file_name,index=False) 这样就会向下取整,例如9:45,9:55,9:32就会都变成9:30,而10:01就会变成10:00,这样再根据这列来进行groupby,最后把这列删除就行了
如果想单独处理每一份切分的时间的话可以看我这篇blog
项目中引用了一个UI组件库,在表单上添加了`ref`属性,方便提交时验证。触发提交方法时显示不存在这个方法或this.$refs为undefined。
<u--form labelPosition="left" :model="userInfo" :rules="rules" ref="loginForm"> <u-form-item label="账号" prop="name" borderBottom ref="username"> <u--input v-model="userInfo.name" placeholder="请输入账号" border="surround"></u--input> </u-form-item> <u-form-item label="密码" prop="password" borderBottom ref="password"> <u--input v-model="userInfo.password" placeholder="请输入密码" border="surround" type="password"></u--input> </u-form-item> <div class="loginBtn"><u-button type="primary" @click="loginApp">登录</u-button></div> </u--form> 解决方法:
引入`getCurrentInstance`,t得到当前组件实例,然后用`ctx.$refs`代替`this.$refs`。这里的`ctx`相当于全局this。
<script setup> import { getCurrentInstance } from 'vue' // 获取当前组件实例 const { ctx } = getCurrentInstance(); function loginApp() { ctx.$refs.loginForm.validate().then(res => { uni.$u.toast('校验通过') }).catch(err => { uni.$u.toast('校验失败') }) } <script> ------------------2023/10/27更新---------------------------------
真机调试时,遇到一个问题,用上面的方法获取不到`dom`元素。
解决方法:
定义一个ref对象,要和视图中的`ref``引用名称相同。
// 视图 <u--form labelPosition="
文章目录 1、环境准备2、简单的系统优化2.1打开文件数优化2.2内核参数优化2.3关闭防火墙,selinux2.4优化history2.5更新阿里云repo源&安装必要的软件2.5加快ssh登录速度 3、开始配置3.1创建基于centos8光盘的base源3.2、配置extras源和epel源 4.总结 1、环境准备 IP地址系统版本安装软件10.0.0.1CentOS Linux release 8.5.2111最小安装nginx,httpd10.0.0.2CentOS Linux release 8.5.2111最小安装httpd 2、简单的系统优化 2.1打开文件数优化 [root@centos8 ~]# cat /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 * soft noproc 65535 * hard noproc 65535 [root@centos8 ~]# 2.2内核参数优化 [root@centos8 ~]# cat /etc/sysctl.conf fs.file-max = 999999 net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.
目录 一.缓存的作用二.缓存的使用1.适用缓存的数据场景2.读取缓存流程图 三.本地缓存和分布式缓存 一.缓存的作用 Java缓存技术是在应用程序和数据库之间的一种中间层,用于存储暂时性数据,尤其是读取频繁但更新较少的数据。它的作用是减轻应用程序和数据库之间的负担,提高应用程序的响应速度和性能。
二.缓存的使用 1.适用缓存的数据场景 (1) 对即时性、数据一致性要求不高的。
(2) 访问量大并且更新频率不高的数据(读多,写少)。
2.读取缓存流程图 三.本地缓存和分布式缓存 本地缓存: 适用于单机情况(分布式情况会出现数据不一致问题)。
分布式缓存: 可以解决本地缓存存在的问题(使用缓存中间件:redis等)。
这个困扰了小虎很久,有些repositories我很想下,但是下载速度对中国的用户很不友好,经常10kb/s。这里给出几种可能的解决办法。
解决方法 方法1到码云拉资源Gitee码云搜索替代用码云拉github的资源 方法2github傻瓜法一个个文件下方法3到美国用当地的网下载 方法1到码云拉资源 Gitee码云搜索替代 这个亲测,库量大,速度快。在这里小虎下载到了在github下载失败n次的带目录deeplearning。
用码云拉github的资源 先登录,复制github链接,然后打开主页面右上角improt repository,粘贴链接。
下载很快。
因为可能已经有人用过这种方法了,所以你可以直接搜索下载,不过的注意可能他们导入时候的代码不是现在的最新版。
参考资料【亲测有效】解决GitHub下载过慢和下载项目失败的问题
方法2github傻瓜法一个个文件下 事实证明这种方法只适用于一些比较简单的库,有些文件必须点开才能下,如果只是需要部分代码,也可以点开重要的代码或文件下载。
下面用svn下载某个特定文件夹,每次到第五个都出错,可以认定是这资源你直接下一辈子下不来。
方法3到美国用当地的网下载 这似乎是最好的办法,github的总部是在老美的。
GitHub, Inc. is a United States-based global company
Java规范参考 详细的解释可以参考Java规范:
https://docs.oracle.com/javase/specs/jls/se19/html/jls-9.html#jls-9.6.3
可重复注解接口介绍 可重复注解接口是从Java 1.8版本引入的,表示可以重复出现。一个可重复注解接口A用@Repeatable修饰,并且@Repeatable的元素value 的值指明了一个A的容器注解接口。容器注解接口必须声明一个value()方法,它的返回类型是可重复注解接口类型的数组,例如A[]。在容器注解接口中声明的其它不同于value()的方法,必须有一个默认值。 例如,定义了一个可重复注解接口Name:
package com.thb; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; @Documented @Retention(CLASS) @Target({ TYPE, FIELD }) @Repeatable(Names.class) public @interface Name { String value(); } 定义可重复注解Name接口的容器注解接口Names:
package com.thb; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; @Documented @Retention(RUNTIME) @Target({ TYPE }) public @interface Names { Name[] value(); } 容器注解接口的保留范围要至少跟可重复注解接口一样长。保留范围用@Retention显式或者隐式声明。
【元素选择】 【问题描述】 给定线性序集中n个元素和一个整数k,1 <= k <= n,要求找出这n个元素中第k小的元素,即如果将这n个元素依次线性序排列时,排在第k个位置的元素即为要找的元素。当k=1时,就是要找的最小元素;当k=n时就是要找的最大元素;当k=(n+1)/2时,称为中位数。
一般的选择问题(找n个元素的最小元素、最大元素以及中位数)在O(n)时间内都可以得到解决。下面将讨论一般选择问题的一个分治算法 线性时间选择。
【算法分析】 1. 找到满足要求的划分基准
(1)将n个输入元素划分成[n/5]个组,每组5个元素,除可能有一个组不是5个元素外。用任意一种排序算法,将每组中的元素排好序,并取出每组中的中位数,共[n/5]个。
(2)递归调用Select找出这[n/5]个元素的中位数。如果[n/5]是偶数,就找它的两个中位数中较大的一个。然后以这个元素作为划分基准。
注:下图为划分策略的示意图,其中n个元素用小圆点来表示,空心小圆点为每组元素的中位数,中位数的中位数x在途中标出,途中所画箭头是由较大元素指向较小元素的。
分析:设所有元素互不相同,在这种情况下,找出的基准x至少比3[(n-5)/10]个元素大,因为在每一组中有两个元素小于本组的中位数,而[n/5]个中位数中又有[(n-5)/10]个小于基准x。同理,基准x也至少比3[(n-5)/10]个元素小,而当n>=75时,3[(n-5)/10]>=n/4。所以按此基准划分所得的两个子数组的长度都至少缩短1/4。
2. Select算法如下:
template<class Type> Type Select(Type a[], int p, int r, int k) { if (r - p < 75) { //用某个简单排序算法对数组a[p:r]排序 return a[p + k - 1]; } for (int i = 0; i <= (r - p - 4) / 5; i++) //将a[p+5*i]至a[p+5*i+4]的第3小元素与a[p+i]交换位置 //找中位数的中位数,r-p-4即上面所说的n-5 Type x = Select(a, p, p + (r - p - 4) / 5, (r - p - 4) / 10); int i = Partition(a, p, r, x), j = i - p + 1; if (k <= j)return Select(a, p, i, k); else return Select(a, i + 1, r, k - j); } 3.
文章目录 前言1.for - else2.一颗星*和两颗星**3.三元表达式4.with - as5.列表推导式6.列表索引的各种骚操作7.lambda函数8.yield 以及生成器和迭代器9.装饰器10.巧用断言assert 总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍 四、Python工具包+项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料 六、Python兼职渠道 前言 Python 语法的精妙之处就体现在下面10个例子中。
1.for - else >>> for i in [1,2,3,4]: print(i) else: print(i, '我是else') 1 2 3 4 4 我是else else 的眼里只有 for,只要 for 顺利执行完毕,else 就会屁颠儿屁颠儿地跑一遍:
>>> for i in [1,2,3,4]: if i > 2: print(i) else: print(i, '我是else') 3 4 4 我是else 只有当 for 循环被 break 语句中断之后,才会跳过 else 语句:
''' >>> for i in [1,2,3,4]: if i>2: print(i) break else: print(i, '我是else') 3 2.
0 效果 1 添加自定义指令 新建目录src/directive/el-table
在el-table目录下新建文件adaptive.js
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event' // 设置表格高度 const doResize = async(el, binding, vnode) => { // 获取表格Dom对象 const { componentInstance: $table } = await vnode // 获取调用传递过来的数据 const { value } = binding if (!$table.height) { throw new Error(`el-$table must set the height. Such as height='100px'`) } // 获取距底部距离(用于展示页码等信息) const bottomOffset = (value && value.bottomOffset) || 90 if (!$table) return // 计算列表高度并设置 const height = window.
忘记过去,超越自己
❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-10-27 ❤️❤️ 本篇更新记录 2023-10-27 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 🔥零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇,涵盖ESP8266大部分开发技巧。 快速导航
单片机菜鸟的博客快速索引(快速找到你要的)
如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。
文章目录 1. 前言2. 核心代码 1. 前言 在前面
【Arduino TFT】 记录ESP32驱动显示二维码 显示gif动图,涉及TFT_eSPI、TJpg_Decoder库、使用python脚本一键生成测试代码
文章中,遇到了一个问题:
生成的jpeg图片背景颜色不对,所以就得在脚本基础上继续加上修改背景颜色的代码。
2. 核心代码 # 修改背景颜色为黑色 pixels = new_im.load() width, height = new_im.size r1, g1, b1 = pixels[0, 0] for x in range(width): for y in range(height): r, g, b = pixels[x, y] if r == r1 and g == g1 and b == b1: pixels[x, y] = (0, 0, 0) 原理就是:获取某一个点的rgb值(比如我这里以左上角,也就是背景颜色),然后把等于这个颜色的值都设置成黑色,就达到改造的目的。
忘记过去,超越自己
❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-10-27 ❤️❤️ 本篇更新记录 2023-10-27 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 🔥零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇,涵盖ESP8266大部分开发技巧。 快速导航
单片机菜鸟的博客快速索引(快速找到你要的)
如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。
文章目录 1. 前言2. Python脚本 1. 前言 博主在制作tft 自定义字库时,有个特别需求就是:
无脑复制了一堆中文汉字,然后需要挑选出不重复的汉字,然后再转成UniCode
所以,首先要解决的就是
挑选出不重复的汉字
直接在网上找到了一个Py脚本,特此分享记录一下。
2. Python脚本 在这里插入图片描述
import re # 打开文件 fr = open('./脚本使用.txt', 'r', encoding='UTF-8') # 读取文件所有行 content = fr.readlines() fr.close() contentLines = '' characers = [] stat = {} # 依次迭代所有行 for line in content: # 去除空格 line = line.
将桥接网络改为默认适配器
记录一下在windows环境下通过命令行窗口进行进程有关的几个操作。
1、查找占用端口的进程ID(PID): netstat -ano|findstr 28087 假如PID为2181 2、根据PID找进程名称: tasklist | findstr 2181 发现是占用28087端口的进程为:java.exe。 3、根据PID结束对应进程: taskkill -PID 2181 -F 强制关闭PID为2181的进程。
这是21年的文章,Win10已经更新太多遍了,这些方法不一定能用了,请慎重! 1、第一步:关闭Windows Update服务 在搜索框中输入“服务”:
打开“服务”操作界面,找到 Windows Update:
右键点击它,选择“属性”(或者直接双击),打开属性界面:
如果服务状态是运行,则先点击“停止”按钮,然后将启动类型设置为“禁用”,最后点击“应用”按钮;
你以为到这里就结束了,那你就小看微软了!
接下来还是在这个界面,点击“恢复”界面,按如下进行设置:
将失败后的操作统一设置成“无操作”,然后将天数尽量往大了写!最后应用并确定。
这次就该弄好了吧,图样图森破!
2、第二步:组策略中关闭Windows10的更新 2.1、打开组策略编辑器 如果你的Win10操作系统是专业版的,则直接跳过该步骤。
如果是Win10家庭版的则需要进行此操作。因为Win10家庭版在默认情况下是没有组策略的选项的,需要通过一些操作来激活组策略的选项。
首先在桌面创建一个名为 GroupPolicy.cmd 和 List.txt 的文件,在 GroupPolicy.cmd 中输入以下内容:
pushd "%~dp0" dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txt dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum >>List.txt for /f %%i in ('findstr /i . List.txt 2^>nul') do dism /online /norestart /add-package:"C:\Windows\servicing\Packages\%%i" pause 保存之后,右键点击->以管理员身份运行,运行结束之后最好重启一下电脑;
此时在搜索框中搜索 gpedit.msc 即可打开组策略编辑器:
组策略编辑器如下所示:
2.2、配置组策略编辑器 首先,通过左侧的目录树转到 计算机配置->管理模板->Windows组件->Windows更新,最终找到 配置自动更新 选项:
然后双击打开,将其数值改为 已禁用 ,然后应用并确定:
如果你想正常接收更新,只是不满自动重启的话,可以修改该项值为 已启用,然后在下拉菜单中选择 自动下载并通知安装: 接下来,则还可以进入组策略编辑器的 用户配置->管理模板->系统 目录,在最下面,有一个项目名为 Windows自动更新,可以一并禁用掉:
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四、核心代码4.1 随机景点推荐4.2 景点评价4.3 协同推荐算法4.4 网站登录4.5 查询景点美食 五、免责说明 一、摘要 1.1 项目介绍 基于Vue+SpringBoot+MySQL的海南旅游推荐系统,基于协同推荐算法,包括用户网页和管理后台,包含景点类型模块、旅游景点模块、行程推荐模块、美食推荐模块、景点排名模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,海南旅游推荐系统基于角色的访问控制,给景点管理员、游客使用,可将权限精确到按钮级别,您可以自定义角色并分配权限,系统适合设计精确的权限约束需求。
项目编号: S 023 ,源码已在 B i l i b i l i 中上架,需要的朋友请自行下载。 \color{red}{项目编号:S023,源码已在 Bilibili 中上架,需要的朋友请自行下载。} 项目编号:S023,源码已在Bilibili中上架,需要的朋友请自行下载。
https://gf.bilibili.com/item/detail/1104039029 为了帮助小白入门 Java,博主录制了本项目配套的《项目手把手启动教程》,希望能给同学们带来帮助。
1.2 项目录屏 二、功能模块 2.1 用户端 景点推荐:根据用户个性化偏好给用户推荐感兴趣的景点
【景点信息包含:景点名称、景点类型、评分、收藏量、门票价格、门票预订(提供购买链接,用户可以通过点击链接到其他平台购买门票)、开放时间、景区地址(所在市区、详细地址)、景点介绍】景点筛选:用户可通过设置自己想要的景点类型、景点门票价格范围、景区地址(海口市、三亚市、儋州市、三沙市等)来筛选满足自身需求的景点
筛选:【注:若用户只设置了一个筛选条件则只需满足一个筛选条件就推荐给用户,若设置两个以上,则需都满足才给用户推荐】旅游攻略:用户可以通过搜索景点名称来获取景点周边美食以及行程路线的相关信息
(1)交通指南:起点、终点、交通方式、行程路线
(2)周边美食:美食图片、名称、类型、简介、人均消费景点数据:景点数据可视化
(1)好评度排名:管理员可以看到好评度高的前十个景点【排名、景点名称、好评度】
(2)景点收藏量:管理员可以看到收藏量排名前十的景点【排名、景点名称、收藏量】个人中心:
(1)个人信息:账号、姓名、联系方式、身份证号(用户可以更新个人信息、退出登录)
(2)景点收藏:用户可以查看、取消收藏过的景点 2.2 管理员端 个人中心:管理员个人信息景点信息管理:
(1)查询:可通过搜索景点名称、地址、景点类型来获取需要的景点数据(搜索到需要的景点数据后可进行查看、修改、删除景点信息操作)
(2)添加:可以添加新的景点信息用户信息管理:
(1)查询:可通过搜索用户账号来查询需要的用户(查询到需要的用户后可对用户信息进行查看、修改、删除操作)
(2)添加:可添加新用户信息行程信息管理:
(1)查询:可通搜索景点地址来获取景点行程路线信息(查询到需要的行程信息后可对其进行查看、修改、删除操作)
(2)添加:可添加信息美食信息管理:
(1)查询:可通搜索景点地址来获取景点周边美食信息(查询到需要的信息后可对其进行查看、修改、删除操作)
(2)添加:可添加新的美食信息景点数据:景点数据可视化(同用户端的景点数据可视化)
(1)好评度排名:管理员可以看到好评度高的前十个景点【排名、景点名称、好评度】
(2)景点收藏量:管理员可以看到收藏量排名前十的景点【排名、景点名称、收藏量】 三、系统展示 四、核心代码 4.1 随机景点推荐 @RequestMapping(value = "
在用laravel框架进行数据库迁移的时候报错如下 这是由于Laravel 默认使用 utf8mb4 字符, 包括支持在数据库存储「 表情」 。 如果你正在运行的 MySQL release 版本低于5.7.7 或 MariaDB release 版本低于10.2.2 , 为了MySQL为它们创建索引, 你可能需要手动配置迁移生成的默认字符串长度, 你可以通过调用 AppServiceProvider 中的 Schema::defaultStringLength 方法来配置它: 解决办法 E:\phpstudy\phpstudy_pro\WWW\laravel\app\Providers\AppServiceProvider.php
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Schema; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { // Schema::defaultStringLength(191); } } //加上默认字符串长度 数据库删了刚才迁移一半的表,然后再次执行php artisan mirgration PS E:\phpstudy\phpstudy_pro\WWW\laravel> php artisan migrate Migration table created successfully.
WinForms 應用程式中使用 WebView2。Windows 應用 SDK WebView2 公共 WebView2 可在 Windows 應用 SDK 中使用 Edge 與 WinUI 合作,將 WebView2 控件反向移植到 WinUI2 中。Windows UI 程式庫 (WinUI) 2 與 Windows SDK 整合並使用 XAML Islands() 為 UWP 應用程式提供官方原生 Windows UI 控制項和其他使用者介面元素。
Visual Studio C# ASP.NET 的應用,替換應用程式 WebBrowser 改用 Microsoft Edge WebView2 的 WinForms 應用程式中內嵌 Microsoft Edge (Chromium) 平台 Web 內容。永久啟動載入器,根據預設 WebView2 會「永久」並接收自動更新,以保持最新狀態且最安全的平台。這個「永久」看以後的網路變化吧。Internet Explorer 瀏覽器徹底淘汰日期在 2022/06/15 不再支援 IE 11 瀏覽器傳統型應用程式,並推薦移轉至 Microsoft Edge。原本於本機作業的 WebBrowser 亦可使用新的網路技術。
最近一两年,笔者使用公司提供的笔记本,由于安全限制,没法安装一些虚拟机软件,导致自己在学习过程总是感觉很麻烦,所以一直想尝试一种不用付费虚拟机如软件,使用window自带的服务Hyper-V来实现。在1,2年前自己也尝试过用Hyper-V,由于在连接wi-fi并且同时能够以固定ip访问Hyper-V中的服务器问题中被卡住,所以一直没用这种方案。最近自己重新尝试用这种方案,最后最终终于解决。现在做以下总结,其中以下内容中一些是网友的编写内容。
开启Hyper-V服务 右键单击 Windows 按钮并选择“应用和功能”。
选择相关设置下右侧的“程序和功能”。
选择“打开或关闭 Windows 功能”。
选择“Hyper-V”,然后单击“确定”。
安装完成后,系统会提示你重新启动计算机。
此部分不一一叙述了,若是有不清楚的地方,可以自行网上查询。
以下是Hyper-V下安装Centos的示例:
以下转自:https://blog.csdn.net/qq_31362933/article/details/132280598?spm=1001.2014.3001.5502
第一步:下载镜像文件 我们到centos官网下载地址去下载,本文采用centos 7.9版本为例,下载源采用阿里云,需要下载其他版本的可以通过centos下载的网址自行下载。
centos-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云
第二步:启用Hyper-V 首先我们先配置虚拟机的网络环境,如下图,点击虚拟交换机管理器。
然后我们创建虚拟网络交换机 (此步可以暂时不配置,直接使用下面的Default Switch(以达到动态获取ip+使用wi-fi), 后面配置外网+一直固定ip访问的时候重新配置网络)
出现如下页面,点击确定,这样我们的虚拟网络交换机就完成了。
接下来我们就要安装centos了,在首页点击操作栏新建右边的小三角形
弹出的选项中选择虚拟机,出现以下弹框,直接点击下一页,
创建你的虚拟机名字,你可以设置如centos7.9,点击下一页
指定代数
分配内存,可以根据你的实际需要分配内存
配置网络,选择我们最开始创建的交换机虚拟网络
连接虚拟网盘,可以指定安装的位置和硬盘大小,按需分配。
安装选项,点击从可启动的CD/DVD-ROM安装操作系统,并选择我们第一步下载的ISO映像文件
点击完成
第三步:安装CentOS 返回Hyper-v首页,选择我们刚刚创建的CentOS7,点击启动
键盘上下键选择 Install CentOS 7,敲回车
选择安装语言
安装信息摘要,选择安装位置
接下来我们点击网络和主机名,配置我们的网络
用户配置,创建我们root的密码
注意:此部分有个重启,发现在Hyper-V重启的时候,还是会进入安装界面,类似如下:
解决思路,光驱的启动项在首位造成。检查虚拟机启动项
以下转自:https://blog.csdn.net/a2262726/article/details/109185657
解决:关闭打开的centos7虚拟机,进入Hyper-V centos8的设置界面CD/DVD选择“无”→“确认”即可。类似如下界面:
检查:重新打开centos虚拟机,类似如下:
启动系统
登录linux
好了,我们的系统安装好了。
centos系统的基本配置请看下一章节
解决配置成固定ip之后,没法连接wi-fi的问题或者说不能同时使用固定ip的问题 参考另外一篇博文:
【Hyper-v 管理器虚拟机配置内网外网固定ip】
解决刚安装完之后,没法wget,没法安装vim等问题 没法安装是因为Centos默认的repo是别的不可用的地址,解决办法是,给它替换成阿里的repo (如果wget不了,直接到:/etc/yum.repos.d/epel.repo.backup
mv /etc/yum.repos.d中,然后去下载,然后通过手动编辑的方式配置文件内容)
# 1.下载安装wget yum install -y wget # 2.
本文转自:https://blog.csdn.net/qq_34340582/article/details/129241425
1.1. Default Switch(Hyper-v默认虚拟网卡)无法设置固定ip Hyper-V自带一个不能删除的Default Switch虚拟交换机,虚拟机使用该网络可以自动获取IP直接上网。但这个网络的网关地址每次重启后都会改变,所以你无法在虚拟机上设置固定IP用于宿主机SSH访问。
微软官方说明:每次主机重启后Hyper-V会自动找一个未使用的网络然后修改Default Switch的网络地址
1.2. 解决方法 用双网卡方案解决该问题。大概思路是用虚拟机第一块网卡连接Default Switch自动获得IP和DNS上外网,用第二块网卡设置内部固定IP地址用于宿主机或其它虚拟机SSH连接。具体操作步骤如下:
1.2.1. 创建内部虚拟交换网络 通过Hyper-V管理器的“虚拟交换机管理器”界面创建一个新的虚拟交换机(假设名字为privateNet,类型为“内部”):
1.2.2. 设置内部使用的虚拟交换机的地址 然后到Windows的“网络连接”里把vEthernet(privateNet)的IP设为固定IP,比如172.16.xxx.xxx。这样设置也决定了172.16.xxx.xxx就是以后虚拟机的网段:(网段根据自己网络环境设置)
1.2.3. 为虚拟机添加新网卡 在虚拟机上新增加一个网卡,加上原来的网卡,虚拟机就有两块网卡。然后将第一块网络适配器的虚拟交换机选为Default Switch,第二块选择前面新建的privateNet:
1.2.4. 虚拟机内设置两块网卡的网络配置 配置eth0 虚拟机启动后编辑/etc/sysconfig/network-scripts/ifcfg-eth0,把BOOTPROTO改为dhcp,ONBOOT改为yes,
BOOTPROTO=dhcp #保持不变 NAME=eth0 DEVICE=eth0 ONBOOT=yes #从no变为yes 配置eth1 注意,如果你是创建虚拟机时就加了一个新网卡,则安装Centos后里面应该已经有/etc/sysconfig/network-scripts/ifcfg-eth1配置文件,如果是安装操作系统之后才新增网卡的,则可以通过以下命令从/etc/sysconfig/network-scripts/ifcfg-eth0拷贝一份修改:
cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth1 修改重点是把BOOTPROTO设成static;把NAME和DEVICE改为eth1;ONBOOT还是yes;记得删除UUID那行(不能和eth0相同)。最后就是加上IPADDR=172.16.xxx.xxx和NETMASK=255.255.xxx.0(注意:IP必须与privateNet一个网段,不需要设置GATEWAY)。
BOOTPROTO=static #删除UUID那行 NAME=eth1 DEVICE=eth1 ONBOOT=yes IPADDR=172.16.xxx.xxx NETMASK=255.255.xxx.0 重启网络:(如果报错就重启虚拟机)
/etc/init.d/network restart 或者 reboot 重启后后就可以从宿主机ssh到该虚拟机了,也可以与其它同网段的虚拟机通讯。
总结 可能还有其它解决方案,但目前是我用过最有效的方法了。
如有其它更好的解决办法,请评论区留言一起探讨!
系列文章目录 利用 eutils 实现自动下载序列文件
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 系列文章目录前言一、获取文献信息二、下载文献PDF文件参考 前言 大家好✨,这里是bio🦖。这次为大家带来自动收集文献信息、批量下载科研论文的脚本(只能批量下载公布在sci-hub上的科研论文)。平常阅读文献时只需要一篇一篇下载即可,并不需要用到批量下载的操作。但有时需要对某领域进行总结或者归纳,就可以考虑使用批量下载咯~
导师下令找文献,学生偷偷抹眼泪。
文献三千挤满屏,只下一篇可不行。
作息紊乱失双休,日夜不分忘寝食。
满腔热血搞科研,一盆冷水当头洛。
(打油诗人作)
一、获取文献信息 每个人的研究领域不一样,获取文献信息的方式不一样。这里以Pubmed1为例,PubMed是主要用于检索MEDLINE数据库中,生命科学和生物医学引用文献及索引的免费搜索引擎。之前爬取冠状病毒核酸数据使用过eutils,本篇博客也使用eutils去获取文献信息,关于eutils的介绍可以看利用 eutils 实现自动下载序列文件 。这里就不做介绍~
首先构造搜索url,其中term是你检索的关键词,year对应文献发表日期,API_KEY能够让你在一秒内的访问次数从3次提升到10次。这里将term替换为Machine learning,year替换为2022。然后使用requests库获取该url的对应的信息,在使用BeautifulSoup库将其转化为html格式。
https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&api_key={API_KEY}&term={term}+{year}[pdat]
代码如下:
import pandas as pd import requests from bs4 import BeautifulSoup import math import re import time API_KEY = "Your AIP KEY" term = "Machine Learning" year = "2022" url_start = f'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&api_key={API_KEY}&term={term}+{year}[pdat]' info_page = BeautifulSoup(requests.get(url_start, timeout=(5, 5)).text, 'html.parser') 爬取的结果如下,可以看到结果主要包括许多PMID。然后包括的信息总数<count>31236</count>、最大返回数<retmax>20</retmax>以及结果开始的序号<retstart>0</retstart>。下一步就是根据id获取文章对应的信息。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE eSearchResult PUBLIC "-//NLM//DTD esearch 20060628//EN"
文章目录 华为eNSP配置专题-路由策略的配置0、概要介绍1、前置环境1.1、宿主机1.2、eNSP模拟器 2、基本环境搭建2.1、终端构成和连接2.2、终端的基本配置 3、配置路由策略3.1、目标3.2、配置路由策略 华为eNSP配置专题-路由策略的配置 0、概要介绍 路由策略就是通过一系列工具或方法对路由进行各种控制,这种策略能够影响到路由的产生、发布、选择等,进而影响报文的转发路径。
1、前置环境 1.1、宿主机 笔记本电脑,配置如下:Windows10企业版,32GB内存
1.2、eNSP模拟器 eNSP1.3.00
2、基本环境搭建 2.1、终端构成和连接 0、总体拓扑如下:
1、在这里路由策略的需求就是,只把R1的lo1和lo2环回口的网络发布给R3,而lo0的网络则不发布出去。
1、2台PC,1台代表总部,1台代表分公司。
2、3台路由器,1台跑RIP,1台跑OSPF,中间1台既跑RIP也跑OSPF
2.2、终端的基本配置 1、配置R1的接口地址、环回口地址,开启RIPv2,将4个网段都宣告出去。
<Huawei>system-view [Huawei]undo info-center enable [Huawei]sysname R1 [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip add 12.1.1.1 30 [R1-GigabitEthernet0/0/0]int lo0 [R1-LoopBack0]ip add 10.1.1.1 24 [R1-LoopBack0]int lo1 [R1-LoopBack1]ip add 10.1.2.1 24 [R1-LoopBack1]int lo3 [R1-LoopBack3]ip add 10.1.3.1 24 [R1-LoopBack3]quit [R1]rip [R1-rip-1]version 2 [R1-rip-1]network 12.0.0.0 [R1-rip-1]network 10.0.0.0 [R1-rip-1]quit 2、配置R2的接口地址,
<Huawei>system-view Enter system view, return user view with Ctrl+Z. [Huawei]undo info-center enable [Huawei]sysname R2 [R2]int g0/0/0 [R2-GigabitEthernet0/0/0]ip add 12.
目录
2.任务Task
2.1 调度Scheduling
2.2基本和扩展任务Basic and Extended Tasks
2.2.1 任务状态Task State
2.2.2 任务优先级Task Priorities
2.2.3 任务队列激活Queued Task Activation
2.2.4 异步任务激活Asynchronous Task Activation
2.3 一致性类Conformance Classes
2.4 最大化性能和最小化内存Maximizing Performance and Minimizing Memory
2.5 任务配置Task Confifiguration
2.5.1 调度策略Scheduling Policy
2.5.2 排队激活Queued Activation
2.5.3 自动启动任务Auto-starting Tasks
2.6 栈管理Stack Management
2.6.1 使用扩展任务Working with Extended Tasks
2.6.2 强制性堆栈信息Mandatory Stack Information
2.6.3 指定任务堆栈分配Specifying Task Stack Allocation
2.6.4 优化扩展任务上下文保存Optimizing the Extended Task context save
2.6.5 处理堆栈溢出Handling Stack Overrun
本篇文章从Glide 4.11源码入手,简单的分析整个图片请求的流程,本着 ”只见树林,不见树木“ 的原则,宏观请求流程,不细究实现细节(细节留坑埋点,之后慢慢写)
引入依赖 以下的所有分析都是基于此版本的Glide分析
//引入第三方库glide implementation 'com.github.bumptech.glide:glide:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' 分析 Glide的使用就是短短的一行代码
Glide.with(this).load("xxx").into(imageView); //拆分成三步 RequestManager with = Glide.with(this); RequestBuilder<Drawable> load = with.load(""); load.into(iv); 首先通过构造Glide的单例对象调用with给每一个RequestManager绑定一个空白的Fragment来管理图片加载的生命周期构建Request对象(真正的实现类SingleRequest)请求之前先检测缓存 先检测活动缓存在检测内存缓存 没有缓存就构建一个新的异步任务检测有没有本地磁盘缓存没有磁盘缓存,就通过网络请求,返回输入流InputStream解析输入流InputStream进行采样压缩,最终拿到Bitmap对象对Bitmap进行转换成Drawble构建磁盘缓存DiskCache构建内存缓存最终回到ImageViewTarget显示图片 with(如何实现生命周期的管控) 调用with方法
public static RequestManager with(@NonNull FragmentActivity activity) { return getRetriever(activity).get(activity); } 会来到RequestManagerRetriever类的get方法中,在这里区分主线程还是在子线程中使用with。
如果在子线程中,绑定的是app的生命周期,在主线程中会将图片的加载与当前activity的生命周期绑定。
这也是为什么不能在子线程中使用Glide的原因,生命周期的管理会失效。
public RequestManager get(@NonNull FragmentActivity activity) { if (Util.isOnBackgroundThread()) { return get(activity.getApplicationContext()); } else { assertNotDestroyed(activity); FragmentManager fm = activity.getSupportFragmentManager(); return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity)); } } 最终会返回一个RequestManager对象。
安装包下载 安装包下载链接: dlib安装包 第一步:找到自己python版本对应的whl文件,例如python3.9,就下载cp39版本的离线安装包。 第二步: 将下载好的whl文件拷贝到python文件夹的Scripts文件夹中,一般路径为:
C:\Users\NL\AppData\Local\Programs\Python\Python310\Scripts
如果实在找不到可以:win+R打开命令提示符,输入where python后回车,即可找到路径
第三步:
在 Scripts文件夹上方搜索栏输入cmd,回车进入命令提示符
第四步:
成功进入 Scripts的命令提示符后,输入pip install +对应whl文件全称,如下图:
按下回车后即可安装成功
最近在学习git高级操作过程中,遇到了一下问题:
我在学习Git合并多个commit为一个的时候,需要输入一个命令
git rebase -i HEAD~2 这说明已经是编辑模式了。当我写好后,我还按照原来在linux上的按下ESC键,但是只是光标跳到了代码上,无法保存退出。我试了很多的键,也到网上搜索了,发现关于Goland操作的非常少,只有IDEA的。于是我就发出来,标题带上Goland,让更多用Go语言的人也能看到。
正确的按键是:CTRL+C
AC代码: #include <stdio.h> int main() { char a; int i,j; scanf("%c",&a); //外循环控制有几层 for(i=1;i<=3;i++) { //第一个内循环控制每层空格个数 for(j=1;j<=3-i;j++) printf(" "); //第二个内循环控制每层字符个数 for(j=1;j<=2*i-1;j++) printf("%c",a); printf("\n"); } return 0; }
AC代码: #include <stdio.h> #include <math.h> int main() { double a,b,c; double p,s; scanf("%lf %lf %lf",&a,&b,&c); // 要判断能不能组成三角形 if(((a+b)>c)&&((a+c)>b)&&((b+c)>a)) { p=1.0/2*(a+b+c); s=sqrt(p*(p-a)*(p-b)*(p-c)); printf("%.1lf",s); } else printf(""); return 0; } a,b,c没有用double时是WA,csdn中有文章表面,用double是为了不丢失精度。
一、背景
今天看代码的时候,发现代码中使用array_map来统一去掉数组中的空格,比起循环来,方便了很多。网上百度一下array_map,然后发现了array_walk。好吧,这两个函数虽然在某些情境下有异曲同工之妙,但是区别还是很大的。
二、关于array_map
1、文档
array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。
回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致。
http://www.w3school.com.cn/php/func_array_map.asp
大家看一下文档,就知道大概的用法了。
//这里可以传递多个数组作为参数,与之对应的,myfunction()函数中也要有多个参数。是一一对应的关系
array_map(myfunction,array1,array2,array3...)
2、例子
public function test_array_map(Request $request)
{
$aa = array('aa', 'bb');
$bb = array_map(function($item) {
$item = $item . 'aa' ;
return $item;
}, $aa);
var_dump($aa);
echo'<br/>';
var_dump($bb);
}
//结果
array(2) { [0]=> string(2) "aa" [1]=> string(2) "bb" }
array(2) { [0]=> string(4) "aaaa" [1]=> string(4) "bbaa" }
此处可以看到,$bb是我们新返回的数组,也是经过我们自己处理过的数组。此时是不会影响到原数组的。
三、array_walk
1、文档
array_walk() 函数对数组中的每个元素应用用户自定义函数。在函数中,数组的键名和键值是参数。
http://www.w3school.com.cn/php/func_array_walk.asp
用法:array_walk(array,myfunction,userdata…)
这里的例子看文档就可以,比较清楚。需要注意的是该函数的返回值是bool值
2、例子:
前言 近些年公司一直采用vue2.x+Element UI进行开发,对于Element UI,由于起步较早,相关的生态一直比较成熟,各种问题在某度上也能找到比较完美的解决方案,最最重要的一点是bug也比较少。
凡是总有个但是:),但是对于Element UI中的Table组件,我个人而言其实不太喜欢的,一是大数据情况下,Table性能堪忧,二是Table组件如果需要展示多行表尾,那是相当的麻烦。尤其是第一点,我相信做报表开发的各位,可能会有比较急迫的需求。
下面针对我个人找到的支持大数据的UI框架进行简单的比较。
大数据UI方案的比较 1. Ant Design Vue 对于React版本的AntDesign,Table组件原生支持虚拟滚动这一特性:https://ant-design.gitee.io/components/table-cn/#components-table-demo-virtual-list。官方文档里的说明是:
通过 react-window 引入虚拟滚动方案,实现 100000 条数据的高性能表格。
而对于Vue版本的AntDesign(文档:https://www.antdv.com/docs/vue/introduce-cn),Table组件功能则比较简陋,并不支持虚拟滚动。
2. Surely Vue 在Ant Design Vue官方文档上,可以看到一个Surely Vue 的推广链接(https://www.surely.cool/),该UI框架上注明是支持百万级别的数据展示。
流畅渲染百万级别数据
横向纵向虚拟滚动
最省心的优化
对于我个人来说,Surely Vue 的Api设计和我当前项目的需求挺符合的,维护人员也有大厂的背景,一开始我是挺倾向于Surely Vue 的。
但是由于目前项目主要采用Vue 2.x开发,而Surely Vue ,目前仅支持Vue 3.x版本,并且无法承诺何时添加对Vue 2.x的支持。另外Surely Vue 需要授权才能使用,这一点对于小公司来说却是一笔不小的开支,遂放弃。
3. umy-ui 官网链接:http://www.umyui.com/。一个典型的个人开发者开发的UI,说是UI,其实目前只开发了表格组件和按钮组件。并且表格组件只是在Element-UI的基础上做了优化:
umy-ui库中的table表格组件,它不造轮子。它改造了element-ui等等库的表格组件。
对于该UI,我想说的是维护人员的出发点是好的,只是功能过于简陋,并且看Git(https://github.com/u-leo/umy-ui)上的更新记录,似乎已经放弃维护了。。。
对于其他一些个人开发的支持大数据表格的UI,似乎都有这样的问题,不展开来说明。
4. vxe-table 官网地址:https://vxetable.cn/。
vxe-table也是几个大牛用爱发电的项目,在码云Gitee上被评为GVP,在Git上也有4.4k的Star,在npm上每个月有55k下载量,算是比较高的热度了。
文档中对于大数据方面的描述是:
虚拟滚动(最大可以支撑 5w 列、30w 行)
vxe-table名称并不带有xxx-ui,且包含了比较常用的组件,像Form、Input、Select、Checkbox等等组件,个人感觉是一个完成度比较高的一个前端框架。
该框架的特点是除了提供一些常用的Api外,另外原生支持一些其他框架中比较少见的功能,比如导入导出、打印、表格筛选等等功能。
目前vxe-table主要维护两个版本3.x以及4.x,其中3.x主要面相于Vue 2.6+,4.x主要面相于Vue 3.x。
对于普通的开发者来说,vxe-table基本上能满足大部分需求,另外对于一些深度使用的用户,vxe-table也通过提供pro版付费插件的形式,额外提供一些比较高级的功能。
5. Ag Grid 官网地址:https://www.ag-grid.com/。
Ag Grid是一个非常优秀且漂亮的表格组件,是市面上难得的同时支持Vue、React、Angular三大框架的。Ag Grid在Git上拥有8K的Star和1.
来源:CCF开源发展委员会
文章目录 华为eNSP配置专题-IPSec的配置0、概要介绍1、前置环境1.1、宿主机1.2、eNSP模拟器 2、基本环境搭建2.1、终端构成和连接2.2、终端的基本配置 3、IPSec的配置3.1、通过ACL定义需要保护的数据流3.2、配置IPSec安全提议3.3、配置IPSec手动方式安全策略3.3.1、在R1上配置3.3.1、在R2(分公司出口路由)上配置 3.4、在接口上应用IPSec策略3.5、更改接口NAT策略3.6、IPSec配置方式二:自动配置 华为eNSP配置专题-IPSec的配置 0、概要介绍 IPSec(Internet Protocol Security):是一组基于网络层的,应用密码学的安全通信协议族。IPSec不是具体指哪个协议,而是一个开放的协议族。IPSec协议的设计目标:是在IPV4和IPV6环境中为网络层流量提供灵活的安全服务。IPSec VPN:是基于IPSec协议族构建的在IP层实现的安全虚拟专用网。通过在数据包中插入一个预定义头部的方式,来保障OSI上层协议数据的安全,主要用于保护TCP、UDP、ICMP和隧道的IP数据包。IPSec架构如下,IKE相当于FTP的21端口,用来SA协商建立IPSec通道。
1、前置环境 1.1、宿主机 笔记本电脑,配置如下:Windows10企业版,32GB内存
1.2、eNSP模拟器 eNSP1.3.00
2、基本环境搭建 2.1、终端构成和连接 0、总体拓扑如下:
1、2台PC,1台代表总部,1台代表分公司。
2、3台路由器,1台为总部的出口路由器,1台为分公司的出口路由器,1台为电信服务商的ISP。
3、启动设备。
2.2、终端的基本配置 1、PC1配置静态IP如下:
2、R1出口路由器配置接口地址、默认路由和NAT
<Huawei>system-view [Huawei]undo info-center enable [Huawei]sysname R1 [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip add 192.168.10.254 24 [R1-GigabitEthernet0/0/0]quit [R1]int g0/0/1 [R1-GigabitEthernet0/0/1]ip add 100.1.1.1 30 [R1-GigabitEthernet0/0/1]quit [R1]ip route-static 0.0.0.0 0 100.1.1.2 [R1]acl 2000 [R1-acl-basic-2000]rule 10 permit source 192.168.10.0 0.0.0.255 [R1-acl-basic-2000]quit [R1]int g0/0/1 [R1-GigabitEthernet0/0/1]nat outbound 2000 3、ISP配置接口地址和环回口地址:
<Huawei>system-view [Huawei]undo info-center enable [Huawei]sysname ISP [ISP]int g0/0/0 [ISP-GigabitEthernet0/0/0]ip add 100.
1.概念
计算机里的数是用二进制表示的,最左边的这一位一般用来表示这个数是正数还是负数,这样的话这个数就是有符号整数(signed integer)。如果最左边这一位不用来表示正负,而是和后面的连在一起表示整数,那么就不能区分这个数是正还是负,就只能是正数,这就是无符号整数(unsigned integer)。
计算机中的整数分为两类:不带符号位的整数(unsigned integer,也称为无符号整数),此类整数一定是正整数;带符号位的整数(signed integer),此类整数可以表示正整数,又可以表示负整数。
简明的说,无符号数就是其所有的位数都用来表示数值的大小,有符号数除最高位来表示数值的正负外(0表示正数;1表示负数),其余各位用来表示数值的大小。
举个例子说明一下:
十机制数 正数255 二进制表达形式:1111 1111
十机制数 负数-1 二进制表达形式:1111 1111 可见-1的二进制的最高位为红色的1,可是为什么其表达形式为1111 1111而不是1000 0001呢?这就关于任何数在计算机内是以补码形式存储问题,下面会介绍的。
2.存储范围
从前面的介绍可以知道,由于有符号数的最高位被拿来用作符号位,所以它所能够表达的最大数值要小于无符号数所能够表达的最大数值。还是举个例子来说明一下吧:
无符号数:1111 1111 十进制值:255
有符号数:0111 1111 十进制值:127
这是有人可能会提出这样的疑问:有符号数所能够表达的数值范围会不会小于无符号数所能够表达的数值范围呢?
答案是否定的!虽然有符号数在表达最大值上的能力减弱了,但是它能够表达负数。负数的个数可以弥补其不足。来让我们比较一下:
一个字节的无符号数的表达数值范围是:[0,255]
一个字节的有符号数的表达数值范围是:[-128,0),[0,127]
可见它们都能够表示256个数。
无符号整数常用于表示地址、索引等正整数,它们可以是8位、16位、32位、64位甚至更多。
8个二进制表示的正整数其取值范围是 0~255( -1)
16位二进制位表示的正整数其取值范围是 0~65535( -1)
32位二进制位表示的正整数其取值范围是 0~ -1
有符号和无符号的差别:
int是有符号的,unsigned是无符号的。
它们所占的字节数其实是一样的,但是有符号的需要安排一个位置来表达我这个数值的符号,因此说它能表示的绝对值就要比无符号的少一半。举个例子,我们有一个1个 [1] 字节的整数(虽然这种类型不存在),那么无符号的就是这样:00000000~11111111 这个就是无符号的范围。
一个字节是8位, 有符号的数,因为第一个位要用来表示符号,那么就只剩下7个位置可以用来表示数了0000000~1111111因为有符号,所以还可以表示范围:-1111 111 ~ +1111 111。
3.各种码(原码/反码/补码)
有些人也许会这样认为"-1"(双字节)在计算机中的表达形式为1000 0000 0000 0001,可是实际上不是的。计算机是以其补码的形式进行表达的,即“-1”(双字节)的表达形式是1111 1111 1111 1111。
说一下各种码的概念吧。
原码:一个整数,按照绝对值的大小转换成二进制数,最高位为符号位。
反码:将原码除最高位(符号位)外,其余各位按位取反,所得到的二进制码。正数的反码为原码。
补码:反码最低位加1即为补码。
关于负数的补码求法说明一下,先得到其反码,之后将反码加1即可。有些大神根据其原码,闭眼即得,这种能力需要修炼一下啊。
这时有些人可能会说,为什么要引入补码的形式呢?直接按照原码存储不就省事很多吗?嘿嘿,要记住,有些事情并不是你想省事就能省事的。好了来欣赏一下补码的优势吧。
1. HTTP有哪些⽅法? HTTP 1.0 标准中,定义了3种请求⽅法:GET、POST、HEAD
HTTP 1.1 标准中,新增了请求⽅法:PUT、PATCH、DELETE、OPTIONS、TRACE、CONNECT
2. 各个HTTP方法的具体作用是什么? 方法功能GET通常⽤于请求服务器发送某些资源POST发送数据给服务器HEAD请求资源的头部信息, 并且这些头部与 HTTP GET ⽅法请求时返回的⼀致。
该请求⽅法的⼀个使⽤场景是在下载⼀个⼤⽂件前先获取其⼤⼩再决定是否要下载, 以此可以节约带宽资源PUT⽤于全量修改⽬标资源 (看接口, 也可以用于添加)DELETE⽤于删除指定的资源OPTIONS⽤于获取⽬的资源所⽀持的通信选项 (跨域请求前, 预检请求, 判断目标是否安全)TRACE该方法会 让服务器 原样返回任意客户端请求的信息内容, 用于诊断和判断CONNECTHTTP/1.1协议中预留给能够将连接改为管道⽅式的代理服务器
(把服务器作为跳板,让服务器代替用户去访问其它网页, 之后把数据原原本本的返回给用户)PATCH⽤于对资源进⾏部分修改 GET POST PUT PATCH DELETE
GET/DELETE 参数是在地址栏中传递的
PUT/PATCH/POST 参数是在请求体传递的
3. GET方法和POST方法有何区别? 默认的http请求的内容, 在网络中传输, 明文的形式传递的 (https 对内容加密)
GET方法POST方法数据传输⽅式通过URL传输数据 (地址栏拼接参数)通过请求体传输数据安全数据暴露在URL中,可通过浏览历史记录、缓存等很容易查到数据信息数据因为在请求主体内,
所以有⼀定的安全性保证数据类型只允许 ASCII 字符⽆限制GET⽆害刷新、后退等浏览器操作是⽆害的可能会引起重复提交表单功能特性安全且幂等(这⾥的安全是指只读特性,就是使⽤这个⽅法不会引起服务器状态变化。
幂等的概念是指同⼀个请求⽅法执⾏多次和仅执⾏⼀次的效果完全相同)⾮安全(会引起服务器端的变化)、⾮幂等 4. HTTP请求报文是什么样的? HTTP 请求报⽂的组成:请求⾏、请求头、(空⾏)、请求体。
实际请求报文实例:
请求行
包含了请求⽅法、URL、HTTP 协议版本,它们之间⽤空格进行分隔。例如:
GET http://www.abc.com/articles HTTP/1.1 请求头
请求头由键值对组成,每⾏⼀对,键值之间⽤英⽂冒号:进行分隔。例如:
Content-Type: application/json Host: www.abc.com 请求体
请求体中放置 POST、PUT、PATCH 等请求方法所需要携带的数据。
原文:
https://zhuanlan.zhihu.com/p/565631049?utm_id=0
速率 比特(bit,记为b)
计算机网络中数据量的基本单位,也是信息论中信息量的单位,一个比特就是二进制数字中的一个1或0
常用数据量单位字节(byte,记为B)、千字节(KB)、兆字节(MB)、吉字节(GB)以及太字节(TB)
换算关系
ps:计算机硬盘厂商采用1×106 b = 1GB的进制,而windows操作系统中的换算公式是230 b = 1GB,两种字节的换算方式不同,使得容量在计算上相差了7.3%,所以常有Windows系统报告的容量比硬盘标示的容量还要小的情况发生。但在苹果公司的OS X操作系统中,对于存储设备的容量计算方式与硬盘厂商一致,均为1GB = 1×106 b 的十进制,避免了计算和使用上的麻烦。
速率
速率是指数据的传送速率(即每秒传送多少个比特),也称为数据率(Data Rate)或比特率(Bit Rate)。
速率的基本单位是比特/秒(bit/s,可简记为b/s,有时也记为bps。即bit per second)。速率的常用单位有千比特/s秒(kb/s或kbps)、兆比特/秒(Mb/s或Mbps)、吉比特/秒(Gb/s或Gbps)以及太比特/秒(Tb/s或Tbps)。
换算关系 大b与小B 带宽 线路的频率带宽越宽,其传输的最高数据率(传送速率)也越高
带宽在模拟信号系统中的意义
某个信号所包含的各种不同频率成分所占据的频率范围
单位:Hz(kHz、MHz、GHz)
带宽在计算机网络中的意义
用来表示网络的通信线路所能传送数据的能力,记载单位时间从网络的某一点到另一点所能通过的最高数据率
单位:b/s(kb/s、Mb/s、Gb/s、Tb/s)
速率匹配 数据传送速率 = min[主机接口速率、线路带宽、交换机或路由器的接口速率]
吞吐量
吞吐量是指在单位时间内通过某个网络或接口的实际数据量。吞吐量常被用于对实际网络的测量,以便获知到底有多少数据量通过了网络。
吞吐量手网络带宽的限制
时延
时延是指数据从网络的一端传送到另一端所耗费的时间,也称为延迟或迟延。数据可由一个或多个分组、甚至是一个比特构成。
分类
发送时延
源主机将分组发往传输线路,这需要花费一定的时间,这段时间称为发送时延
计算公式:发送时延 = 分组长度(b)/发送速率(b/s)
发送速率应注意速率匹配问题(数据传送速率 = min[主机接口速率、线路带宽、交换机或路由器的接口速率])
传播时延
代表分组的电信号在链路上传播,需要一定的时间,这段时间称为传播时延
计算公式:传播时延 = 信道长度(m)/信号传播速率(m/s)
要注意传输媒体,不同的传输介质,电磁波的传播速率不同
自由空间:3.0×108m/s
铜 线:2.3×108m/s
光 纤:2.0×108m/s
使用光纤作为传输介质会给我们的上网感受就是快,但并不是因为光纤的传播速率快,而是因为光纤的带宽很大,所能承载的最高数据传送速率很大,单位时间内可传输更多的比特。
排队时延
分组进入路由器后,会在路由器的输入队列中排队缓存并等待处理,在路由器确定了转发接口后,分组会在输出队列中排队缓存并等待转发,分组在路由器的输入队列和输出队列中排队缓存所耗费的时间就是排队时延。
在分组从源主机传送到目的主机的过程中,分组往往要经过多个路由器的转发,分组在每个路由器上产生的排队时延的长短往往取决于网络当时的通信量和各路由器的自身性能,由于网络的通信量随时间变化很大,各路由器的性能也不完全相同,因此排队时延往往无法用一个简单的公式进行计算。
题解 | #实现四舍五入#
#include <iostream>using namespace std;int main() { float number; ci
武汉农业银行研发中心面试
10.24农研一面,坐两小时车跑去面试难顶。面试是群面,每个人一个编号,然后回答问题每个人自我介绍给一份考卷,每个人八分钟写回答,然后每个人进行回答问每个人一个
秋招互联网末尾总结,多益已录用
海投一百多家,有面试的有中金所(一面挂,没准备好),多益(已录用),海能达(垃圾群面)等。笔试挂了挺多的:去哪儿,掌阅,美团,funplus,58,华勤,耀乘健
题解 | #编程题1#
#解方程的思想:若想打平需满足#1)总场数是3的倍数n%3==0 #2) 差距超过1/3则无法追平比分#3)每场比赛得分最多的不得超过总场数的1/3 #4)
题解 | #明明的随机数#
import java.util.Scanner;import java.util.List;import java.util.ArrayList;import
C++多继承中的内存布局(2)
接上文,还是先看一个例子:struct base { int value = 99;};struct offset { char space[10] =
题解 | #素数伴侣#
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息public class Main klook客路
有收到二面的家人吗,10.22中午面的
招行苏分1面
金融科技,不是群面,线上大概十分钟左右自我介绍可以接受转用户研究吗(和客户对接)接受地点调剂吗根据简历问了一两个问题稍后我们的终面通知会以短信的形式发出
和利时能不能给我发个面试😭😭,投了的
和利时能不能给我发个面试😭😭,投了的好多公司都没动静🙃
快要签三方了,鼠鼠手里有这几个offer
快要签三方了,鼠鼠手里有这几个offer,很犹豫要不要签一个,感觉秋招快结束了,拜托各位佬给给意见哈~#阿里 腾讯 美团 字节 快手 京东 oppo 华为 荣耀
一、逆向mysql数据库 官网下载mysql的ODBC(开放数据库互连)
选择自己对应版本,我的power designer是32位的,需要选择32的ODBC进行下载,不然power designer会监测不到。
双击exe文件,安装ODBC
这个比较简单,就不阐述了配置ODBC
控制面板=》系统与安全=》管理工具=》ODBC数据源(32位)
用户DSN=》添加
输入自己的数据库信息,连接成功即可power designer逆向工程
连接即可,确定即开始逆向! 二、逆向pg数据库 同理
附pg数据库ODBC下载地址
mysql --version
1.redis目录
./bin/redis-server ./redis.conf
2.redis/bin目录
./redis-server .././redis.conf
Python 问世至今已经三十三年左右了,但其仅在过去几年人气迅速飙升超过了除 java 和 C 以外的其他语言。总的来说,Python 已经成为教学、学习编程和软件开发的优秀起点,而且其可以成为任何技术栈中有价值的一部分。
不幸的是,这样的流行程度也会暴露 Python 的缺点,最显著且众所周知的缺点是这三个:运算性能、打包及可执行程序的生成、项目管理
虽然这三个缺点都不是非常致命,但是和其他处于上升通道的语言如 Julia、Nim、Rust 和 Go 相比,Python 的劣势将越来越明显。
下面给大家讲讲 Python 程序员面临的这三个缺点,以及 Python 与其第三方工具开发人员提出的解决这些缺点的方法。
缺点一:Python 多线程和速度 Python 整体性能缓慢,有限的线程和多处理能力是其未来发展的主要障碍。
Python 长期以来一直重视编程的易用性而不是运行时的速度。当通过使用 C 或 C++ 编写的高速外部库(如 Numpy 和 Numba)在 Python 中完成如此多的性能密集型任务时,你会发现 Python 重视编程的易用性也是一种不错的选择。但是尽管如此,Python 的开箱即用的性能速度依然落后于其他语言,比如说具有同样简单语法的 Nim 和 Julia,却可以被编译为机器代码,具有更高的性能优势。
Python 无法全面利用多核处理器是其长久以来的问题,它确实具有线程功能,但它的线程功能是局限于单个核心的。虽然 Python 可以使用多进程,但是调度和同步这些子进程的结果并不总是有效的
解决方案 目前没有单一,自上而下的整体解决方案来解决 Python 的性能问题,不过我们有一系列加速 Python 的举措。比如说:
使用 PyPy 解释器替代官方解释器,PyPy 能够将 Python 代码编译成机器代码,它在仅仅使用 Python 自带的模块的代码中效果最好,不过现在也可以适用于如 numpy 这样的流行的库,但是其始终只适合于长期运行的服务,而不是能打包带走的应用程序。Cython,Cython 能将 Python+C 混合编码的.pyx 脚本转化为 C 代码。该项目最初是为科学和数值计算而设计的,但它可以在大多数情况下使用。Numba,Numba 和 Cython 类似,主要用于科学计算。Mypyc,是现在仍在开发的项目,它会将用 mypyc 类型装饰器装饰的代码转化为 C.
求解器用的是分支定界框架,准确的说用的是分支切割算法,在分支定界的框架中不断自动添加各种割cut,直到“所有”节点探测完毕。
gap体现了目前求解的状态,直观的说,gap=(上界-下界)*100%/上界(min问题)。更一般的表述是:(当前最好解-bound)*100%/bound。
从公式上可以看出,当gap下降很快,要么是上界在降低(更好的整数解),要么是下界在提升(更好的下界)。
回到一开始的问题,当gap没有太大的变化(找不到更好的解,bound改进比较慢)时,我们的方法也是从上述公式入手,要么想办法找到更好的可行解,要么想办法提升bound。具体的说,有以下几个思路可以着手:
1.考虑为什么找不到更好的整数可行解(上界)?
要么是模型特别复杂,求解器的数学启发式无法找到更好的可行解。>>>尝试启发式算法输入一个比较好的可行解;
或者是,目前解已经是最优可行解,但是optimality proof没完成,因为下界不改进了。(这个没办法,分支定界必须探索完所有节点)。
2.考虑为什么下界不改进了?
这个问题,一般是模型比较松弛,不够紧。LP的解距离整数解差距比较大,因此迭代缓慢。>>>改写模型;
另外就是分支切割算法无法找到新的有效的cut以进一步收紧下界。>>>尝试添加cut;
还有就是,模型复杂,分支后分支定界树极其不平衡。>>>尝试不同的探索策略,广度,深度,或混合策略。
注:
当问题求解很快,反应在求解器的输出日志上体现在两方面,一个是需要探测的节点在减少;一个是gap在不断下降,甚至下降的很快。前者是探测节点很快,节点所在的支被切掉(整数解,更差的非整数解,或不可行三种情形之一),此时求解会很快,反应在求解器的输出日志上就是,需要备探测的节点在减少。后者是gap下降很快,这种情况要么是找到了更好的上界,更小的整数解(最小化问题),要么是更好的下界,这种情况的本质是前者的探测节点在减少,砍掉了更多的枝。
猜数字游戏要求: 1.创建一个menu函数,实现菜单选项,选择0表示退出游戏,选择1表示开始游戏(即可以连续多次游玩猜数字游戏)
2.系统随机产生一个1-100的数字,要求每次产生的随机数不一样
3.只允许猜5次及5次以下,超过5次则为失败
注意点: 1.怎么生成随机数? C语言提供了一个函数 rand,用于产生随机数
函数原型:
int rand ( void ); 使用该函数需要使用库函数:<stdlib.h>
该函数会生成一个伪随机数,范围是在0~RAND_MAX之间,RAND_MAX的⼤⼩是 依赖编译器上实现的,但是⼤部分编译器上是32767。
出现问题: 因为rand函数生成的是伪随机数,默认的种子是1,直接使用每次生成的随机数其实是确定的,我们需要做以下事情来实现真正的生成随机数:
1.改变种子的值,使得每次游玩的种子值不一样,这样每次生成的随机数也不一样
2.每次改变的种子值和之前不相同,若相同,那和默认种子为1没区别,只是把1变成了2or3or其他数字。
解决方法: C语言中的srand函数,用于改变种子值
函数原型:
void srand ( unsigned int seed); 如何使得每次种子值都不一样?
现实生活中时间在不断变化,我们可以根据时间的变化来生成种子值,从而改变rand函数生成的随机值。
C语言中的time函数,可以获取时间
函数原型:
time_t time ( time_t * timer); time 函数会返回当前的⽇历时间,其实返回的是1970年1⽉1⽇0时0分0秒到现在程序运⾏时间之间的 差值,单位是秒。 返回的类型是time_t类型,time_t 类型本质上其实就是32位或者64位的整型类型。 如果 timer 是NULL,就只返回这个时间的差值。time函数返回的这个时间差也被叫做: 时间戳 使用该函数需要使用头文件:<time.h> 因此使得rand函数实现真正的随机值的代码如下:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(){ //srand要求函数类型为unsigned int类型,但是time函数的返回类型为time_t类型,因此需要强制转换 srand((unsigned int)time(NULL)); printf("%d\n",rand()); return 0; } 2.怎么使得生成的随机数在1-100之间? 在刚刚的代码中,每次生成的随机数位数都不一样,因为我们需要进行运算将随机数控制在1-100之间。
很久没更新,我又变强了!!!
1.下载了Xshell和xftp安装后打开发现需要最新版本,妈呀,我就是最新版本啊。
2.尝试把本机时间修改为2022年01月01日,(应该没有人在2021年12月31日看这篇文章的吧)。
咦咦咦咦咦~~ 发现可以顺利开~~,但是,系统时间不对,会导致其他问题出现,可不行!!
3.来来来,直接写脚本了,先改时间,在打开,在恢复时间,搞定!!!
创建一个文本文件,在把后缀.txt改为.bat。
注意:这里有些小白的电脑是看不到文件后缀的,请先随便打开一个盘,找到【选项】-【查看】-【高级设置】把下图中关闭
脚本内容如下:
## 修改系统时间为你可以打开xShell的时间 date 2019-01-01 ## 打开xShell start /d "D:\KaiTong\tools\Xftp\" Xftp.exe ## 等待3s,不等待的话,xshell没启动就已经恢复时间了,所以这里要等待几秒,看你的电脑响应速度来调整 ## 你的电脑足够快!都可以不用下面这一句!!! TIMEOUT /T 3 ## 自动同步系统时间 net start w32time w32tm /config /update w32tm /resync /rediscover net stop w32time ## 系统时间没有恢复,建议加上等待1秒 ## TIMEOUT /T 1 ## 自动退出可加,可不加,看你喜好,一般都会加 exit 这一句,请替换自己的程序安装路径: start /d "D:\KaiTong\tools\Xftp\" Xftp.exe
启动不了你来打我~~
@RequestParam、@PathVariable 和 @RequestBody 是 Spring 框架中用于处理 HTTP 请求参数的不同注解,它们之间的主要区别在于参数的来源和传递方式:
@RequestParam: 这个注解用于从请求的查询参数中获取数据,通常是通过?key=value形式添加到URL中的参数。
例如,在以下URL中,courseId和userId是查询参数:
http://example.com/api/someEndpoint?courseId=7&userId=1 在方法参数中使用@RequestParam注解,可以将查询参数的值提取到方法中:
@GetMapping("/someEndpoint") public JsonResponse someEndpoint(@RequestParam(name = "courseId") String courseId, @RequestParam(name = "userId") String userId) { // 处理 courseId 和 userId 参数 } @PathVariable: 这个注解用于从请求的URL路径中提取参数,通常是作为路径的一部分,例如:
http://example.com/api/someEndpoint/7/1 在方法参数中使用@PathVariable注解,可以从URL路径中提取这些参数的值:
@GetMapping("/someEndpoint/{courseId}/{userId}") public JsonResponse someEndpoint(@PathVariable(name = "courseId") String courseId, @PathVariable(name = "userId") String userId) { // 处理 courseId 和 userId 参数 @RequestBody: 这个注解用于接收请求体中的数据,通常是 JSON 或 XML 格式的数据。它通常用于处理 POST 或 PUT 请求中的请求体数据。
例如:
引入了模块依赖还是有这个问题
加上mybatisplus的依赖解决
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.4.3.4</version> </dependency>
0、引言 如果你已经开发了一个中型或者大型的 .NET / .NET Framework 项目但还没有为其添加日志系统。那么,你可能需要重新回顾大量的业务逻辑代码,并在其中找到合适的位置,编写合适的日志输出语句进行插入🙁。
显然,这是一个非常耗时且麻烦的工作,并且会对业务逻辑代码产生大量改动,造成代码的可读性变差。好在,我们可以利用面向切面编程(AOP)这一编程范式😀。在不修改现有代码的基础上,通过添加行为(Advice)来解决横切关注点;将通用功能(比如日志记录)从业务逻辑中抽离出来,使得我们能够专注于业务逻辑本身。
如果您不是很了解 AOP,那么以下的链接将会很有帮助:
Aspect-oriented programming细说Spring——AOP详解(AOP概览)Spring AOP(一) AOP基本概念面向对象困境之 —— 横切关注点Aspect Oriented ProgrammingWhat is Aspect-Oriented Programming (AOP)?AOP简单介绍 1、.NET 平台下的 AOP 实现 有非常多的编程语言都实现了 AOP,您可以在这里查看比较详细的列表。但我们的项目是基于 .NET / .NET Framework 的,使用的日志框架也是 log4net,所以我们重点关注 .NET 平台下的 AOP 框架:
名称logo描述PostSharp.ilPostSharp 旗下商业产品,一个基于 MSIL 的 .NET 下的面向切面框架,拥有功能受限的免费版本。MetalamaPostSharp 旗下商业产品,一个 C# 中用于简洁代码的框架,拥有功能受限的免费版本。(MSDN 上提供了 Metalama 的教程)Castle DynamicProxy一个用于在运行时动态生成轻量级 .NET 代理的库。代理对象允许在不修改类代码的情况下拦截对对象成员的调用。类和接口都可以被代理,但是只有虚成员可以被拦截。许多其他框架(如 Spring.NET、AspectCore-Framework 等)都内部使用了 Castle DynamicProxy 来提供 AOP 功能。Spring.NET一个全功能的 .NET 应用程序框架,不仅提供了依赖注入和面向切面编程(AOP),还提供了数据访问抽象、ASP.NET 集成等功能(更多详细介绍)。AspectCore-FrameworkAspectCore 是一个面向 .NET Core 和 .NET Framework 的基于 AOP 的跨平台框架。Core 支持切面拦截器、依赖注入集成、Web 应用程序、数据验证等。 以上都是最近仍有更新的项目;如果您想要了解还有哪些更多 .
背景 日常生活中,每天都要用到日历,日历成为我们生活中的必需品,那么如何制作日历呢,其实方法有很多,可以直接在excel中制作,也可以手画等等。
学习过编程的朋友,能否想到用Python编写一个日历呢??Python可谓是功能强大,只有你想不到,没有python做不到,,,Python标准库中的calendar模块就可以做到这件事。
实现 输出某月日历 下面是一个简单的示例,显示当前月份的日历:
import calendar
year = int(input("请输入年份: "))
month = int(input("请输入月份: "))
#year = 2023
#month = 10
#打印某个月的日历
print(calendar.month(year,month))
运行结果如下:
输出某年日历 上面的代码使用了calendar.month()函数,它会返回一个字符串,表示指定年份和月份的日历。我们也可以使用calendar.calendar()函数来打印一个完整的年历。
以下是一个打印当前年份的完整年历的示例代码:
import calendar
year = int(input("请输入年份: "))
month = int(input("请输入月份: "))
#year = 2023
#month = 10
#打印某个月的日历
#print(calendar.month(year,month))
# 打印年历
print(calendar.calendar(year))
运行结果如下:
设置周日为第一天 可以看到上面日历是以星期一为第一天,calendar还提供了设置一周内的某一天为第一天的函数,请看以下示例(以周日为第一天):
import calendar
year = int(input("请输入年份: "))
month = int(input("请输入月份: "))
#year = 2023
#month = 10
#打印某个月的日历
背景 日历是一种常见的工具,用于记录事件和显示日期。在编程中,可以使用Python编码来制作日历。
Python提供了一些内置的模块和函数,使得制作日历变得更加简单。
在本文,我们将探讨如何使用Python制作日历,并将日历输出到excel文档中。
效果展示 实现 在代码中会用到calendar模块和openpyxl模块,其中calendar模块是python自带的,而openpyxl模块需要自行下载“pip install openpyxl”。
import calendar
import openpyxl
from openpyxl.styles import Alignment, PatternFill, Font
from openpyxl.utils import get_column_letter
from openpyxl.drawing.image import Image
from openpyxl.styles import Side, Border
#year = int(input(“请输入年份:”))
#calendar.setfirstweekday(firstweekday=6)
###设置表头所在起始行
table_head_row = 3
##设置表内容所在起始行
table_comment_row = table_head_row + 1
# 创建一个工作䈬
wb = openpyxl.Workbook()
# 遍历12个月
for i in range(1, 13):
# 添加工作表
sheet = wb.create_sheet(index=0, title=str(i) + '月')
# 获取具体日期时间,设置表内容
for j in range(len(calendar.
为什么要使用并发编程 提高程序的响应性:通过并发编程,可以将程序的任务分成多个子任务并行执行,使得程序能够更快地响应用户的请求。特别是在处理大量并发请求的情况下,使用并发编程可以避免阻塞和延迟,提高系统的吞吐量和响应速度。
充分利用多核处理器:并发编程可以将任务分配到不同的核心上并行执行,充分利用多核处理器的计算能力,提高程序的运行效率。解决资源竞争问题:在多线程环境下,各个线程可能会同时访问共享资源,导致资源竞争的问题。并发编程提供了各种同步机制和数据结构,如锁、信号量和并发容器等,可以有效地解决资源竞争问题,确保线程安全。
提高系统的可伸缩性:并发编程可以将任务分布到多个线程上,并行执行,从而提高系统的处理能力。当需求增加时,可以通过增加线程数来扩展系统的处理能力,实现系统的可伸缩性。
改善用户体验:并发编程可以使程序在执行耗时任务的同时,保持界面的响应,加快响应速度,让用户体验更好。
多线程应用场景 当需要同时处理多个任务时,可以使用多线程来并发执行这些任务,提高处理效率。
例如tomcat或jetty中,每个客户端请求可以使用一个线程来处理,同时处理多个客户端的请求。在需要执行一些耗时的操作时(如网络请求、文件读写等IO操作),可以将这些操作放在后台线程中执行,以避免阻塞主线程。在需要对大量数据进行处理时,可以将数据分成多个部分,使用多线程并行处理,提高处理速度。例如,在数据分析和图像处理领域,多线程可以加速对数据的处理和计算。 多线程可以在各种需要同时处理多个任务、提高并发性能、改善用户体验等方面发挥作用。
Java 程序中怎么保证多线程的运行安全? 使用同步机制:Java提供了synchronized关键字和锁机制,可以用来保证多个线程对共享资源的互斥访问。通过在关键代码块或方法上添加synchronized关键字,可以确保同一时间只有一个线程可以执行该代码块或方法。这样可以避免多个线程同时修改共享资源而导致的数据不一致问题。
使用并发容器:Java提供了一些线程安全的并发容器,如ConcurrentHashMap、ConcurrentLinkedQueue等。这些容器在内部实现上采用了锁机制或并发算法,可以保证多线程对容器的操作是安全的。
使用原子类:Java提供了一些原子类,如AtomicInteger、AtomicLong等,它们提供了一些原子操作,可以在不使用锁的情况下实现线程安全。这些原子类的操作是原子的、非阻塞的,可以确保多线程环境下的数据一致性。
使用volatile关键字:volatile关键字可以保证被修饰的变量在多线程环境下的可见性和禁止重排序。当一个变量被声明为volatile时,对该变量的读写操作都会直接读写主内存,而不会使用线程的工作内存,从而避免了数据不一致的问题。
使用线程安全的类:在Java的标准库中,有一些线程安全的类,如StringBuffer、Vector等,它们在内部实现上采用了同步机制,可以安全地在多线程环境中使用。
并行和并发有什么区别? 并行和并发是计算机领域中常用的两个概念,它们描述了任务执行的不同方式。下面是它们的区别:
并行(Parallelism):指的是同时执行多个任务或多个子任务,通过利用多个处理单元(如多核处理器或分布式系统)来实现任务的并行执行。在并行执行中,多个任务或子任务可以同时进行,每个任务占用一个独立的处理单元,它们之间相互独立且不会相互干扰。并行旨在通过同时处理多个任务来提高计算速度和效率。
并发(Concurrency):指的是在同一时间段内执行多个任务或多个子任务,通过任务的快速切换来实现多个任务的交替执行。在并发执行中,多个任务或子任务在时间上可能有重叠,它们通过共享的资源来交替执行,每个任务会分配一段时间片进行执行,然后切换到下一个任务。并发旨在提高系统的资源利用率、增加同时处理的能力。
执行方式:并行是同时执行多个任务,每个任务占用独立的处理单元;而并发是在同一时间段内交替执行多个任务,任务之间共享资源。
原理:并行通过利用多个处理单元来实现,每个任务可以并行执行;而并发通过任务的快速切换来实现,多个任务在时间上可能有重叠。
目标:并行旨在提高计算速度和效率;而并发旨在提高资源利用率和同时处理的能力。
并行和并发并不是互斥的概念,它们可以同时存在。例如,在多核处理器上可以同时执行多个任务(并行),而每个任务内部可能也存在多线程的并发操作。
什么是多线程? 多线程(Multithreading)是指在一个程序中同时执行多个线程,每个线程都是独立的执行路径。多线程允许程序在同一时间内执行多个任务,提高程序的并发性和响应性。
在传统的单线程编程中,程序按照顺序执行,每个任务按照固定的顺序一个接一个地执行。而多线程编程可以将程序拆分成多个独立的执行单元(线程),每个线程可以并行执行不同的任务,互不干扰。
多线程的优点包括:
提高程序的性能和效率:通过多线程并行执行多个任务,可以充分利用多核处理器的计算能力,提高程序的运行效率。
改善用户体验:多线程可以保持界面的响应性,将耗时的操作放在后台线程中执行,避免阻塞主线程,提供更好的用户体验。
提高系统的可伸缩性:通过增加线程数来扩展系统的处理能力,实现系统的可伸缩性,适应不同的工作负载。
解决资源竞争问题:多线程编程提供了同步机制,可以解决多个线程之间对共享资源的竞争问题,确保线程安全。
然而,多线程编程也带来了一些挑战,如线程同步、死锁、竞态条件等问题,需要谨慎设计和处理。此外,多线程编程还需要考虑线程间的通信和协调,确保各个线程能够正确地协同工作。
最近很多小伙伴,让我帮忙找一套 Java 学习资料,于是我翻遍了收藏的 1024G 资料,找到一套华为工程师总结的 Java 笔记,可以说是 Java 程序员必备!
整个资料包内容专注 Java 技术,包括 Spring、Spring Boot/Cloud、Dubbo、JVM、集合、多线程、JPA、MyBatis、MySQL、大数据、Nginx、Git、Docker、GitHub、Servlet、JavaWeb、IDEA、Redis、算法、面试题等几乎覆盖了 Java 基础和进阶的方方面面,非常适合初学者入门和进阶者巩固知识!
据说已经有小伙伴通过这套资料,成功的入职了蚂蚁金服、今日头条等大厂。而且,这些资料不是扫描版的,里面的文字都可以直接复制,非常便于我们学习!
我放在这里,CSDN免积分下载:
https://download.csdn.net/download/weixin_42116348/88439145
合并数组 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
pip install模块时报错Microsoft Visual C++ 14.0 is required。
尝试过的解决方案:
1、下载visualcppbuildtools_full.exe,但是打开后提示安装包损坏。
2、直接下载Microsoft Build Tools for Visual Studio 2019 Build Tools,安装MSVC v142 和 Windows 10 SDK,重启电脑后依然提示Microsoft Visual C++ 14.0 is required
成功的解决方案:
下载离线安装包(2选1即可):
1、百度网盘链接: https://pan.baidu.com/s/1vqdf81LBrx-lal154kyU7Q 提取码: yef7 2、超星云盘免登录高速下载链接(分为2卷,都要下载,下载后要放在一个文件夹):1卷:msbulidtools.z01,主卷:msbulidtools.zipp
下载后将msbulidtools.zipp后缀改为zip,解压后双击VisualCppBuildTools_Full.exe即可成功安装。
目录
一、绝对路径
二、相对路径
一、绝对路径 绝对路径是从”/”目录开始的,“/”也称为根目录。
二、相对路径 相对路径一般是以“.”或者“../”或者“../../”开头的路径,或者路径前没有”/”。表示在相对于用户的“当前路径”的目录位置。
目录
一、Linux下文件权限的描述
二、修改权限的命令
三、举例说明
一、Linux下文件权限的描述 每一个权限位描述了所有者、所属组以及其它人对文件的读、写和执行
的权限。这三类每一个对应3 个位,共9 位。
linux权限表,后面写代码的时候,常常以数字组合表示文件的权限。
二、修改权限的命令 通过chmod +xxx 文件名方式修改文件权限。
三、举例说明
目录
一、用户
1.超级用户
2.创建用户
3.查看用户
4.删除用户 5.Linux用户的组织
二、用户组
1.Linux用户组介绍
2.添加组
3.查看组
4.删除组
一、用户 1.超级用户 通过su root命令并输入密码进入超级用户内
2.创建用户 通过useradd xunwei命令创建用户
3.查看用户 通过cat /etc/passwd命令查看用户
4.删除用户 通过userdel xunwei删除用户
注意: 最好不要用系统自带的用户;最小系统下没有命令。
5.Linux用户的组织 通过more /etc/passwd命令查看用户的组织
二、用户组 1.Linux用户组介绍 Linux 中的组与Windows 中的组很类似。可以创建一个组然后将成员添加到这个组的列表中。可以以组为单位来分配资源。隶属于同-个组的成员可以访问同一资源。
2.添加组 使用groupadd mygroup命令添加组
3.查看组 使用cat /etc/group命令来查看组
4.删除组 使用groupdel mygroup命令来删除组
GB/T28181协议介绍 文章目录 GB/T28181协议介绍总体介绍GB/T28181基本结构GB/T28181关键协议流程设备注册设备目录查询实时视频播放流程 GB/T28181协议总结 说到GB/T28181协议,如果你是从事视频监控领域的工作,那对他一定不陌生,在公共安全、城市治理、政务监管、企事业监管等涉及视频汇聚、视频监控等场景,它已经是视频终端设备、监控平台必须支持的视频协议,可以说是视频监控界的头号玩家,用来规定视频监控系统如何传输、交换和控制信息。本文主要对协议基础知识进行介绍,后续会专门从视频流的角度写一篇文章,详细介绍GB/T28181协议如何进行视频流协议申请、流封装和传输的。 总体介绍 GB/T28181协议,全名叫《安全防范视频监控联网系统信息传输、交换、控制技术要求》,是由中国国家标准委员会发布的一种国家级的标准。它主要对视频监控系统的各个方面做了明确的规定,使得不同厂商生产的视频监控设备能够相互连通,信息共享,提高整个监控系统的效率和可靠性。28181协议从2011年发行第一个版本以来已经连续迭代了3个版本,最新发布版本为GB/T28181-2016,最新的协议文档可通过点击文末的阅读原文获取。在公安、政府、企事业单位等视频监控类项目中,28181协议基本是IPC、NVR、平台、视频边界网关必须支持的流媒体协议。
28181协议包含设备注册、实时音视频点播、设备控制、报警时间通知和分发、设备信息查询、状态信息报送、历史音视频文件检索、历史音视频文件回放和下载、网络校时、订阅和通知、语音对讲和语音广播等内容,具体详细介绍可参考《GB/T28181-2016 安全防范视频监控联网系统信息传输、交换、控制技术要求》,规范文档可关注公众号:壹零仓,发送:协议规范,获取。本文主要介绍下28181基本结构、关键协议流程及应用场景介绍。
GB/T28181基本结构 28181协议基本结构如下如所示:
28181协议包含终端侧协议和平台侧协议,终端侧包含IPC、NVR等终端设备,平台侧包含NVR、视频平台、网闸等。IPC通过28181协议接入视频监控平台或NVR;NVR可向下接入IPC,向上接入视频监控平台;GB28181支持多级级联,因此视频监控平台之间可通过28181协议级联,实现协议交换和视频传输。这里视频网闸作为网络安全边界,在公安跨网传输时作为安全网络区域与非安全网络区域之间的网络隔离设施,支持28181的协议通道,因此上下级视频监控平台可直接通过28181协议实现跨网闸通信。
28181协议结构如下图所示:
协议包含两个通道会话通道和媒体流通道,会话通道包含信令交互、视频会话,主要基于sip进行扩展,流媒体通道通过RTP/RTCP进行传输,其中传输层协议最新版本28181规范已经可以支持TCP和UDP两种方式。下面对信令交互、音视频会话、音视频传输三种类型的协议进行介绍:
信令交互:信令交互协议是28181协议的基础,其在sip协议的基础上进行了扩展,扩展协议IETF RFC3428规定的MESSAGE方法实现,协议体为xml格式。主要的SIP消息有注册、心跳、设备搜索、设备状态查询、设备控制等。音视频会话:包含视频预览和视频回放,视频预览采用sip的INVITE、ACK、BYE方法实现,媒体协议通过SDP协议来携带;视频回放采用SIP INVITE实现会话连接,擦用SIP INFO方法实现回放命令控制,控制协议命令引用MANSRTSP的PLAY、PARUSE、TREADOWN等命令。音视频传输:通过视频会话建立视频传输通道后,通过RTP/RTCP进行视频传输,传输的音视频封包方式为PS流,有关PS流封装方式详解,关注公众号:壹零仓,发送:ps,获取相关文章。 GB/T28181关键协议流程 本文主要介绍关键的协议流程,包含设备注册、设备目录查询、视频播放等流程,要通过28181协议实现流媒体协议的交互,这几个协议流程是绕不开的,有关28181视频流交互的详细解析,后续会单独写一篇文章来介绍。
设备注册 这里以IPC向视频平台注册为例,设备注册流程如下:
IPC向视频平台发起Register注册请求,携带设备信息。视频平台收到注册请求后,判断是否携带认证信息,如果未携带,则返回401,鉴权失败。IPC根据平台鉴权的要求,携带Anthorization认证信息,重新发起注册请求。平台对认证信息进行认证,认证通过后,返回200,注册成功。 这里要注意鉴权方式,平台回复401时会携带WWW-Authenticate头字段,此字段包含平台支持的鉴权方式,一般方式有basic、digest等。IPC需要根据平台支持的鉴权方式进行认证信息的封装。
设备目录查询 设备目录查询主要查询设备/下级平台的目录结构,通过查询目录结构之后获取设备摄像头列表信息,通过摄像头列表信息,平台才可选择摄像头进行摄像头视频播放等操作,28181所有信令操作流程基本类似,了解了此协议流程,其他信令交互可参照。
28181信令交互采用异步交互的方式,请求消息和响应消息异步进行。
1.平台向IPC发起目录查询请求(catlog),携带查询设备ID。
2.设备直接返回200 OK,不携带响应
3.设备向平台发送目录查询响应信息,携带设备目录信息
4.平台接收响应信息,返回200 OK
实时视频播放流程 视频播放采用SIP IETF RFC 3216规定的INVITE、ACK、BYE方法,还是以视频平台向IPC申请视频为例,来说明28181视频播放流程:
视频平台向IPC发起INVITE请求,SDP携带视频播放信息。IPC收到INVITE请求后,根据SDP携带的信息,进行视频流推送准备,返回响应信息,携带SDP音视频描述信息。视频平台收到响应信息后,根据SDP音视频描述信息,进行视频流接收准备并返送ACK到IPC。IPC收到ACK后,进行音视频流推送,音视频流封装为PS格式,并通过RTP/RTCP传输。 GB/T28181协议总结 GB/T 28181协议的应用可以说是无处不在,比如公共安全、城市管理、企事业等监控领域都有它的身影。接下来我们就来聊聊它的应用场景。
GB/T 28181协议作为公共安全领域中的重要标准之一,规范了视频监控联网系统的信息传输、交换和控制,提高了不同厂商生产的视频监控设备的互联互通性和信息共享性。它不仅在公共安全领域中发挥着重要作用,也在智能家居、企业应用和城市管理等领域有着广泛的应用。通过遵循GB/T 28181协议的规定,我们可以有效地提高视频监控系统的可靠性和有效性,保障我们的安全和生活秩序。
有关GB28181更多文章,关注公众号:壹零仓,发送:28181,获取。
首先需下载js,然后直接引入即可:https://download.csdn.net/download/hon_vin/11829986
<!DOCTYPE HTML> <html> <head> <script src="https://code.jquery.com/jquery-3.2.1.js"></script> <script src="pinyinUtil.js"></script> </head> <body style="font-size:12px"> <form> 输入内容: <input type="text" onkeyup="pym.innerHTML = Pinyin.GetJP(this.value);allpym.innerHTML=Pinyin.GetQP(this.value); staffpym.innerHTML=Pinyin.GetHP(this.value);" /> <br /><br /> 拼 音 码: <span id="pym"></span><br /><br /> 拼音全码: <span id="allpym"></span><br /><br /> 混 拼 码: <span id="staffpym"></span> </form> </body> </html> 获取首字母简拼:Pinyin.GetJP(str);
获取全拼:Pinyin.GetQP(str);
获取混拼:Pinyin.GetHP(str);
效果图
文章目录 前言一、创建自己第一个自定义弹窗1.1 创建自定义弹窗1.2 创建构造器,与装饰器呼应相连CustomDialogController参数详解函数介绍open() close() 1.3 点击与onClick事件绑定的组件使弹窗弹出 二、示例代码总结 前言 自定义弹窗(CustomDialog)可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过CustomDialogController类显示自定义弹窗。具体用法请参考自定义弹窗。
一、创建自己第一个自定义弹窗 1.1 创建自定义弹窗 使用@CustomDialog装饰器装饰自定义弹窗。
@CustomDialog装饰器用于装饰自定义弹框,此装饰器内进行自定义内容(也就是弹框内容)。
@CustomDialog struct CustomDialogExample { controller: CustomDialogController build() { Column() { Text('我是内容') .fontSize(20) .margin({ top: 10, bottom: 10 }) } } } 需要注意的是:我们需要把这个自定义弹窗的代码放到我们需要使用的页面里面,就像这样:
我们自定义弹窗中有两个需要我们写的:
controller:控制我们的自定义弹窗的
build函数:和我们主界面是一模一样的,没有区别,直接和主页面一样写代码即可。
1.2 创建构造器,与装饰器呼应相连 在创建好自定义弹窗之后,我们肯定要弄出他的对象来吧,他的类型是CustomDialogController
dialogController: CustomDialogController = new CustomDialogController({ builder: CustomDialogExample({}), }) builder: CustomDialogExample({})为指定哪个自定义窗口
CustomDialogExample的参数为自定义窗口的参数
CustomDialogController参数详解 接口函数原型:
CustomDialogController(value:{builder: CustomDialog, cancel?: () => void, autoCancel?: boolean, alignment?: DialogAlignment, offset?: Offset, customStyle?: boolean, gridCount?
一、在Ubuntu上写helloworld程序并用交叉编译器编译 arm-none-linux-gnueabi-gcc -o helloworld helloworld.c -static
arm-none-linux-gnueabi-gcc 是开发板用的编译器
-static 是生成静态库
二、将生成的文件拷贝到U盘 三、挂载U盘到开发板 mount /dev/sda1 /mnt/disk/
我的是sda1,注意用自己的
四、去到挂载目录运行程序
一、问题描述:
通过SpringBoot+mybatis+druid集成,向mysql数据库插入数据或查询数据时,存入数据库里的中文数据,以及用ApiPost接口工具查询出的中文数据,均显示正常,但是idea控制台却显示中文乱码。
截图1(ApiPost查询的中文数据正常显示):
截图2(idea控制台显示的中文乱码):
二、分析
从数据来源文件(如Excel文件)里读取数据存入数据库,以及从数据库里查询出数据,中文均可以正常显示,这说明在业务操作里,并未受到中文乱码的干扰影响。
三、结论
正常的业务操作,并未产生乱码,在idea控制台里却出现了中文乱码,此时唯一的可能,就是idea配置方面的问题。
于是,在idea的File->settings里,对下述配置进行修改:
配置前:
配置后:
修改上述配置后,重新启动程序,进行查询测试,发现idea控制台的中文可以正常显示了:
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 前言硬件&操作系统一、静态路由是什么?二、开始配置1.netplan2.NetworkManager1.CLI2.Desktop 三、开始测试总结 前言 最近有一个需求,一开始让我满头疼的。有一个设备C挂在A服务器下面,在A上可以访问;现在我需要在B上访问C设备,A和B是同网段,B和C不是一个网段。如果B想直接访问C,最好地办法就是配置静态路由。
硬件&操作系统 CPU:I5 6700HQ
内存:DDR4 2400
OS:Ubuntu-18.04(server&desktop)
一、静态路由是什么? 静态路由(英语:Static routing)是一种路由的方式,路由项(routing entry)由手动配置,而非动态决定。与动态路由不同,静态路由是固定的,不会改变,即使网络状况已经改变或是重新被组态。一般来说,静态路由是由网络管理员逐项加入路由表。
查看本机路由也简单:
ip route 目前没有配置静态路由,等配置好了会出现在路由表里。
二、开始配置 静态路由配置这里介绍两种经典的方法,基于server的netplan方案和基于图形界面的NetworkManager方案(Debian系),还有其他发行版的方案这里就不单独介绍了,因为我用的最多的还是Ubuntu系统。
1.netplan #使用vim打开yaml文件,你的可能和我不一样 sudo vim /etc/netplan/00-installer-config.yaml # This is the network config written by 'subiquity' network: ethernets: enp97s0f1: addresses: - 10.0.48.37/24 # B服务器IP gateway4: 10.0.48.1 # 网关 nameservers: addresses: - 223.5.5.5 - 223.6.6.6 routes: - to: 172.20.0.80 # C服务器IP via: 10.0.48.31 # A 服务器IP on-link: true version: 2 这里就是配置B服务器通过A服务器到C设备的静态路由,指定了在B上访问C就经过A转一道。配置静态路由之前,B到C是没有直接路由的,是unreachable的。
题目描述】
一个最简单的计算器,支持+, -, *, / 四种运算。仅需考虑输入输出为整数的情况,数据和运算结果不会超过int表示的范围。然而:
1. 如果出现除数为0的情况,则输出:Divided by zero!
2. 如果出现无效的操作符(即不为 +, -, *, / 之一),则输出:Invalid operator!
【输入】
输入只有一行,共有三个参数,其中第1、2个参数为整数,第3个参数为操作符(+,-,*,/)。
【输出】
输出只有一行,一个整数,为运算结果。然而:
1.如果出现除数为0的情况,则输出:Divided by zero!
2.如果出现无效的操作符(即不为 +, -, *, / 之一),则输出:Invalid operator!
【输入样例】
1 2 +
【输出样例】
3
按要求做就行,三个变量,switch第三个变量字符类型,在除时判断0
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int x,y;
char k;
cin>>x>>y>>k;
switch(k){
case '+':
cout<<x+y;
break;
case '-':
cout<<x-y;
break;
case '*':
cout<<x*y;
break;
case '/':
if(y==0) { cout<<"
先提几个问题:
0、什么是 initrd 和 initramfs?
概述
现代Linux系统都使用到了一种功能比较特殊的微型系统,作为Linux内核初始化完成但未进入最终系统时的过渡系统,主要的目的是为了将最终系统载入到根文件系统上,辅助内核启动最终系统,可以称之为“辅助系统”。
辅助系统的作用
通常,主流的Linux发行版都会把内核中一些非必要且可以编译成模块的核心功能,如SATA、SCSI等设备的驱动程序,以内核模块的方式来提供。考虑这样一个场景,如果Linux系统是安装在如SATA磁盘上,那么就需要加载SATA磁盘的驱动程序来挂载磁盘上的根文件系统,但SATA的驱动程序又是放在磁盘的文件系统上,因此通过把SATA的驱动程序放到辅助系统中,就可以灵活解决这个问题。
辅助系统实现
辅助系统存放方式目前有两种:
Initrd
Initial RAM Disk,使用传统的内存磁盘方式存放辅助系统,现在基本已经不使用这种方式了,但很多Linux发行版在/boot目录也还在继续使用Initrd这个名字;
Initramfs
Initial RAM Filesystem,使用比较现代的内存文件系统方式存放辅助系统,也是当下主流的使用方式。
Initrd
Initrd采用RAM Disk来存储辅助系统,RAM Disk模拟块设备操作,Linux内核启动过程将辅助系统的镜像文件还原到RAM Disk设备上,在RAM Disk设备上使用辅助系统必须采用文件系统,必须将镜像文件格式化Linux内核支持的文件系统,在该文件系统中存放辅助系统。
将镜像文件还原到RAM Disk设备上时需要注意RAM Disk设备的大小,镜像文件还原后的文件系统占用空间必须小于等于RAM Disk设备的空间,否则会出现还原错误。
启动器将该镜像文件从磁盘上读取并存放到内存某个特定位置上,再由Linux内核在启动过程中从内存特定位置中将镜像文件还原到RAM Disk上,默认还原的RAM Disk设备文件名为/dev/ram0,然后按照Initrd的方式启动辅助系统。
Linux内核将Initrd中的辅助系统视为过渡系统,在辅助系统执行完成后,Linux内核重新获得控制权,继续执行根文件系统中的“最终系统”。
Initramfs
Initramfs采用内存文件系统存储“辅助系统”。与Initrd方式不同,Initramfs中的系统在Linux内核中被视为“最终系统”,定义为“辅助系统”是从制作该系统目的而言的,Linux内核将辅助系统文件还原到根文件系统,内核执行该系统后就不再接管执行控制权了,执行的控制都由该系统完成。
启动流程:
采用“Initrd”时Linux内核的启动过程
辅助系统文件采用“Initrd”时,内核将root参数指定设备对应的编号保存在内核的内部变量“real-root-dev”中,如果内核未能探测到root指定的设备,“real-root-dev”中将保存为“0”。
内核将“Initrd”文件还原到/dev/ram0设备上,运行其中根目录下的linuxrc文件,等待该文件的执行结束,linuxrc文件执行结束后推出并返回到内核继续执行。内核再次获得执行权后将检查“real-root-dev”中的取值,根据取值作不同处理:
real-root-dev为“0”,将提示无法挂载“0:0”设备而出错,无法继续启动;
real-root-dev的值与“/dev/ram0”的设备号相同时,内核认为“最终系统”已经准备就绪不再处理,直接运行当前根文件系统中/sbin/init命令;
real-root-dev的值不是“/dev/ram0”的设备号时,内核会认为需要挂载设备到根文件系统,按照“real-root-dev”对应的设备号挂载设备到根文件系统,并运行根文件系统中/sbin/init命令,如果内核无法挂载该设备将提示错误并启动失败。
采用“Initramfs”时Linux内核的启动过程
内核探测“Initramfs”后将会把文件解压还原到根文件系统中,形成一个微型系统,并认为该系统就是“最终系统”而直接运行其中的/sbin/init命令,内核完成启动过程。
1、initrd 和 initramfs 有什么区别?
linux 初始化会执行 init 进程,而 init 进程 会初始化 根文件系统(rootfs),但由于 init 进程也在 rootfs 中,这里出现一个先有鸡还是现有蛋的问题; **kernel 2.6 以前:**所以我们需要创造一个临时的文件系统环境(initrd.img),init 进程在 initrd.img 创造的文件系统里面运行起来,然后 init 进程去挂载真正的 根文件系统
需求:前端录入外部数据源,数据库类型多样,录入的数据源需要保存在系统中
本文只是一个单元测试,用于测试方案可行性,完整业务实现可以参考另一篇文章 1,引入依赖 <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.12</version> </dependency> <!--外部数据库--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.5.0</version> </dependency> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>9.5.0-SNAPSHOT.jre8-preview</version> </dependency> <dependency> <groupId>org.xerial</groupId> <artifactId>sqlite-jdbc</artifactId> </dependency> 2,多数据源demo 支持mysql,sqlserver,postgresql,sqlite,支持初始化时加载和动态新增
import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @Description 多数据源测试,支持mysql,sqlserver,postgresql,sqlite,支持初始化时加载和动态新增 * @Date 2022/12/1 11:31 * @Author 余乐 **/ public class ConnectAllData { //数据源连接池,放在单例类里 private static final ConcurrentHashMap<String, DataSource> hashMap = new ConcurrentHashMap<>(); //静态代码块先加载已有的数据源mysql,sqlite (正式开发一般放到ApplicationRunner的实现类里,从数据库读取已保存的配置) { System.
声明:
本文标题由ChatGpt 生成
导读 VChart不只是开箱即用的多端图表库,更是生动灵活的数据故事讲述者。
VChart是字节跳动开源可视化解决方案 VisActor 的核心图表组件库。它基于可视化语法库VGrammar和渲染引擎VRender进行封装,在满足数据呈现的同时,还支持面向叙事场景的动画编排、丰富的交互能力和定制化的图表风格,简单易用的配置大大降低了用户的学习成本。
快速上手 获取 VChart 你可以通过以下几种方式获取 VChart。
使用 NPM 包 首先,你需要在项目根目录下使用以下命令安装 VChart:
使用 npm 安装 npm install @visactor/vchart使用 yarn 安装 yarn add @visactor/vchart 使用 CDN 你还可以通过 CDN 获取构建好的 VChart 文件。将以下代码添加到 HTML 文件的 <script> 标签中:
<script src="https://unpkg.com/@visactor/vchart/build/index.min.js"></script> 引入 VChart 通过 NPM 包引入 在 JavaScript 文件顶部使用 import 引入 VChart:
import VChart from '@visactor/vchart'; 使用 script 标签引入 通过直接在 HTML 文件中添加 <script> 标签,引入构建好的 vchart 文件:
<!DOCTYPE html> <html> <head> <meta charset="
文章目录 前言10个代码1.逗号连接2.元音统计3.首字母小写4.展开列表5.列表的差6.通过函数取差7.链式函数调用8.检查重复项9.合并两个字典10.将两个列表转化为字典 总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍 四、Python工具包+项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料 六、Python兼职渠道 前言 学 Python 怎样才最快,当然是实战各种小项目, 只有自己去想与写,才记得住规则。
本文同样是 10 个极简任务,初学者可以尝试着自己实现;从这 10 段代码,Python 开发者也可以看看是不是有没想到的用法。
10个代码 1.逗号连接 下面的代码可以将列表连接成单个字符串,且每一个元素间的分隔方式设置为了逗号。
hobbies = [ "basketball", "football", "swimming"] print( "My hobbies are: "+ ", ".join(hobbies)) # My hobbies are: basketball, football, swimming 2.元音统计 以下方法将统计字符串中的元音 (‘a’, ‘e’, ‘i’, ‘o’, ‘u’) 的个数,它是通过正则表达式做的。
importre def count_vowels(str): return len(len(re.findall(r '[aeiou]', str, re.IGNORECASE))) count_vowels( 'foobar')# 3 count_vowels( 'gym')# 0 3.首字母小写 如下方法将令给定字符串的第一个字符统一为小写。
def decapitalize(string): return str[:1]. lower+ str[1:] decapitalize( 'FooBar')# 'fooBar' decapitalize( 'FooBar')# 'fooBar' 4.
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 前言10个代码1.重复元素判定2.字符元素组成判定3.内存占用4.字节占用5.打印 N 次字符串6.大写第一个字母7.分块8.压缩9.解包10.链式对比 总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍 四、Python工具包+项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料 六、Python兼职渠道 前言 学 Python 怎样才最快,当然是实战各种小项目, 只有自己去想与写,才记得住规则。本文是 10 个极简任务,初学者可以尝试着自己实现;本文同样也是 10 段代码,Python 开发者也可以看看是不是有没想到的用法。
10个代码 1.重复元素判定 以下方法可以检查给定列表是不是存在重复元素,它会使用 set 函数来移除所有重复元素。
def all_unique(lst): return len(lst)== len(set(lst)) x = [ 1, 1, 2, 2, 3, 2, 3, 4, 5, 6] y = [ 1, 2, 3, 4, 5] all_unique(x) # False all_unique(y)# True 2.字符元素组成判定 检查两个字符串的组成元素是不是一样的。
from collections importCounter def anagram(first, second): return Counter(first)== Counter(second) anagram( "abcd3", "3acdb") # True 3.
package com.demo.lxb.kafka; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.common.serialization.StringSerializer; import java.time.Duration; import java.util.Arrays; import java.util.Collections; import java.util.Properties; /** * @Description: kafka消费者消费消息,消费者端默认是同步提交offset策略 * @Author: lvxiaobu * @Date: 2023-10-24 16:26 **/ public class MyConsumer { private final static String CONSUMER_GROUP_NAME = "GROUP1"; // 消费者组 private final static String TOPIC_NAME = "topic0921"; // 主题 public static void main(String[] args) { Properties props = new Properties(); // 一、设置参数 // 配置kafka地址 // props.
3U 算法评估模块化系统设计用于集成到需要小尺寸,低功耗和实时处理的已部署 RF系统 IWRFSOC 8*8XiliX- RFSOC Gen 1,具有8个RF-ADC和8个RF-DAC通道,模块和全面的软件套件可快速用于原型制作,使用户能够快速适应开发应用程序代码,方便缩短产品开发周期,以便快速验证和部署。同时,配套的示例代码和教程演示了 Xilinx RFsoc 多瓦片同步(多转换器同步)和多板卡同步模拟捕获。
目标应用:
相控阵雷达、5G大规模MIMO、混合波束成形、信号检测与干扰、卫星通信
PS端接口:
2*QSPL flash(512MB,8bit)固化配置文件
1*SATA.M.2硬盘扩展接口(6G speed)
1*10/100/1000 Ethernet RGMll (RJ45)网口
1*USB-JTAG/UART 调试接口
1*Mircro SD Card
PL端接口
8路ADC(12-bit、4.096GSPS)端口
8路DAC(14-bit、6.554GSPS)端口
2*GPIO*16PMOD Ports
硬盘
1个SATA硬盘扩展接口
ATX电源供电接口(DC)
环境温度要求
工作温度-40°~110°
为了方便mysql等数据库的用户使用,特整理一些现有版本和历史版本的下载地址,如有问题请在评论区联系!后续会更新mysql免安装版的部署方法。
历史版本客户端下载地址(下载地址.../navicat后面的三位数字,前两位是大版本,后面是小版本,以下地址支持windows 64(x64)位和32(x86)位系统)
http://download.navicat.com/download/navicat100_premium_cs.exe
http://download.navicat.com/download/navicat110_premium_cs_x86.exe
http://download.navicat.com/download/navicat110_premium_cs_x64.exe
http://download.navicat.com/download/navicat120_premium_cs_x86.exe
http://download.navicat.com/download/navicat120_premium_cs_x64.exe
http://download.navicat.com/download/navicat121_premium_cs_x86.exe
http://download.navicat.com/download/navicat121_premium_cs_x64.exe
https://download.navicat.com/download/navicat150_premium_cs_x64.exe
https://download.navicat.com/download/navicat150_premium_cs_x86.exe
https://download.navicat.com/download/navicat160_premium_cs_x64.exe
https://download.navicat.com/download/navicat160_premium_cs_x86.exe
https://download.navicat.com/download/navicat161_premium_cs_x64.exe
https://download.navicat.com/download/navicat161_premium_cs_x86.exe
https://download.navicat.com/download/navicat162_premium_cs_x64.exe
https://download.navicat.com/download/navicat162_premium_cs_x86.exe
如需最新版本客户端请到官网下载(支持windows macOS Linux )
文章目录 前言一、Python代码1.表达式2.赋值句子3.引证4.分支句子5.循环句子 二、五行代码项目实例总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍 四、Python工具包+项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料 六、Python兼职渠道 前言 Python代码主要由:5个部分组成,下面就分别介绍,这5个部分代码的使用方法如下:
一、Python代码 1.表达式 产生或计算新数据值的代码片段,称为表达式,一般由数据和操作符等构成,也可以作用于字符串;
如下图所示,操作符:+;关于数据代表求和,关于字符串代表字符拼接;
2.赋值句子 对变量进行赋值的一行代码被称为赋值句子。语法格局∶
<变量>=<表达式>
举例:把1+1赋值给变量a,打印输出后成果为:2;由于2是整型,所以a的数据类型为:int;
3.引证 Python适用于各个领域,其最大的魅力就在于:它可以引证大量的外部函数库。
【引证方法】
①import<功用库库名>
②from<库名>import<函数名>
引证time库的sleep函数,可以实现延时1秒,以上2中引证方法,运转成果相同;
4.分支句子 分支句子是控制程序运转的一种句子,它的作用是,依据判别条件选择程序执行路径。
分支句子包含单分支、二分支和多分支。
5.循环句子 循环句子包含:遍历循环和条件循环,使用方法如下∶
,python代码库,最开始学习Python,不需要太过杂乱。只要玩儿的高兴就行,渐渐培养爱好,等你上手后,你会学习的更有信心。
二、五行代码项目实例 5行代码能做啥?这儿我为大家介绍两个好玩儿的小项目,介绍如下:
项目一:5行代码让电脑永不息屏!
项目二:5行代码爬取表格数据!
项目一:5行代码让电脑永不锁屏
众所周知,当你的电脑鼠标一向在动的时候,体系会默认你的电脑是在工作傍边,因此就不会息屏。
既然是玩吗?你就不要杠,说为啥“不设置用不息屏”?那样,你赢了,我无话可说。哈哈!
这儿便是用代码自动化操控鼠标,完成鼠标的“上下左右”移动操作,让电脑误以为是以为在操作鼠标。
在这儿,咱们运用的是Python中的pyautogui库。假如你的电脑没有安装这个库,能够运用下面代码安装一下。
pipinstallpyautogui
操控鼠标移动,运用的是pyautogui库中的moveRel(x,y)函数,用法如下:
含义:依据当前方位,相对移动鼠标指针;
留意:当x/y大于0,则表明往右/往下移动鼠标指针。当x/y小于0,则往左/往上移动鼠标指针【x/y是整数】;
当然这个随机数,肯定不要你人为去设置,咱们也随机生成。在这儿我需要为大家在介绍random库中的一个函数random.randint(a,b),用法如下:
含义:用于生成指定数值范围内的随机整数;
留意:该函数有两个参数a和b,表明指定区间的上限和下限;
importrandom
random.randint(a=100,b=300)
结果如下:
有了这些根底后,咱们直接上代码吧!
#导入相关库
importpyautogui
importrandom
importtime
#运用whileTrue循环,让程序一向执行!
whileTrue:
x=random.randint(-200,200)
y=random.randint(-200,200)
pyautogui.moveRel(x,y)
time.sleep(5)#让鼠标移动到某个方位,停留几秒钟,我怕它太累
当然,pyautogui库作为一个自动化操作鼠标的库,有许多值得你去挖掘的常识点。这儿仅仅简略运用,其它常识能够依据你的实际需求,去体系学习一下。
项目二:5行代码爬取表格数据
假如说想学习Python爬虫的话,我想这应该是最简略爬虫代码了。
说白了,便是pandas库爬取表格数据。这个其实和Excel有点像,Excel不便是只能爬取一些规矩的表格数据吗?可是这个更好用哦,究竟不让你着手。
今日咱们爬取到网页是“中商情报网”。
网址如下:
https://s.askci.com/stock/a/0-0?reportTime
假如想要运用pandas爬取数据,它的HTML结构是下面这个Table格式的。
咱们点击F12,查看源代码,当咱们定位待爬取数据时,会发现该数据满意这个特点。
其他常识没必要多讲,究竟都是pandas中的常识,大家很熟悉了。上代码:
#导入相关库
importpandasaspd
backbone "Backbone" 是深度学习中的一个术语,通常用于描述卷积神经网络 (Convolutional Neural Network, CNN) 或其他神经网络架构的一部分。这个术语指的是网络的主要结构或骨干部分,它负责提取输入数据的特征,并将这些特征传递给后续的层来执行任务,如分类、检测或分割。
特征提取:骨干网络包括卷积层、池化层和正则化层,它们协同工作以从原始输入数据中提取有用的特征。这些特征可以是图像、文本、声音等不同类型的数据,具体取决于网络的应用领域。
迁移学习:骨干网络通常在大规模数据集上进行预训练,这使得它们能够捕获大量的通用特征。这些预训练的骨干网络可以用作迁移学习的基础,以加速新任务的训练过程和提高性能。
backbone 的主要用途是为深度学习任务提供强大的特征提取和表示学习能力,从而提高模型的性能和泛化能力。不同的任务可能需要不同的 backbone 架构和权重。
head head是获取网络输出内容的网络,利用之前提取的特征,head利用这些特征,做出预测。
"head" 是神经网络模型的一个关键组成部分,主要负责执行特定任务的操作和生成模型的最终输出。Head 的功能和作用因任务类型而异,以下是一些常见的任务以及 Head 的主要功能和作用:
图像分类任务:
Head 用于将骨干网络(如卷积神经网络)提取的图像特征映射到类别标签。通常包括一个或多个全连接层,最后一层通常是 softmax 层,用于产生类别概率分布。 目标检测任务:
在目标检测中,Head 用于预测目标的位置(边界框)和类别。通常包括两个分支:一个用于回归边界框的坐标,另一个用于预测目标类别。Head 的输出会生成多个边界框和相应的类别概率。 图像分割任务:
在图像分割中,Head 负责生成像素级的类别标签。Head 可能包括卷积和上采样层,以将骨干网络提取的特征映射到与输入图像相同大小的分割结果。 自然语言处理任务:
在自然语言处理中,Head 可用于执行文本分类、情感分析、命名实体识别等任务。Head 可能包括全连接层、递归神经网络(RNN)、长短时记忆网络(LSTM)等结构,用于处理文本数据。 总之,Head 的主要功能是将从骨干网络提取的特征映射到任务相关的输出。这些特征映射可能包括类别标签、位置信息、文本分类等,具体取决于任务的性质。 Head 的设计通常是根据任务的需求和网络架构来定制的,以确保模型能够有效地解决特定任务。
neck "neck" 是指神经网络模型中的一个组成部分,通常位于“骨干网络”(backbone)和“头部”(head)之间。Neck 的作用是进一步处理骨干网络提取的特征,并将其准备好用于特定任务的头部。
特征融合和增强:Neck 通常包括卷积层、池化层和其他操作,用于融合、增强和调整骨干网络提取的特征。这有助于提高特征的表示能力,使其更适合任务的要求。
尺度调整:在一些计算机视觉任务中,不同尺度的特征对于正确执行任务非常重要。Neck 可以用于将多个尺度的特征融合在一起,以增强模型的多尺度感知能力。
特征金字塔:一种常见的 Neck 结构是特征金字塔网络(Feature Pyramid Network, FPN),它可以用于处理多尺度输入并生成多尺度的特征图,适用于目标检测和分割等任务。
上采样和下采样:Neck 可能包括上采样层和下采样层,用于将特征图的分辨率调整到与任务相匹配的分辨率。
连接不同任务的头部:在多任务学习中,Neck 可以用于连接不同的头部,以共享特征提取过程并提高模型的效率和性能。
"neck" 在神经网络模型中扮演了一个关键的角色,它有助于进一步处理和改进从骨干网络提取的特征,以便适应特定任务的需求。
1、打开51单片机最小系统工程文件。
2、整体删除同层的走线:打开PCB文件,在层的选项卡中选择顶层“Top Layer”,在“编辑”菜单下选择“选中”选项,选择“当前层上所有的”选项对顶层的走线全部选中,采用键盘上的“Del”删除键对整个顶层的走线进行全部删除。若要删除底层走线,只要在层的选项卡中选择底层“Bottom Layer”,采用同样的方法进行删除。
3、一般规则设定:PCB的板层设计和布线第11条,安全间距设为8mil,走线宽度最小值设为10mil,默认宽度为10mil,最大宽度为200mil;过孔参数可以采用默认参数。
4、特定规则设定:在“设计”菜单下选择“规则”进入布线规则的设定界面,在“Routing”选项中选择“Width”选项,将鼠标放在“Width”选项上单击右键,选择“新规则”进行添加新的规则,
这时菜单中会出现新的规则项“Width-1”,选中“Width-1”进入新规则的设定,在“Where The Object Matches”窗口中选择“Net”后,右边相应的下拉窗口会显示为何选择,从下拉窗口中选中“Vcc-5v”,表示该规则只适用于Vcc-5v网络的走线,其他走线不受影响,
这时可根据图形提示修改该网络走线的最小宽度(10mil)、默认宽度(20mil)和最大宽度(200mil),设置完成后点击右下方的“Apply”进行应用。
采用同样的方法,重新再添加你想设置的走线的新的规则。
5、选择布线层:同样在“Rules…”菜单下选择“Routing Layers”->双击下面的“Routing Layers”,在右边的窗口中会出现“Top Layer”和“Bottom Layer”两个选项,如果两个选择都打“√”,可以进行双层布板,如果只有“Top Layer”打“√”,则只能对顶层进行单层布线,如果只有“Bottom Layer”打“√”,则只能对底层进行单层布线。
6、放置标尺及PCB板尺寸:PCB的板层设计和布线第9条,画出一个40mm*70mm的PCB板的布线范围。该项在自动布线前一定要完成,否则计算机在进行自动布线时,由于走线不受约束而容易造成死机现象。
8、自动布线和撤销布线:以上规则设定好后,在“布线->自动布线”菜单中选择“全部”进入自动布线窗口,点击“Route All”按钮进行全部自动布线。自动布线完毕后,检查PCB板,有些元件由于管脚间隔太小,无法按照设定规则进行布线,这时可以利用手动布线进行补画。
若要撤销已经布好的走线,可在“布线”菜单中选择“取消布线”选项,选中“全部”选项进行全部撤销自动布线。
9、添加泪滴焊盘:布线结束后,所有的焊盘都是元件封装的焊盘,如果需要添加泪滴焊盘,可在“工具”菜单中选择“滴泪”选项进入添加泪滴焊盘的窗口,如果选择“添加”再点击“确定”则是添加泪滴焊盘,如果选择“删除”再点击“确定”则是撤销泪滴焊盘。泪滴焊盘的形状如下图所示。
10、PCB板的敷铜:在“放置”菜单下选择“敷铜”点击“Tab”键,右侧弹出“Properties(属性)选项进入放置敷铜窗口,设置的主要参数:Properties(属性)中的“Net”下拉菜单中可以选择敷铜所接的网络线,我们选择“GND”(即所有的敷铜接地),“Layer”的下拉菜单中可以选择不同的层进行敷铜,我们先选择“Top Layer”层进行敷铜;“Solid”按钮向下是选择敷铜形状:“Solid”为实心型敷铜;“[hætʃt]Hatched”为网格型敷铜;“None”为空心型敷铜,我们选择实心型敷铜,“Remove Dead Copper”选项被选中时,表示敷铜结束后删除死铜,若该项不被选中,则不删除死铜(死铜的定义为不被网络连接的敷铜。在PCB板上画出需要敷铜的区域,单击鼠标右键结束画线,软件会自动在所画的区域内进行敷铜的放置。采用同样的方法,放置底层的敷铜。
11、敷铜安全间距的调整:放置敷铜完成后,若发现敷铜与连线之间的间距不合适,可以进入“规则”规则设定中重新设定安全间距后,双击敷铜,进行重新放置敷铜,安全间距为10mil的敷铜效果。当修改了敷铜参数后,需要重新敷铜操作步骤:在有敷铜的区域点击右键弹出对话框“铺铜操作->所有铺铜重铺”即可完成对所有敷铜的重新操作。
12、删除敷铜:在层的选项卡中选择需要删除的敷铜层,单击敷铜层,采用键盘上的“Del”删除键进行删除。
软件版本:Kepserver6.12
串口调试工具:Sscom5.13.1
首先先来看下串口工具,通讯上来的数据:
KepServer通讯配置:
添加通道→选择U-CON驱动→下一步; 选择【以太网封装】→选择通信办卡→通信方式选择【非主动】模式→输入秤的端口号,其他默认→下一步; 更正:通信方式选择【主动】模式 默认配置→下一步; 默认配置→下一步; Unsolicited Mode选择【是】,其他默认→下一步; 添加设备,自定义名称→下一步; 默认配置→下一步; 默认配置→下一步; 默认配置→下一步; 默认配置→下一步; 默认配置→下一步; 默认配置→下一步; 默认配置→下一步; 默认配置→完成; 右击U-CON Device Profile进入编辑模式→添加NewTag→DataType:String→DataLength:10(根据串口调试工具ASCII,提取相对应的字长)→OK; 添加Unsolicited指令Read Response→方式一:0D为结束语→OK; 添加Unsolicited指令Read Response→方式二:输入报文总数量→OK; 添加Unsolicited指令Update Tag→输入需要从第几位开始寻址→OK; 添加Unsolicited指令Clear RX Buffer→输入需要从第几位开始寻址→OK; 如需要同时读取两组数据→ 添加Block→添加两个Tag→添加Unsolicited指令,依次添加Update Tag命令→OK; Update Tag Tag2寻址地址需要重新输入开始地址→OK; 注意:如果测试过程中,针对通道或是设备配置修改,修改后的参数不起作用,需要重新建立通道或者设备,新配置才生效。
1、计算序列 1 + 1/3 + 1/5 + … 的前N项之和 题目:本题要求编写程序,计算序列 1 + 1/3 + 1/5 + … 的前N项之和。
输入格式: 输入在一行中给出一个正整数N。
输出格式: 在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后6位。题目保证计算结果不超过双精度范围。
输入样例: 23 输出样例: sum = 2.549541 代码1: #include<stdio.h> int main() { int i,n,a,b=1; double sum=0; scanf("%d",&n); for(i=1;i<=n;i++){ a=1; sum=sum+a*1.0/b; b=b+2; } printf("sum = %.6f",sum); return 0; } 代码2: #include <stdio.h> int main() { int i,n; double sum=0; scanf("%d",&n); for(i=1;i<=n;i++) sum+=1.0/(2*i-1); printf("sum = %f\n",sum); return 0; } 2、计算平方根序列√1+√2+√3+⋯的前N项之和 题目:本题要求编写程序,计算平方根序列√1+√2+√3+⋯的前N项之和。可包含头文件math.
前言 tig对应的服务是influxdb grafana telegraf
此架构比传统的promethus架构更为简洁,虽然influxdb开源方案没有集群部署,但是对于中小型服务监控需求该方案简单高效
本文以docker-compose来演示这套监控体系的快速搭建和效果。 部署 docker-compose.yaml
version: '3' networks: monitor: driver: bridge #配置应用 services: #grafana 报警推送 #账号密码 prometheusalert prometheusalert prometheusalert: image: feiyu563/prometheus-alert container_name: prometheusalert hostname: prometheusalert restart: always ports: - 8087:8080 networks: - monitor volumes: - ./docker/prometheusalert/conf:/app/conf - ./docker/prometheusalert/db:/app/db environment: - PA_LOGIN_USER=prometheusalert - PA_LOGIN_PASSWORD=prometheusalert - PA_TITLE=PrometheusAlert - PA_OPEN_FEISHU=1 #界面展示 默认账号密码 admin admin grafana: image: grafana/grafana container_name: grafana hostname: grafana restart: always volumes: - ./docker/grafana/data/grafana:/var/lib/grafana ports: - "3000:3000" networks: - monitor #influxdb数据库v2自带管理端 #账号密码 root root influxdb: image: influxdb container_name: influxdb environment: INFLUX_DB: test # 可能无效 INFLUXDB_USER: root # 可能无效 INFLUXDB_USER_PASSWORD: root # 可能无效 ports: - "
面向对象 面向对象基础 类 对象和消息 方法重载 封装 控制修饰符的限定范围 继承 子类父类** 类的加载顺序 子类在继承父类时,子类只继承父类的非私有方法或属性;
示例 多态 动态绑定 面向对象设计原则 面向对象分析(OOA) 面向对象设计(OOD) 面向对象测试 面向对象程序设计(OOP) UML 事务 对模型中具有代表性的成分的抽象;
关系 依赖 关联 泛化 实现 关联多重度 UML中的图 类图 示例 重写(覆盖)
对象图 用例图 包含关系 扩展关系 泛化关系 用例图的概念 交互图(序列图-顺序图) 通信图 状态图 状态和活动 转换和事件 状态图的概念 示例 活动图 构件图 部署图 设计模式 设计模式的要素 设计模式分类汇总 创建型设计模式 简单工厂模式 工厂方法模式 工厂方法模式相关概念 抽象工厂模式 抽象工厂模式的适用性 生成器模式 生成器模式的适用性 原型模式 原型模式的适用性 原型设计模式(入门code) public class ImitationPrototype { public static void main(String[] args) { product product = new product(123, 123456.
该项目分为两个部分:一是数据计算,二是可视化,三是MACD策略 一、计算MACD 1、数据部分 数据来源:tushare
数据字段包含:日期,开盘价,收盘价,最低价,最高价,涨跌
需要计算的数据:macd,diff,dea
2、MACD的计算 (1)计算指数移动平均值(EMA) 12日EMA的算式为
EMA(12)=前一日EMA(12)×11/13+今日收盘价×2/13
26日EMA的算式为
EMA(26)=前一日EMA(26)×25/27+今日收盘价×2/27
(2)计算离差值(DIF) DIF=今日EMA(12)-今日EMA(26)
(3)计算DIF的9日EMA 根据离差值计算其9日的EMA,即离差平均值,是所求的MACD值。为了不与指标原名相混淆,此值又名
DEA或DEM。
今日DEA(MACD)=前一日DEA×8/10+今日DIF×2/10。
计算出的DIF和DEA的数值均为正值或负值。
用(DIF-DEA)×2即为MACD柱状图。
二、可视化 1、可视化工具:pyecharts pyecharts官网
三、MACD策略 代码实现如下: from typing import List, Sequence, Union from pyecharts import options as opts from pyecharts.commons.utils import JsCode from pyecharts.charts import Kline, Line, Bar, Grid # 数据 #时间, #ema重构版 import pandas as pd import numpy as np import tushare as ts def macd(code,start_date,end_date): ''' 获取数据 预处理 计算股票的ema、dif、dea、macd 主要有9日,12日,26日 ''' #获取数据 pro=ts.
目录 1. 方法一:遍历列表2. 方法二:使用Collections类3. 方法三:使用流 Java列表取最大值
在Java中,我们经常需要从一个列表中找到最大的值。列表可以是数组、集合或其他数据结构。本文将介绍如何使用不同的方法来取得列表中的最大值,并给出相关的代码示例。
1. 方法一:遍历列表 最简单的方法是使用循环遍历列表,逐个比较元素的大小,并记录最大值。下面是一个使用for循环的示例代码:
List<Integer> list = Arrays.asList(1, 9, 5, 3, 7); int max = list.get(0); // 假设列表中至少有一个元素 for (int i = 1; i < list.size(); i++) { if (list.get(i) > max) { max = list.get(i); } } System.out.println("列表中的最大值是:" + max); 这段代码先将列表的第一个元素设为最大值,然后从第二个元素开始遍历,逐个比较,如果发现有更大的值,则更新最大值。最后输出最大值。
2. 方法二:使用Collections类 Java的Collections类提供了一系列静态方法,可以方便地对集合进行操作,包括获取最大值、最小值等。我们可以使用Collections.max()方法来获取列表中的最大值。下面是一个示例代码:
List<Integer> list = Arrays.asList(1, 9, 5, 3, 7); int max = Collections.max(list); System.out.println("列表中的最大值是:" + max); 这段代码直接调用Collections.max()方法,将列表作为参数传入,即可获取到列表中的最大值。
3. 方法三:使用流 Java 8引入了流(Stream)的概念,可以方便地对集合进行各种操作。我们可以通过将列表转换为流,然后使用流的相关方法来获取最大值。下面是一个示例代码:
需求背景:
多台服务器使用华为交换机组建了局域网,需要让交换机的指定端口可以访问外网。
需求分析:
交换机组建的局域网是二层组网,需借助路由器接入外网,然后通过DHCP分配内网IP地址给交换机指定端口连接的设备。
网络拓扑:
配置方法:
1、首先登录华为交换机,添加VLAN124
注意在添加时勾选“创建VLANIF接口”,然后IP地址设置为192.168.124.2
2、交换机配置DHCP
按上图点击“新建”,弹出如下窗口。选择步骤1创建的VIlanif124接口,DHCP模式选择“外部服务器分配”(即通过新华三路由器分配),服务器IP地址填写路由器IP地址“192.168.124.1”
3、新华三路由器DHCP配置
如下图所示,启用DHCP服务器,地址池起始地址从192.168.124.3开始
(192.168.124.1用于华三路由器,192.168.124.2用于华为交换机的VLANIF接口)
4、网线连接
如拓扑图,路由器的WAN口连接外网,路由器的LAN口连接交换机的VLAN124端口,需要访问外网的计算机连接交换机的其它VLAN124端口。路由器通过DHCP给计算机分配IP后,计算机即可访问外网。
判断两个对象是否相等(是同一个对象),首先调用hashCode()方法得到各自的hashcode, 1、如果hashcode不相等,则表明两个对象不相等。
2、如果hashcode相等,继续调用equals方法进行判断
2.1:equals()返回true,则对象相等
2.2:equals()返回fasle,两对象不相等
所以,要求程序员在重写hashCode方法时尽量做到:不一样的对象,hashCode不一样,这样在判断两个对象是否是同一对象时可以提高效率
compareTo()方法和equals()方法的关系: 对于某些对象如集合(TreeSet)需要实现内部排序,所以要实现Comparable接口,从而要实现里面的唯一方法compareTo();实现Comparable接口的对象表明遵循自然排序。从Comparable的API中可以看出:
compareTo方法和compare的意义及作用
1、普通的类要实现排序,必须实现Comparable接口,并重写CompareTo()方法。
2、compareTo(Object o)方法是java.lang.Comparable接口中的方法,当需要对某个类的对象进行排序时,
该类需要实现Comparable<T>接口的, 必须重写public int compareTo(T o)方法,比如MapReduce中Map函数和Reduce函数处理的 <key,value>, 其中需要根据key对键值对进行排序, 所以,key实现了WritableComparable<T>接口,实现这个接口可同时用于序列化和反序列化。 WritableComparable<T>接口 (用于序列化和反序列化)是Writable接口和Comparable<T>接口的组合; 3、compare(Object o1,Object o2)方法是java.util.Comparator接口的方法,它实际上用的是待比较对象的compareTo(Object o)
实例 package com.lei; import java.util.Objects; public class students implements Comparable<students>{ private String name; private int age; public students() { } public students(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.
文章目录 前言1.使用yum命令安装Crontab:2.查看Crontab状态:3.添加定时任务:4.查看任务列表:5.Crontab相关命令:6.部分脚本无法执行问题:7.Crontab默认调度任务:8.注意清理系统用户的邮件日志:9.Crontab日志路径:10.Crontab命令在线验证工具: 前言 Crontab介绍:
Linux crontab是用来crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。该词来源于希腊语 chronos(χρ?νο?),原意是时间。通常,crontab储存的指令被守护进程激活, crond常常在后台运行,每一分钟检查是否有预定的作业需要执行。这类作业一般称为cron jobs。当安装完成操作系统之后,默认便会启动此任务调度命令。crond 命令每分锺会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。
注意:新创建的 cron 任务,不会马上执行,至少要过 2 分钟后才可以,当然你可以重启 cron 来马上执行。
1.使用yum命令安装Crontab: yum install vixie-cron yum install crontabs 注:vixie-cron软件包是cron的主程序; crontabs软件包是用来安装、卸装、或列举用来驱动 cron 守护进程的表格的程序。 cron是linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务: /sbin/service crond start #启动服务 /sbin/service crond stop #关闭服务 /sbin/service crond restart #重启服务 /sbin/service crond reload #重新载入配置 2.查看Crontab状态: service crond status ntsysv #查看crontab服务是否已设置为开机启动 chkconfig –level 35 crond on #加入开机自动启动 3.添加定时任务: crontab -e #编辑cron任务模式 i #默认文字编辑器为vim,按i字母键即可添加cron任务 30 3 * * * /usr/local/etc/rc.d/lighttpd restart #将命令代码放入,此命令意义为每天的03:30 重启apache ESC #按ESC键退出编辑模式 :wq #键入:wq保存 service crond restart #重启crontab服务 4.
文章目录 前言一、DataPanel数据面板1.1 接口参数介绍 1.2 属性1.3 DataPanelType枚举说明1.4 深度剖析number[]参数1.5 示例代码 二、DatePicker日期选择2.1 接口参数说明 2.2 属性2.3 事件DatePickerResult对象说明 2.4 示例代码 总结 前言 DataPanel:数据面板组件,用于将多个数据占比情况使用占比图进行展示。
DatePicker:日期选择器组件,用于根据指定日期范围创建日期滑动选择器。
一、DataPanel数据面板 1.1 接口 DataPanel(options:{values: number[], max?: number, type?: DataPanelType}) 从API version 9开始,该接口支持在ArkTS卡片中使用。
参数介绍 下面的参数分别代表:参数名,参数类型,必填,参数描述
values,number[],是,数据值列表,最多包含9个数据,大于9个数据则取前9个数据。若数据值小于0则置为0。
max,number,否
max大于0,表示数据的最大值。
max小于等于0,max等于value数组各项的和,按比例显示。
默认值:100
type,DataPanelType,否,数据面板的类型(不支持动态修改),默认值:DataPanelType.Circle
1.2 属性 除了通用属性,如:backgroundcolor,color,font这些属性,他还有自己独特的属性:
closeEffect,boolean,关闭数据占比图表旋转动效。默认值:false 1.3 DataPanelType枚举说明 从API version 9开始,该接口支持在ArkTS卡片中使用。
下面参数功能分别为这个:名称,描述
Line,线型数据面板。
Circle,环形数据面板。
1.4 深度剖析number[]参数 通过图片理解:
他们是累加,在前一个数据后面累加,并不是从0开始!!!
1.5 示例代码 // xxx.ets @Entry @Component struct DataPanelExample { public valueArr: number[] = [10, 10, 10, 10, 10, 10, 10, 10, 10] build() { Column({ space: 5 }) { Row() { Stack() { DataPanel({ values: [25], max: 100, type: DataPanelType.
问题 使用ToDesk等远程软件连接自己的Linux或Windows主机时,若主机已连接显示器,则可通过系统设置更改显示分辨率。但如果主机没有连接显示器或显示器的电源关闭,则无法正常调整分辨率。下文介绍解决方案。
解决方案 方案1:连接显示器并打开显示器电源 主机连接显示器并打开显示器电源后,通过ToDesk等远程软件连接后,便可通过系统设置更改分辨率。
若主机不想连接显示器或不想打开显示器电源,则可参考方案2。
方案2:使用显卡欺骗器 若主机不想连接显示器或不想打开显示器电源,则可购买显卡欺骗器,并插入主机的显卡输出接口,可以是HDMI或DP接口。
显卡欺骗器是一种让显卡认为被连接了一个显示器,然后开启正常的输出功能及性能的设备,主要适用于科学计算、远程控制等情况。
设备外形如图:
插入显卡欺骗器后,使用ToDesk等远程软件连接主机后,便可通过系统设置更改分辨率。
有些软件卸载重装如果没提前清理注册表便会导致无法成功安装(点名ArcGIS),我们如果自己手动删除如果误删某些注册表又会产生新的问题,而CCleaner便作为一款非常好用傻瓜级的软件出现到了我的视野里。
1.浏览器搜索CCleaner,进入官方界面下载free版 原网址:CCleaner 让您的计算机更快速、更安全 | 官方网站
CCleaner官网 进入此界面后浏览器自动开始下载 2.安装操作 过程中只需要注意安装路径即可,不要什么东西都往C盘安哦
3.进入主界面,左侧菜单栏中选择“注册表” 4.我们先点击左下方的“扫描问题”(我这里已经点过了),如何等待上方读条,读条至100%时单击“查看选定问题” 5.我们在修复前会有个弹窗要先备份注册表,我们把注册表备份放置到一个自己记得住的位置,再单击“修复所有选定问题”,修复注册表操作完成
//1、将可能为空的对象转换为Optional对象 // LiabilityPayEntity liabilityPayEntity1 = null; LiabilityPayEntity liabilityPayEntity1 = LiabilityPayEntityBuilder.builder().setIsChecked("1").createLiabilityPayEntity(); Optional<LiabilityPayEntity> optionalLiabilityPayEntity = Optional.ofNullable(liabilityPayEntity1); System.out.println("是否不为null:"+optionalLiabilityPayEntity.isPresent()); //2、Optional链式操作 String isChecked = optionalLiabilityPayEntity.map(LiabilityPayEntity::getIsChecked).orElse("0"); System.out.println("isChecked:"+isChecked); //3、Optional短路 //假设optionalLiabilityPayEntity对象从数据库中查询出来的,如果不存在则新建用户并返回 //(1) 错误用法,orElse是不断路的,如果orElse中的执行是负影响的,会被执行。 //LiabilityPayEntity liabilityPayEntity = optionalLiabilityPayEntity.orElse(newBean()); //(2) 正确写法,如果对象为空,newBean不执行。 LiabilityPayEntity liabilityPayEntity = optionalLiabilityPayEntity.orElseGet(() -> newBean()); System.out.println("liabilityPayEntity != null:"+(liabilityPayEntity != null)); //4、Optional抛出异常 optionalLiabilityPayEntity.orElseThrow(() -> new RuntimeException("对象为空!")); //5、Optional映射等一些其他的操作 optionalLiabilityPayEntity.map(LiabilityPayEntity::getIsChecked) .filter(isChecked1 -> isChecked1.equals("1")) .ifPresent(isChecked2 -> System.out.println(isChecked2)); private LiabilityPayEntity newBean(){ System.out.println("我要创建对象啦!"); return LiabilityPayEntityBuilder.builder().setIsChecked("9").createLiabilityPayEntity(); }
🌟🌟🌟 专栏详解 🎉 🎉 🎉
欢迎来到前端开发之旅专栏! 不管你是完全小白,还是有一点经验的开发者,在这里你会了解到最简单易懂的语言,与你分享有关前端技术和实用技巧的内容。此专栏的目标是提供易于理解且实用的内容,通过深入浅出的方式让大家掌握前端开发的核心概念和技能。我也相信,通过这个专栏,各位开发者们将更好地理解Web开发的本质,从而掌握更深层次的技术。Are you ready? 各位开发者们你们准备好了吗?
文章目录 一、Header标签的作用?结语 一、Header标签的作用? <header>用于定义文档或页面的头部
其实作用也就是类似于div标签,只是更好的让大家知道,我这个标签是个头部
结语 ✨ 每天创作一点点
✨ 开心快乐一整天
✨ 点赞关注加收藏
✨ 美好一天又一天
铁铁们 感谢支持 我需要你们的三连 👍👍👍
简介 Remmina 是一款在 Linux 和其他类 Unix 系统下的自由开源、功能丰富、强大的远程桌面客户端。
对于一个Linux作为主力开发机而言,Remmina 解决痛点主要是公司堡垒机远程客户现场的计算机,公司只给开发了win系统下的远程连接程序,而没有linux版本。
Remmina安装 官网安装教程:
https://remmina.org/how-to-install-remmina/
Remmina 配置 需要进行基本的ip,端口,用户名和密码设置,以及远程分辨率和快捷键的设置
Remmina 文件互传:本地机器和远程桌面 Remmina有一个痛点:无法copy文件到远程桌面,解决方案如下:
去bing搜索如下关键字:
然后会得到下面结果(也就是解决方案):
https://gitlab.com/Remmina/Remmina/issues/243
says that shares show up using Remmina when you also enable sound redirection. To recap, here is what you have to do:
Create a Remmina RDP connection to the windows machine Edit that connection. Under the Basic tab Choose a share folder In Advanced tab, change sound to local.
目录 1.背景介绍1.1. 项目背景1.2. 项目难点1.3. 项目环境 2. flask后端开发实现的功能3. flask部署和前后端对接3.1. flask运行配置和服务器部署3.2. flask前后端传参 4. 后端测试工具4.1. 工具介绍4.2. 工具使用 后记 1.背景介绍 1.1. 项目背景 就是前几个月临时接手了一个后端项目,使用python flask框架进行后端开发,整个项目开发内容相对简单,主要是文件读取和修改,没有用上数据库操作,主要实现的功能点包括:
根据网页端的参数数值,修改对应文件的参数值;展示oai运行的结果,返回给前端;使用python编程语言远程连接服务器,多线程运行liunx命令,从而运行oai代码和matlab代码。 实时读取liunx命令的命令行输出,返回给前端做展示;随时终止命令行执行; 这篇文章将会梳理我在这个项目开发过程中的学习收获,欢迎交流!
1.2. 项目难点 前后端对接;修改本地文件,包括.mlx这类动态脚本文件;查找文件内容,并修改对应参数;python语言远程连接服务器并执行命令;命令行输出实时读取并展示;后端代码调试手法(小白第一次搞后端嘛 1.3. 项目环境 flask 2.3.3gunicorn 20.0.4python 2.7.18MobaXterm_Personal 23.2Ubuntu 20.04.6 LTS ( GNU/Linux 5.4.0-163-lowlatency x86_64) 2. flask后端开发实现的功能 修改文件参数值——根据网页端的参数数值,修改对应文件的参数值 获取网页端传参读取对应文件:包括普通的程序文档以及mlx文件;查找对应修改位置,替换数据 读取结果数据——展示oai运行的结果,返回给前端; 文件结果如何存储;读取对应文件,构建参数返回给前端; 运行liunx命令行——使用python编程语言远程连接服务器,多线程运行liunx命令,从而运行oai代码和matlab代码。 远程连接服务器python语言多线程执行liunx命令实时读取liunx命令的输出数据终止命令执行 3. flask部署和前后端对接 3.1. flask运行配置和服务器部署 flask安装
打开cmd窗口,如果已经部署了python环境,则使用如下命令安装flask对应包 pip install flask
flask基本框架
最简单的flask框架如下所示:
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World' if __name__ == '__main__': app.
删除表 drop table 表名; drop table if exists 表名; 修改表 修改表名 alter table 表名 rename to 新表名; 添加列 alter table 表名 add 列名 数据类型; 删除列 alter table 表名 drop 列名; 修改数据类型 alter table 表名 modify 列名 新数据类型; 修改列名和数据类型 alter table 表名 change 列名 新列名 新数据类型; 图形化客户端工具 Navicat 给指定列添加数据
insert into 表名(列名1,列名2...) values(值1,值2...); 给所有列添加数据时,依然可以用上面的格式,如下
INSERT into stu(id,name,sex,birthday,score,email,tel,status) value(2,'李四','男','1999-1-1',88.88,'lisi@163.com','13888888888',1); 但给所有列添加数据可以简化,把列名删去,减少代码量
insert into 表名 values(值1,值2...); INSERT into stu value(2,'李四','男','1999-1-1',88.88,'lisi@163.com','13888888888',1); 美化SQL
点击后:
批量添加,仅需把括号和里面的内容多复制几遍,并且加上逗号,然后运行即可,例如: