今天学到了,使用了ros::spin()就是让程序一直在subscriber里面死循环.
更新需求,要把按键设置成控制速度按钮,摇杆作为前进后退的控制.
首先需要测试手柄上所有的按键对应的buttons[]的哪一位:
sudo jstest /dev0/input/js0 全部测试后,发现了以下对应信息:
Buttons[]: A: 0 B: 1 X: 2 Y: 3 L1: 4 R1: 5 select:6 start: 7 mode: 8 //9,10没有分配 控制的逻辑还是在按下L1下开始,只有按下L1其他按键按动才会启动,现在的设想是:
Y和A分别控制线速度的增加和减少,X和B分别控制角速度的增加和减少;
每个设置4档:0,1,2,3
SELECT设置为最低速度, START设置为最高速度,其它按键暂时不设置.
设置比较简单,但最后的逻辑需要思考一下,先实现:
首先在launch里面更改:
<launch> <node pkg="turtlesim" type="turtlesim_node" name="turtle1" output="screen" /> <node pkg="ros_handle_control" type="teleop_turtle4" name="teleop4" output="screen" /> <node pkg="ros_handle_control" type="teleop_turtle5" name="teleop5" output="screen" /> <!-- 方向按键控制 --> <param name="axis_linear" value="7" type="int" /> <param name="axis_angular" value="6" type="int" /> <!-- 摇杆控制 --> <param name="
每次开机都得先科学上网,再退出,才能连接校园网。
烦死了!!!
解决方法如下:
右键点击Windows左下角“开始”菜单-“搜索”,输入Internet,并在结果中点击打开“Internet选项”
进入“Internet选项”界面后,修改两个位置:
首先,点击“Internet选项”界面顶部“连接”选项卡,点击“局域网设置”,取消勾选“为LAN使用代理服务器(这些设置不用于拨号或VPN连接)”,确定。
然后,点击“Internet选项”界面顶部“高级”选项卡,勾选“使用HTTP 1.1”“使用HTTP
2”两项,并取消勾选“通过代理连接使用HTTP 1.1”,确定。
最后,尝试一下是否能正常上网,如果不能,重新启动电脑生效。
网易云放音乐加载不出来 CSDN打不开等问题 重新分配一个ip地址
方法一:
windows+r打开cmd输入 ipconfig /release重新连一遍网 方法二:
百度网盘下载下面cmd文件
链接:https://pan.baidu.com/s/1rSmJ9MarLt66iNTyccLR3Q
提取码:tiag直接点一下即可 超级神奇!!!
GitHub加速 在github上下载clone源码过慢的问题,甚至失败问题。加速解决方案如下:
方法一、使用"码云"中转下载。 使用’码云’平台做中转,先将项目导入’码云’,再从’码云’平台clone,很快。
注册登录"码云",码云。
点击右上角新建仓库的加号+,选择“从GitHub/GitLab导入仓库”菜单。
填写想clone的仓库地址。
码云clone项目非常快,等待导入完成。
导入完成后,使用码云生成的地址clone项目。
重新关联远程地址。
文本编辑器打开项目.git文件夹中的config配置文件。(.git文件是隐藏文件夹)。
将配置文件中的[remote "origin"].url字段重新关联到原来位于GitHub上的GitHub项目地址。
方法二、替换原URL 使用国内镜像源替换。将url中github.com替换为镜像地址github.com.cnpmjs.org
如:
git clone https://github.com/flutter/flutter.git 替换为:
git clone https://github.com.cnpmjs.org/flutter/flutter.git 方法三、使用gitclone.com平台clone 从GitHub缓存加速网站clone。
使用如下:
方法一(替换URL) git clone https://gitclone.com/github.com/tendermint/tendermint.git 方法二(设置git参数) git config --global url."https://gitclone.com/".insteadOf https:// git clone https://github.com/tendermint/tendermint.git 方法三(使用cgit客户端) cgit clone https://github.com/tendermint/tendermint.git 方法四、修改hosts文件。 在国内IP查询网站(https://www.ipaddress.com/)上查询:
github.com
assets-cdn.github.com
github.global.ssl.fastly.net
等的地址,然后修改host文件。
MAC电脑中打开终端
sudo vi /etc/hosts 参看:https://zhuanlan.zhihu.com/p/65154116
方法五、配置代理。 在你有代理能上网的前提下,仅仅针对github进行配置,让github走本地代理,其他的保持不变;
# socks5协议,1080端口修改成自己的本地代理端口 git config --global http.https://github.com.proxy socks5://127.0.0.1:1080 git config --global https.https://github.com.proxy socks5://127.0.0.1:1080 # http协议,1081端口修改成自己的本地代理端口 git config --global http.
转载声明 本文大量内容系转载自以下文章,有删改,并参考其他文档资料加入了一些内容:
使用Guava RateLimiter限流以及源码解析
作者:人在码途 转载仅为方便学习查看,一切权利属于原作者,本人只是做了整理和排版,如果带来不便请联系我删除。
1 前言 在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流
缓存
缓存的目的是提升系统访问速度和增大系统处理容量。降级
降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开。限流
限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。 2 常用的限流算法 2.1 漏桶算法 漏桶算法思路很简单:
水(请求)先进入到漏桶里漏桶以恒定的速度出水注意,当水流入速度过大时会直接溢出。 漏桶算法能强行限制数据的传输速率为恒定速率,当流入的请求过大时就拒绝抛掉了。
2.2 令牌桶算法 对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。
如上图所示,令牌桶算法的原理:
系统会以一个恒定的速度往桶里放入令牌如果请求需要被处理,需要先从桶里获取一个令牌当桶里没有令牌可取时,则拒绝服务或等待 2.3 漏桶对比令牌桶 2.3.1 当请求流入速度小于请求处理速度时 漏桶
整个系统处理速度取决于请求流入速度;令牌桶
此时请求获取令牌速度小于令牌放入速度,此时整个系统处理速度也取决于请求流入速度。 2.3.2 当请求流入速度大于请求处理速度时 漏桶
整个系统处理速度取决于系统限制的处理请求的平均速度,处理不过来的请求溢出(抛掉)。令牌桶
整个系统处理速度取决于系统限制的放入令牌速度,处理不过来的请求抛掉或排队等待令牌。 2.3.3 关键区别 漏桶
无论怎么样,使用漏桶算法最多也就能将处理速度达到请求流入的恒定速度上限,而面对突发的请求流入就无能为力了,只能抛掉。令牌桶
因为可以提前放入令牌,所以可能低峰期累积了一定量令牌,可在突发请求时使用这些令牌。有一些算法如Guava-RateLimiter可在令牌不足时提前直接使用,而只是在下一次使用令牌时等待这些数量的令牌。 2.3.4 使用场景区别 并不能说明令牌桶一定比漏洞好,她们使用场景不一样:
令牌桶可以用来保护自己,主要用来对调用者频率进行限流,为的是让自己不被打垮
所以如果自己本身有处理能力的时候,如果流量突发(实际消费能力强于配置的流量限制),那么实际处理速率可以超过配置的限制(之前由于放入令牌速度大于令牌申请速度而放了预备的一些令牌)。而漏桶算法,这是用来保护他人,也就是保护他所调用的系统
主要场景是,当调用的第三方系统本身没有保护机制,或者有流量限制的时候,我们的调用速度不能超过他的限制,由于我们不能更改第三方系统,所以只有在主调方控制。这个时候,即使流量突发,也必须舍弃。因为消费能力是第三方决定的。 总结起来:如果要让自己的系统不被打垮,用令牌桶。如果保证被别人的系统不被打垮,用漏桶算法。
3 Guava-RateLimiter的使用 3.1 概述 Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法实现流量限制,使用十分方便,而且十分高效。
3.2 RateLimiter使用 简单例子:
public void testAcquire() { // 首先创建一个限流器,参数代表每秒生成的令牌数 RateLimiter limiter = RateLimiter.create(1); for(int i = 1; i < 10; i = i + 2 ) { // limiter.
最近需要测试图像的指标,然后特意去关注了一下相关的信息,然后主要用的评价指标为:
1、PSNR 和 SSIM 去看:图像质量评价指标: PSNR 和 SSIM_马鹏森的博客-CSDN博客_psnr范围
5、LPIPS 也叫作感知损失,比PSNR和SSIM更接近于真实人感到的感觉:
https://blog.csdn.net/weixin_43135178/article/details/127664187
3、FID 去看:FID使用(Frechet Inception Distance score)_马鹏森的博客-CSDN博客
出自论文:GANs Trained by a Two Time-Scale Update Rule Converge to a Local Nash Equilibrium(https://arxiv.org/abs/1706.08500)
4、Recall(多样性) 代码:https://github.com/blandocs/improved-precision-and-recall-metric-pytorch
关于这个评价参数我是在“Diffusion-GAN: Training GANs with Diffusion”论文中看到的,地址为:https://arxiv.org/abs/2206.02262
原文对这个的解释:Lower FIDs indicate better fidelity, while higher Recalls indicate better diversity. We further report the improved Recall score introduced by Kynkäänniemi et al. [2019] to measure the sample diversity of generative models.
目录 前言论文及代码链接论文动机PointRCNN主要模块分析总结及个人思考 前言 这篇论文比较老了,是2018年12份上传到arxiv的,虽然也就才几年,但是对于现在深度学习相关领域日卷月卷的情况而言,确实有点太旧了。个人感觉,如果对于二阶段目标检测算法已经有了大概的一个了解,这篇论文可以不去深究了,赶紧看看最新论文或者其他相关领域的论文找想法凑毕业要求吧。
本篇文章是个人阅读文献的一些总结与思考,如有某些地方理解有问题请指出,个人QQ:1981425845
论文及代码链接 论文链接:论文链接
(这块儿碎碎念一句,如果觉得arxiv下载论文慢别傻傻等,有方法的,自己网上查查,很简单就是把网址稍微改一下就行)
代码链接:代码链接
论文动机 作者发现,在3D点云中,不存在2D图像中的各个不同物体之间的遮挡问题(这个很好理解的,3D空间的物体肯定是相互独立的),这也就是说,一个bounding_box中的点应该只有一个物体的语义信息。基于这种思想,作者提出里一种二阶段3D目标检测网络Point-RCNN,第一阶段直接为每一个点生成一个Bounding_box,而第二阶段通过NMS得到一定数量proposal然后进行proposal的精调。
PointRCNN主要模块分析 这里先介绍一下Point-RCNN的整体结构以及算法流程,然后再对主要的结构进行详细分析,Point-RCNN的结构框图如下图所示:
这个图中,上半部分为第一阶段,第一阶段的主要作用就是提取出用于第二阶段的Proposal。具体流程也很简单,就是通过Pointnet++ 得到每个点的特征,然后将每个点的特征输入到前背景分割网络中得到得到每个点是前背景的概率,输入到包络框生成网络中生成每个点对应的Bounding_box参数。
(eg:如果不了解Pointbet++可以移步我之前写的一篇文章:Pointnet以及Pointnet++论文笔记
个人认为对于pointnet、pointnet++以及voxel_net这两个系列的网络还是很有必要好好看一下,这是绝大部分后来的网络的backbone的。)
下半部分是第二阶段,第二阶段主要是对第一阶段得到的Proposal进行调整得到最终的结果。注意第一阶段每一个点都会生成一个Bounding_box的,那是对所有的Bounding_box都进行refinement么?当然不可能了,这样子得多大计算量,而且很多是冗余计算。作者在进行第二阶段的refinement之前,对Bounding_box进行了非极大值抑制。依据的标准就是与Ground_Truth的IOU,注意需要把角度也就是Bounding_box的朝向考虑进去。得到经过NMS的proposal(proposal就是经过NMS的bounding_box)之后,进一步提取特征并与原来第一阶段得到的特征进行拼接,然后进行proposal的refinement和点的类别置信度预测。下面将详细介绍第一部分以及第二部分的关键结构。
第一阶段:
第一阶段的bockbone就不讲了,就是通过poinetnet++得到了point-wise的特征。然后分别用分类网络得到点的前背景概率与包络框网络得到包络框参数,其实这两个网络就是两个全卷积网络(FCN)。第一阶段要注意的主要就是第一阶段的损失函数组成,包括Focal_loss以及Bin-based 3D-bounding loss。接下来我们分别来介绍这两个部分。
Focal_loss : 主要用于解决正负样本数不平衡的问题,由何凯明大神提出。(这里挖个坑,做一篇正负样本不平衡的相关处理技术的总结,之后来填)。Focal_loss用于前背景点的分类中,因为在点云中,绝大部分点是背景点,如果采用普通的Cross_Entropy损失函数会导致于网络倾向于识别成背景点。Focal_loss表达式如下:
这里做一个直观的解释把,我们以二分类,或者更加直接我们要找出的对象就是汽车(代码中实现的是多分类版本,也就是要找出汽车、行人、自行车,我觉得有必要好好研究一下那一块儿)。对于原始点,是汽车的点标签为1,不是的为0,一个点预测的值大一0.5即认为其为汽车。如果负样本的比率比较大,那么其趋向于把每个点的预测值预测地比较低,也就是接近于0。这样地化,我们看上面的式子。对于负样本,由于预测值偏低,那么pt=1-p就会比较大,进而1-pt就会比较小,而对于正样本,刚好相反,1-pt就会偏大。这样子,正样本LOSS的权重或者说影响力就会比较大,用权重来弥补数量上的不足。同时,文中还对(1-pt)取了一个大于1的指数,这样子的话正负样本的权重差距拉的就更大了。
Bin-based 3D-bounding loss :为了方便,我们以是对点云中的一点P进行处理为例,要确定点P对应的Bounding_box一共需要(x,y,z,w,h,l,θ)七个参数,其中xyz是Bounding_box中心点坐标,lwh对应长宽高,θ对应于俯视图下的朝向。但是实际上我们也并不会直接去得到回归得到Bounding_box的中心点坐标,这样会丧失刚体变化的不变性,我们一般是求Bounding_box中心点相对于P点的位置偏移,也就是我们其实是要得到(Δx,Δy,Δz,w,h,l,θ),一般的做法也就是直接对这七个值进行回归。但是作者通过实验发现了一种bin-based能得到更好的结果。那么什么是bin_based呢,看论文中的图。
图中,紫色的点是我们当前处理的点(Point-RCNN中每一个点会对应一个Bounding_box),也就是点P,而橙色三角形P点的预测的bounding_box的中心。那么我们怎么表示这个中心的位置呢?首先,我们以P点位置为中心,分别向x,z方向选定一个的搜索范围(注意在KITTI中,y方向才是竖直方向,不考虑;我记得代码中搜索范围是以该点为中心±1.5m),然后将该搜索方位分成离散的区间。我们首先确定bounding_box的中心点在哪个区间,但是仅仅确定其在哪个区间还不行,比如代码中每个区间是0.5m,如果只确定在那个区间,那个最大误差会接近0.5m,这肯定不满足要求。所以确定区间之后,我们还需要对其在小区间的具体哪个位置进行回归,得到其精确的位置。也就是说bounding_box的中心的位置表示为LocationP + δ*区间分类+区间中具体位置回归。其中δ是每个区间的长度。论文中只对x,z与朝向θ进行了bin处理,其他的还是直接通过回归得到的,也就是说每个点对应的bounding_box的标签组成如下(x的bin分类向量,x在小区间的偏移值,z的bin分类向量,y在小区间的偏移值,y值,长,宽,高,角度的bin分类向量,角度在在小区间的偏移值)。
这块还有个地方提一下吧,就是x,y方向的分类标签与回归标签是怎么计算的,我当时看了老长时间也没有看明白,也许是我悟性不够。文章中给出的式子如下(具体参数什么意思大家自己看论文呀,论文里头都有解释的,打出来太费劲了):
看这个式子之前,我们记住一点,标签值是正数,别被前头那张图以及惯性思维迷惑。自认为那张图是以P点为原点,那么P点对应的bin编码应该是(0,0),这样的话上面这个式子为什么要加S就会看不懂了。其实原点对应的bin编码应该是S/δ,比如代码中S=1.5,δ=0.5,那么P点对应的bin编码应该是(3,3),注意这个编码值还应该转成one-hot向量形式。剩下的应该就好理解了,大家自己看论文吧。
第一阶段整体的损失函数如下:
第二阶段:
第二阶段主要就是对第一阶段给出的Proposal进行redifiment,既然要更为精确地得到proposal,就需要进一步提取更为精确的特征。作者在这个部分采用了以下几个手段:
略微扩大proposal范围进一步提取局部特征
扩大范围很好理解,提高proposal内的特征总量,注意这个扩大量不是越大越好,文章中给出了实验结果:
进一步提取局部特征其实就是提取proposal中的局部特征。具体方法就是将proposal中的点转到局部的标准坐标系下面。什么是proposal的局部标准坐标系大家看原文以及下图,很好理解了,就是在proposal中定义了统一标准的原点以及坐标轴,如下:
得到proposal标准坐标系之后,我们进行进一步的局部空间特征提取。这次的特征输入包括每个点在proposal标准坐标系下的位置,点的反射强度,第一阶段的MASK值,也就是是前景点还是背景点以及其距离信息,距离信息用欧式距离来表示,也就是 d = x 2 + y 2 + z 2 d= \sqrt{x^2+y^2+z^2} d=x2+y2+z2 ,注意这里头的xyz是在原来坐标系下的xyz,这个特征是很有必要的,因为距离在点云中对特征的影响比较大。得到这些特征之后,通过全连接层进行编码,在与第一阶段的特征进行连接,就得到了第二阶段的完整的特征描述,之后就是利用这些特征进行proposal的refinement。
第二阶段的LOSS的定义与第一阶段类似,主要就是这次bin的尺度小了一点,因为本来就是微调了。具体大家可以看看论文。 总结及个人思考 总的来说这个算法偏向于如果去提高精度,但是对于计算速度没有没有进行考虑。比如说Pointnet++作为主干网络本来是就很耗时间的,比如说后面对每个proposal进行扩大,又得遍历一遍整个点云。
还有一点,其实在作者之后的实现中(OpenPCDet项目)中,作者取消了了bin-based的loss计算方式,还是采用了直接回归的方式。
本专栏教程将记录从安装carla到调用carla的pythonAPI进行车辆操控并采集数据的全流程,带领大家从安装carla开始,到最终能够熟练使用carla仿真环境进行传感器数据采集和车辆控制.
第四节 介绍carla中的地图 本小节的主要内容是介绍carla中的地图的种类和修改方法.
章节内容介绍:
第1小节介绍了carla中包含的地图。第2小节介绍了地图的加载方法。第3小节介绍了闪退问题及其解决方法。附录部分展示了鸟瞰图和道路图。 1.carla0.9.12中包含的地图 运行carla服务器之后,再通过下面的脚本可以打印出地图.
从其中关键的函数是调用get_available_maps().
# 生成汽车流 import glob import os import sys # ============================================================================== # -- Find CARLA module --------------------------------------------------------- # ============================================================================== try: sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % ( sys.version_info.major, sys.version_info.minor, 'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0]) except IndexError: pass # ============================================================================== # -- Add PythonAPI for release mode -------------------------------------------- # ============================================================================== try: sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/carla') sys.path.append("../examples/") except IndexError: pass import carla # Connect to the client and retrieve the world object try: client = carla.
学习unity3d的第一天 建立一个由键盘控制走路,鼠标控制方向的对象
构成对象:地形(Terrain)、player(创立的对象)、Sphere(在对象创立的对象)、Camera(跟随在Sphere的摄像机)
键盘控制走路的代码:
public class playmove : MonoBehaviour { public float speed; public CharacterController playercontroller;//角色控制器 void Update() { float x, z; x = Input.GetAxis("Horizontal");//水平 z = Input.GetAxis("Vertical");//垂直 Vector3 move; move = transform.right * x + transform.forward * z;//控制按键操控的方向变换 playercontroller.Move(move * speed * Time.deltaTime);//设置时间 } } 解析: 1、添加角色控制器 在Player上添加CharacterController组件 2、移动方法 这种方法一般用于3D游戏Player进行移动 Input.GetAxix()得到游戏轴上的输入 "Horizontal"水平轴 "Vertical"垂直轴 检测x、z轴的按键输入输入 move = transform.right * x + transform.forward * z 相当于 move=(0,0,0) transform.right * x=(x,0,0) transform.
工作流程初识 一、先打开软件,创建一个新的项目,找到一个素材,把片头和片尾的文字去掉。 image.png 二、先定格到片尾位置找到要去掉的文字,然后用键盘方向左键固定到帧的位置。 image.png 去除片头文字,也是同样将指针定格到开头,然后用方向右键固定具体帧位置,然后选择剃刀工具,点击一下然后把它剪断。然后切换成选择工具按Delete键直接切除。然后发现前面有个白色空档,这个时候我们直接鼠标右键点击波纹删除。
image.png image.png 最后一定要导出选择H264以MP4格式的文件然后进行保存(Ctrl+s)。
前引 相信大家 MySQL 都用了很久了,各种 join 查询天天都在写,但是 join 查询到底是怎么查的,怎么写才是最正确的,今天我就和大家一起学习探讨一下
索引对 join 查询的影响 数据准备 假设有两张表 t1、t2,两张表都存在有主键索引 id 和索引字段 a,b 字段无索引,然后在 t1 表中插入 100 行数据,t2 表中插入 1000 行数据进行实验
CREATE TABLE `t2` ( `id` int NOT NULL, `a` int DEFAULT NULL, `b` int DEFAULT NULL, PRIMARY KEY (`id`), KEY `t2_a_index` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE PROCEDURE **idata**() BEGIN DECLARE i INT; SET i = 1; WHILE (i <= 1000)do INSERT INTO t2 VALUES (i,i,i); SET i = i +1; END WHILE; END; CALL **idata**(); CREATE TABLE t1 LIKE t2; INSERT INTO t1 (SELECT * FROM t2 WHERE id <= 100); 复制代码 有索引查询过程 我们使用查询 SELECT * FROM t1 STRAIGHT_JOIN t2 ON (t1.
PR剪辑自学之路 一、剪辑大致流程 01.导演(客户)沟通02.熟悉素材03.素材整理04.结构搭建05.粗剪06.精剪07.配音配乐08.检查输出
二、PR软件的介绍 Adobe Premiere是由Adobe公司开发的一款非线性编辑的实拍编辑软件,可用于图像设计、视频编辑与网页开发,是Adobe Creative Suite套装的一部分。
适用对象:
Premiere Pro是视频编辑爱好者和专业人士必不可少的视频编辑工具。它可以提升您的创作能力和创作自由度,它是易学、高效、精确的视频剪辑软件。Premiere提供了采集、剪辑、调色、美化音频、字幕添加、输出、DVD刻录的一整套流程,并和其他Adobe软件高效集成,使您足以完成在编辑、制作、工作流上遇到的所有挑战,满足您创建高质量作品的要求。
1.配置如下: 2.编译、运行 使用那个都可以
运行结果:
selenium因为找不到元素会抛出异常,导致执行结束
可以考虑使用driver.find_elements(),找不到元素时就会返回空列表,使用if-else语句,判断列表是否为空,非空,则正常找到元素,进行后续代码执行;空,则直接跳过,执行其他代码
if len(list) != 0 #判断列表的长度是否为0
# 非0,执行的代码
else:
#为0,执行的代码
前言 今天我想和你分享的是C语言程序结构中的顺序结构。
顺序结构 1.什么是顺序结构?
顺序结构是按照代码的书写顺序从前到后执行的结构。是C语言最简单、最基本的结构。
2.为什么顺序结构是最基本、最简单的结构?
因为顺序结构有以下三个特点
1.自上而下
2.没有分支
3.依次执行
3.如何理解并运用顺序结构?
这里我写一个简单的两数求和代码
#include<stdio.h> int main() { int a = 20; int b = 10; int sum = 0; sum = a + b; //求a和b的和 printf("sum=%d\n",sum); //打印a和b的和 return 0; } 当我按control+f5进入程序时,首先程序从上而下开始运行,先读取了我主函数内的第一行代码 int a = 20,然后程序继续往下走,读取了我的第二行代码 int b = 10 。 这里依旧没有遇到retrun 0,所以程序并不会结束。 程序继续往下走,这里程序读取了我创建的一个变量sum变量来存放a+b的值。程序有往下走,读取到了printf()函数,在屏幕上输出了sum=30。最后程序走到return 0 ,程序也就结束了。这就是一个简单的顺序结构程序。顺序结构就是程序运行时自上而下的依次执行我们所写的代码。
总结 本篇文章主要介绍了C语言的顺序结构。希望能够帮到你,你们的支持与建议都是我前进的动力,最后祝愿我们一起进步!
SQL的语法格式如下
SELECT DISTINCT < select_list > FROM < left_table > < join_type > JOIN < right_table > ON <join_condition> WHERE < where_condition > GROUP BY < group_by_list > HAVING < having_condition > ORDER BY < order_by_condition > LIMIT < limit_number > 想掌握最基础的三个:left join、right join、inner join
假设有A表和B表两张表
A表:id、员工名、部门 B表:主键id、部门名、部门主管
我们都知道数据库在进行表连接即(join)操作的时候,是进行笛卡尔积操作
A表两行记录,B表两行记录。进行迪卡积就变成2 x 2=4行记录
(不考虑数据真实性)假设如上A、B两张表进行笛卡尔积操作结果就是如下
第一个是左连接:A Left Join B 得到集合(A)
left join 特点是保留A表所有字段,如果没有匹配到连接条件则用null填充
对应sql示例
select A.*,B.* from A left join B on A.
Django内置的User对象,已经包含了一些主要的属性,如username、password、email等,但实际情况可能还需要昵称、头像等其他属性,仅仅使用内置的User属性是不够的。
通过使用AbstractUser可以对User进行扩展使用,添加用户自定义的属性。
User模型源码如下。
class User(AbstractUser): class Meta(AbstractUser.Meta): swappable = 'AUTH_USER_MODEL' 由此可见,User对AbstractUser仅仅是继承,没有进行任何的扩展。所以我们继承AbstractUser可以获得User的所有特性。
model中使用 继承AbstractUser
from django.contrib.auth.models import AbstractUser class MyUser(AbstractUser): pass 全局settings.py中设置 覆盖默认的user model
AUTH_USER_MODEL = 'app.MyUser' 在admin.py中注册MyUser from django.contrib import admin from .models import UserProfile admin.site.register(UserProfile,UserAdmin) #用UserAdmin去注册UserProfile 欢迎关注,互相学习,共同进步~ 我的个人博客
我的微信公众号:编程黑洞
相同点
都能返回文件的绝对路径。
>>> import os >>> os.path.realpath(__file__) f:\work\tmp\test.py >>> os.path.abspath(__file__) f:\work\tmp\test.py 输出:
f:\work\tmp\test.py
f:\work\tmp\test.py
不同点
example:
file_a
file_b -> file_a # 软连接指向a
>>> import os >>> os.path.abspath(file_b) /tmp/file_b # 会得到指向的文件的路径 >>> os.path.realpath(file_b) /tmp/file_a 欢迎关注,互相学习,共同进步~ 我的个人博客
我的微信公众号:编程黑洞
简介 并不是真正的实时处理框架,只是按照时间进行微批处理进行,时间可以设置的尽可能的小。
将不同的额数据源的数据经过SparkStreaming 处理之后将结果输出到外部文件系统
特点 低延时
能从错误中搞笑的恢复: fault-tolerant
能够运行在成百上千的节点
能够将批处理、机器学习、图计算等自框架和Spark Streaming 综合起来使用
粗粒度 Spark Streaming接收到实时数据流,把数据按照指定的时间段切成一片片小的数据块,然后把小的数据块传给Spark Engine处理。
细粒度
数据源
kafka提供了两种数据源。
基础数据源,可以直接通过streamingContext API实现。如文件系统和socket连接高级的数据源,如Kafka, Flume, Kinesis等等. 可以通过额外的类库去实现。 基础数据源 使用官方的案例 /spark/examples/src/main/python/streaming
nc -lk 6789
处理socket数据
示例代码如下: 读取socket中的数据进行流处理
from pyspark import SparkContext from pyspark.streaming import StreamingContext # local 必须设为2 sc = SparkContext("local[2]", "NetworkWordCount") ssc = StreamingContext(sc, 1) lines = ssc.socketTextStream("localhost", 9999) words = lines.flatMap(lambda line: line.split(" ")) pairs = words.map(lambda word: (word, 1)) wordCounts = pairs.
什么是StatefulSet? 是用来创建有状态应用,可以通过过某种方式记录这些状态,然后在 Pod 被重新创建时,能够为新 Pod 恢复这些状态。
什么是有状态应用?
首先是需要有数据的持久化,及时Pod被重启后,也能恢复,与重启前保持一致。然后是应用创建的所有pod有依赖关系,顺序的创建、需要运行在指定的宿主机上,并且都有对应的网络标志。
应用场景?
分布式应用,它的多个实例之间,往往有依赖关系,比如:主从关系、主备关系。
使用StatefulSet 创建StatefulSet 创建yaml文件定义StatefulSet对象如下,与Deployment比较,多了一个serviceName字段,这个是用来指定StatefulSet锁管理的pod是用域名访问是通过该service所设定的。
apiVersion: apps/v1 kind: StatefulSet metadata: name: redis-sts spec: serviceName: redis-svc replicas: 2 selector: matchLabels: app: redis-sts template: metadata: labels: app: redis-sts spec: containers: - image: redis name: redis ports: - containerPort: 6379 创建StatefulSet对象
[root@k8s-worker1 zwf]# kubectl apply -f statefulset.yaml -n zwf statefulset.apps/redis-sts created [root@k8s-worker1 zwf]# kubectl get sts -n zwf NAME READY AGE redis-sts 2/2 54s 查看创建的Pod会发现,命名不在是随机创建的名字,而是有了顺序号,从0开始,而k8s也会按照这个顺序一次创建。
先来看一看案件的背景:
某地警方接到受害人报案称其在某虚拟币交易网站遭遇诈骗,该网站号称使用“USTD 币”购买所谓的“HT 币”,受害人充值后不但“HT 币”无法提现、交易,而且手机还被恶意软件锁定勒索。警方根据受害人提供的虚拟币交易网站调取了对应的服务器镜像并对案件展开侦查。 本次wp参照了大佬的博客:大佬博客!!!
检材一 1、检材1的SHA256值为: 用取证大师直接计算:
2、 3、 用火眼仿真就直接能看出来
或者是直接可以仿真后用命令查看:cat /etc/redhat-release
4. 检材1系统中,网卡绑定的静态IP地址为 如图所示 172.16.80.133
(大型补充现场:在这里我学到了连接工具的方法(不管是windterm和XShell都很好使!!)主要是为了看命令之类的都会很方便,还是好好学习一下!!)
在这里我们知道了主机的IP,是在172网段。接下来我们对虚拟机网络进行设置:
将网络模式更改为NAT模式,将子网IP设置为172.16.80.0(与虚拟主机一个网段),然后再对DHCP进行设置:
保存后等待生效,用windterm直接可以ssh连接成功。连接上后如图所示:
(含泪感谢大佬QAQ) 5. 检材1中,网站jar包所存放的目录是(答案为绝对路径,如“/home/honglian/”) 找不到咱就直接搜,如图:
\web\app\jdk1.8.0_181\bin\jar 6. 检材1中,监听7000端口的进程对应文件名为 先推荐一个java的反编译工具:JD GUI
在看历史命令记录的时候,我们会发现在同一个路径下的jar包有很多个,这个时候我们在没有办法(我没有办法)启动起网站的时候(因为发现和网站相关的很多文件被删除了),可以进入路径中对其一个一个的进行分析。最后我们发现,在cloud.jar文件中,发现了和7000端口有关的东西。
现在就可以看出,7000端口的进程对应文件名是cloud.jar 7. 检材1中,网站管理后台页面对应的网络端口为(答案填写阿拉伯数字,如“100”) 用证据分析软件分析检材,发现有一个网址是后台管理页面
黑客搭建网站之后肯定会留下维护登录记录,9090就是后台管理界面的网络端口号 8. 检材1中,网站前台页面里给出的APK的下载地址是(答案格式如下:“https://www.forensix.cn/abc/def”) 找不到等会说
9. 检材1中,网站管理后台页面调用的用户表(admin)里的密码字段加密方式为? C 10. 分析检材1,网站管理后台登录密码加密算法中所使用的盐值是 检材二 根据IP地址落地及后续侦查,抓获了搭建网站的技术员,扣押了其个人电脑并制作镜像“检材2”,分析所有掌握的检材回答下列问题
11. 检材2中,windows账户Web King的登录密码是 在解压了检材二之后,我们用某仿真系统直接打开,就会跳出一个提示,是否还要保存Web King的登录密码
这个时候我们就可以知道这个用户的登录密码是135790 12. 检材2中,除检材1以外,还远程连接过哪个IP地址?并用该地址解压检材3 172.168.80.128 找到了两个网址,尝试了一下,就是这个网址
13. 检材2中,powershell中输入的最后一条命令是 ipconfig
具体在哪里找到的记不得了,反正不要把他和linux的命令弄混!!!!
14. 检材2中,下载的涉案网站源代码文件名为 没找到,真无语
15. 检材2中,网站管理后台root账号的密码为 root 如图 16. 检材2中,技术员使用的WSL子系统发行版本是(答案格式如下:windows 10.
Machine Learning at the Wireless Edge" description: “概述无线网络边缘端的分布式学习的一些成果,包括两个主题:联邦学习和去中心化学习”
原博文:https://windy810.github.io/blog/2022-10-28-Machine_Learning_at_the-_Wireless_Edge/
URL: https://www.ee.bgu.ac.il/~haimp/VincentPoorMLCOM22.pdf
URL 2: 【【直播回放】IEEE TNSE杰出讲座系列(五) 2022年10月28日8点场】 引言(机器学习与无线网络的关联): 使用机器学习优化通信网络在移动设备上学习 1. Motivation 1.1 机器学习最新现状 大量数据可用,计算能力提高标准的机器学习是集中式的,可以访问所有数据在云端使用软件工具运行模型,通过特殊硬件加速 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SbtVUWHT-1667306608763)(https://imgur.com/xCQo3Mx)]
1.2 无线边缘的机器学习 集中机器学习不适合一些新兴应用,如:自动驾驶、急救网络、医疗网络这些场景特殊的原因:数据由边缘产生、有限容量上行链路 、低延迟和高可靠性、数据隐私/安全、可扩展性和局部性 以上原因促使了机器学习需要更接近网络边缘
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vHle7CbY-1667306608765)(https://imgur.com/2z4ZBoQ)]
1.3 网络化机器学习模型 标准机器学习:数据存储在云端;在云端进行训练;没有隐私联邦机器学习:云与用户设备同时机器学习;只有部分数据存储在云端;促进隐私去中心化机器学习:没有类似于云的基础设施;数据完全分布;协作智能;隐私 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-luzstP64-1667306608766)(https://imgur.com/NpXEPP8)]
2. 联邦学习 2.1 基本架构 【数据集】终端用户(UE)使用本地的原始数据→
【训练】终端用户使用共享模型进行训练→
【联邦计算】边缘节点(AP)从终端收集权重并更新共享模型→迭代至收敛
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uEk0CQRb-1667306608766)(https://imgur.com/aFewsqH)]
2.2 需要解决的问题 与边缘节点的交流只能通过无线信道无线介质是共享的而且有限:每轮更新只能选取部分设备;因为干扰传输不可靠 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cQTlGjYk-1667306608766)(https://imgur.com/hPUU0zs)]
2.3 调度机制 随机调度轮询:分组再依次选组比例公平:选择最强信噪比的终端用户 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zsghaKnF-1667306608767)(https://imgur.com/65XiqPK)]
2.4 性能指标 更新的前提条件: 终端用户被调度器选择接收的信噪比大于解码阈值 量化训练有效性的指标:达到解法精度所需要的沟通轮次 【注】 ϵ \epsilon ϵ-accurate solution:最大化一个强凸函数(原始解和对偶解是相同的),此时,只有两个解,原始解和对偶解,彼此在 ϵ \epsilon ϵ之内
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8uvTzUW-1667306608767)(https://imgur.com/7RbB76r)]
【参数注解】 ϵ \epsilon ϵ是试图实现的二元差, θ \theta θ是信噪比阈值,其他如图所示(具体细节可以暂时不注意)
Apk体积优化一直是迭代中的不可忽略的问题, 这次要说的是apk体积的检测方法, 毕竟优化都是基于检测的;
当然, 在Android Studio中有Apk Analyser工具可以使用, 但是需要导出, 或者在每个版本迭代中生成报告, 手动生成apk后拖入也是比较麻烦的; 使用Matrix 提供的工具 ApkChecker可以独立检测apk并生成报告, 下面介绍下打包检测过程; 1.下载ApkChecker.jar https://download.csdn.net/download/qq_23992393/86871532
独立的工具jar包, 需要java环境可用
2. 命令封装 如果想查看支持的命令说明, 可以运行:
java -jar matrix-apk-canary-2.0.8.jar 一般项目中会通过配置文件方式设置, 直接看下demo中的设置:
2.1 目录: 独立将几个需要的文件独立到一个文件夹中,便于移动管理
matrix_apk_checker_config.json:
{ "--apk":"[项目apk目录]", "--mappingTxt":"[项目mapping.txt目录]", "--output":"apk-checker-result", "--format":"mm.html,mm.json", "--formatConfig": [ { "name":"-countMethod", "group": [ { "name":"Android System", "package":"android" }, { "name":"java system", "package":"java" }, { "name":"com.tencent.test.$", "package":"com.tencent.test.$" } ] } ], "options": [ { "name":"-manifest" }, { "name":"-fileSize", "--min":"10", "--order":"desc", "--suffix":"png, jpg, jpeg, gif, arsc"
// 这是后台数据 var dataSource = [{ "saturday": 2764, "project": "过店人次", "thursday": 3389, "sum": 18958, "sunday": 2364, "tuesday": 2945, "wednesday": 3452, "friday": 1398, "monday": 2646 }, { "saturday": 17, "project": "环比上周", "thursday": 73, "sum": 205, "sunday": 9, "tuesday": 48, "wednesday": 54, "friday": -39, "monday": 43 }, { "saturday": -36, "project": "对比今年均值", "thursday": -21, "sum": -261, "sunday": -45, "tuesday": -32, "wednesday": -20, "friday": -68, "monday": -39 }, { "saturday": "296 (17 - 18点)"
前言 为了使软件开发过程有章可循,保证软件质量,加强开发管理。 目录 文件规范
命名规范
代码规范
Maven使用规范
文件规范 文件必须使用UTF-8编码
License或者copyright声明信息。(如果需要声明)
命名规范 项目命名规范
项目编号:项目英文/中文拼音名称_开发组编号_序列号(序列号由3位数字组成,不足的用'0'补齐)。
项目文档:项目英文/中文拼音名称_文档名称_序列号_编写人名称/编号_日期
数据库命名规范
数据库表命名均遵循以下规范:
类型名模块名存储信息名词(多个单词用下划线分隔),全部小写,例如:fun_mail_message。(fun前缀表示功能,com前缀表示组件,sec前缀表示权限)
数据库字段命名遵循以下规范:
存储信息名词(多个单词用下划线分隔),全部小写,例如:message_id。
Java源码命名规范
目录 的命名
项目resty-example:
src/main/java 源码目录
src/main/resources 资源文件目录
src/main/webapp web文件目录
src/test/java 测试源码目录
src/test/resources 测试资源文件目录(如果不是特例可以直接读取main下的资源文件)
复杂项目或需要被别人依赖的项目分包:
发布依赖包命名 模块-系统类型-definer,示例 user-api-definer 和 user-service-definer,主要存放定义的Model和Interface等其他项目使用你的功能所必要的内容,不需要具体的实现代码(特别是rpc场景),保证有效依赖,去除无意义依赖
具体的实现包命名 模块-系统类型-provider,示例 user-api-provider 和 user-service-provider,主要存放支持definer的具体实现
Package 的命名
Package 的名字应该都是由一个小写单词组成,包的命名一般都是按照域名+公司名+项目名+具体反映包内容的名字。例如:cn.dreampie.xxx。
此外,对于包名我们做如下约定:
工具函数类包名前缀为 .utils
Servlet类包名前缀为 .servlet
逻辑功能类包前缀为 .fun
具体的逻辑功能内容前缀为功能的缩写 .fun.order
Class 的命名
类名是个名词,采用大小写混合的方式,每个单词的首字母大写。尽量使你的类名简洁而富于描述。例如:DataFile或InfoParser。使用完整单词,避免缩写词(除非该缩写词被更广泛使用,像URL,HTML)。异常类最后加上「Exception」(例:SQLException)。另外,接口的命名和类的命名大体相同,只是接口一般用形容词。例如:Runnable。
Class 变量的命名
变量的名字必须用一个小写字母开头。后面的单词用大写字母开头,变量名一般为动词。变量名不应以下划线或美元符号开头,尽管这在语法上是允许的。例如:debug 或 inputFileSize。
Static Final 变量的命名
Static Final 变量的名字应该都大写,并且指出完整含义,多个单词之间用下划线分隔。例如:MAX_UPLOAD_FILE_SIZE=1024。
文章目录 0 前言1 java web 管理系统 毕设选题2 java web 平台/业务系统 毕设选题3 游戏设计、动画设计类 毕设选题 (适合数媒的同学)4 算法开发5 数据挖掘 毕设选题6 大数据处理、云计算、区块链 毕设选题7 网络安全 毕设选题8 通信类/网络工程 毕设选题9 嵌入式 毕设选题10 开题指导11 最后 0 前言 Hi,大家好,这里是丹成学长,大四的同学马上要开始毕业设计啦,大家做好准备了没!
学长给大家详细整理了计算机毕设最新选题,对选题有任何疑问,都可以问学长哦~
1 java web 管理系统 毕设选题 java web 系统往年很常见,不太推荐纯管理系统作为毕设了。
学籍管理系统设计与实现
教务管理系统设计与实现
网上考试系统设计与实现
在线考试系统设计与实现
题库(及试卷)管理系统设计与实现
网络远程作业处理系统设计与实现
毕业论文管理系统的设计与实现
毕业设计管理系统设计与实现
毕业生学历证明系统设计与实现
基于jsp的毕业生派遣管理系统设计与实现
XX学院信息化办公平台-公文、组织机构管理系统的设计与实现
XX学院师资培养管理系统设计与实现
基于web的师资管理系统设计与实现
高校评教教师工作量管理系统设计与实现
教师信息管理系统设计与实现
教师档案管理系统设计与实现
教学进度管理系统设计与实现
网络教学平台-教师子系统设计与实现
学生日常行为评分管理系统设计与实现
学生成绩学分制管理系统设计与实现
学生社团管理系统设计与实现
可视化学生宿舍管理系统设计与实现
班级管理系统设计与实现(或者是班级网站)
高校实验室教学管理系统的设计与实现
校园新闻管理系统设计与实现
基于SSM的学科竞赛管理系统
办公管理系统设计与实现
库存管理系统设计与实现
物资管理系统设计与实现
公文管理系统设计与实现
前提: VTK-已安装(sudo apt-get install libvtk7.1-qt libvtk7.1 libvtk7-qt-dev) cmake version 3.10.2 已安装 1、下载PCL
git clone https://github.com/PointCloudLibrary/pcl.git 2、进入目录编译文件
cd pcl mkdir build && cd build cmake .. make -j8 3、编译后成功
sudo make install 至此,PCL安装成功!
文章目录 0 简介1 人脸识别 - 常用实现技术1.1 基于几何特征的人脸识别方法1.2 初级神经网络方法。1.3 深度学习方法。 2 人脸识别算法缺陷3 人脸识别流程3.1 相关数据集3.2 对齐3.3 仿射变换3.4 人脸目标检测3.5 人脸特征提取3.5.1 分类模型有哪些3.5.2 度量学习模型——FaceNet为例 3.6 人脸识别(特征分类)3.6.1 欧氏距离3.6.2 余弦距离3.6.3 Joint Bayesian 方法 4 实现过程4.1 自己构建人脸数据集4.1.1 拍照程序 4.2 预处理4.3 人脸特征提取 5 识别效果5.1 人脸检测效果5.2 人脸识别结果 6 最后 0 简介 今天学长向大家介绍一个机器视觉的毕设项目,基于深度学习的人脸识别
:基于深度学习的人脸识别【全网最详细】 - opencv 卷积神经网络
1 人脸识别 - 常用实现技术 人脸识别主要研究的是如何获得高效的特征, 并利进行人脸匹配的计算。 至今为止人脸识别的算法已经很多。
1.1 基于几何特征的人脸识别方法 该方法所考虑的特征相对朴。 所谓的几何特征是指人脸图像上各器官等的相对位置或相对距离所组成的矢量, 具体指利用人工方式标出人脸图像特征点位置, 对标定好的特征点计算相对距离; 将所得的多个距离按照预定顺序组成一个矢量, 该矢量即为几何特征。 Nicholas Roeder 和 Xiaobo Li 对几何特征的提取进行了详细研究, 由于几何特征只是粗略的描述的人脸图像, 因此效果并不如人意。
由于之前用的是wsl ubuntu发现编译SDK一直失败,别人提示改用VMware创建虚拟机,所以在win上的这里【控制面板-程序-启用或关闭windows功能】:
关闭了原来勾选的【适用于Linux的Windows子系统】和【虚拟机平台】,并且重启了电脑。
但是!但是!但是!但是!但是!但是!
vmware创建虚拟机的时候,在点了开启此虚拟机之后,提示了这个东西【侧通道缓解】:
起初没在意,结果变得特别卡,像老头机一样。
后面网上搜索之后,说是开了Hyper-v,vmware就会出现这种情况,我之前明明关了,直到打开任务管理器,然后在服务中关闭了Hyper service,在vmware编辑此虚拟机这里,点高级右边有个开启禁用侧通道缓解,变得没之前卡。
目录
1.TS把JS变成了静态类型的语言,可以给变量指定类型
2.JS中的函数是不考虑参数的类型和个数的,但是TS会考虑函数的参数类型和个数,且要规定返回值类型。
3.常见的TS类型
1.可以直接使用字面量进行类型声明 字面量声明的应用:可以使用 | 来连接多个类型(联合类型)
& 表示同时满足
2.any类型(不建议使用)
表示的是任意类型,一个变量设置类型为any后相对于对该变量关闭了TS的类型检测。
使用TS时,不建议使用any类型
编辑
3.unknown类型
4.void 虽然说void 用来表示空,以函数为例,就表示没有返回值的函数。但是会默认返回一个 undefined
5.never 也表示空,但真的就是啥都不返回
6.object 对象类型(不推荐写) 推荐这样写:let a :{name:string}; 要指定对象里面的属性
对象的可选属性(重要)
7.array 实际开发中希望数组里面存的都是同一类型的数据
8.tuple 元组,就是固定长度的数组
解构赋值配合元组的使用 9.enum 枚举 4.类型的别名
5.类型定义的注意点
注意点:
//类型推论,a没有设定类型,在初始化之后,系统会为之设定一个类型,这个过程就是类型推论。
let a = 200; //等价于 let a:number = 20;
非严格模式下:
//undefined 类型可以赋值给 void 类型。 undefined类型的数据只有一个值就是undefined
//null 类型可以赋值给void类型。 null类型的数据只有一个值就是null
//但是 null类型 和 undefined类型不能相互赋值。
1.TS把JS变成了静态类型的语言,可以给变量指定类型 注意点1:这里就算报错,编译时也会生成一个对应的js文件,因为给a赋值字符串是符合js语法的,是可以编译的,这样可以让初学ts的更容易上手。
注意点2:编译后产生的js文件中会出现 var 这些,是因为TS可以把代码编译成任意版本的JS代码 注意点3:变量先声明,再赋值 和 声明后直接赋值的区别
今天编写项目运行起来报这个错误,找了半天才找到这个错误在哪,这个错误是发生在element-ui里面的;
Element-ui中的el-form-item中少写了一个prop所以报这个错!
给el-form-item添加上prop就可以了!!
什么是不优雅的参数校验 后端对前端传过来的参数也是需要进行校验的,如果在controller中直接校验需要用大量的if else做判断
以添加用户的接口为例,需要对前端传过来的参数进行校验, 如下的校验就是不优雅的:
@RestController @RequestMapping("/user") public class UserController { @PostMapping("add") public ResponseEntity<String> add(User user) { if(user.getName()==null) { return ResponseResult.fail("user name should not be empty"); } else if(user.getName().length()<5 || user.getName().length()>50){ return ResponseResult.fail("user name length should between 5-50"); } if(user.getAge()< 1 || user.getAge()> 150) { return ResponseResult.fail("invalid age"); } // ... return ResponseEntity.ok("success"); } } 针对这个普遍的问题,Java开者在Java API规范 (JSR303) 定义了Bean校验的标准validation-api,但没有提供实现。
hibernate validation是对这个规范的实现,并增加了校验注解如@Email、@Length等。
Spring Validation是对hibernate validation的二次封装,用于支持spring mvc参数自动校验。
接下来,我们以springboot项目为例,介绍Spring Validation的使用。
实现案例 本例子采用 spring validation 对参数绑定进行校验,主要给你提供参数校验的思路。针对接口统一的错误信息(比如绑定参数检查的错误)封装请看
Tez引擎相关配置参数如下:
hive-site.xml: 1. hive.exec.parallel:Hive并发执行,true表示并发,即开启作业并行。若为true一个sql语句中分解的多个job没有顺序关系时会并发执行,有顺序关系时会按顺序执行,资源充足时建议开启。默认false。 2. Hive.exec.parallel.thread.num:默认8,最多并行的作业数量,即1个sql最多允许8个mr或tez作业并行。 3. hive.execution.engine:Hive引擎,默认mr,一般设为tez。 4. hive.tez.cpu.vcores:设置小于1时,将被mapreduce.map.cpu.vcores替代。每个容器运行所需的vcpu个数。 5. hive.tez.auto.reducer.parallelism:配置是否开启作业自动调节在Reduce阶段的任务并行度,一般开启。 6. hive.optimize.countdistinct:去重并计数的作业会分成两个作业来处理,为了减缓sql数据倾斜。 7. hive.tez.container.size:不小于或者是yarn.scheduler.minimum-allocation-mb的倍数。默认值-1猜测和最小配置内存一直,一般建议是该最小值的1倍或2倍。 8. tez.task.resource.memory.mb:TEZ容器中已启动任务使用的内存量。通常,此值是在DAG中设置的,默认1024MB。 9. hive.tez.java.ops:设置Container的jvm参数,默认值(Hortonworks建议):–server –Djava.net.preferIPv4Stack=true–XX:NewRatio=8 –XX:+UseNUMA –XX:UseG1G(默认80%*hive.tez.container.size),在hive 2.x的官方文档中没有找到这个参数,网上找到有这个值。 10. hive.auto.convert.join.noconditionaltask:是否将多个mapjoin合并为一个,默认true。建议默认值。 11. hive.auto.convert.join.noconditionaltask.size:这个参数使用的前提是hive.auto.convert.join.noconditionaltask值为true,多个mapjoin转换为1个时,所有小表的文件大小总和小于这个值,这个值只是限制输入的表文件的大小,并不代表实际mapjoin时hashtable的大小。默认值:10000000(10MB),建议值:1/3* hive.tez.container.size。该参数取代了旧版本的hive.smalltable.filesize or hive.mapjoin.smalltable.filesize。 12. hive.vectorized.execution.enabled:是否启用向量化查询,默认false关闭,建议开启。 tez-site.xml: 13. tez.am.resource.memory.mb:集群中每个Tez作业对应的ApplicationMaster占用内存大小,默认1024MB。 14. tez.container.max.java.heap.fraction:基于yarn提供的内存,分配给java进程的百分比,默认是0.8,一般不用变。 15. tez.runtime.unordered.output.buffer.size-mb:如果不直接写入磁盘,使用的缓冲区大小,默认100MB,建议为0.1*container.size 16. tez.am.launch.cmd-opts:tez-site.xml,设置AM的jvm选项,启动TEZ任务进程期间提供的命令行选项。默认值:-XX:+PrintGCDetails -verbose:gc -XX:+PrintGCTimeStamps -XX:+UseNUMA -XX:+UseParallelGC(用于GC,默认的大小:80%*tez.am.resource.memory.mb)。建议:不要在这些启动选项中设置任何xmx或xms,以便tez可以自动确定它们。 17. tez.runtime.io.sort.mb:设置输出排序内存大小,默认100,建议:40%*hive.tez.container.size,一般不超过2G。 18. tez.runtime.unordered.output.buffer.size-mb:如果不直接写入磁盘,使用的缓冲区大小,默认100,建议:10%* hive.tez.container.size。 19. tez.am.container.reuse.enabled:容器(Container)重用,默认true,建议默认。 mapred-site.xml: 20. mapreduce.map.cpu.vcores:默认1,每个map任务的cpu数量。 21. mapreduce.reduce.cpu.vcores:默认1,每个reduce任务的cpu个数。对tez不起作用。 yarn-site.xml: 22. yarn.nodemanager.resource.memory-mb:nm的可分配的内存总大小,一般为物理内存的80%左右 23. yarn.scheduler.minimum-allocation-mb:container最小内存,根据实际,总32,2GB 24. yarn.scheduler.maximum-allocation-mb:container最大内存,总32,24GB 25. yarn.nodemanager.resource.percentage-physical-cpu-limit:管理的所有Container使用CPU的阈值。默认100%。 26. yarn.nodemanager.resource.cpu-vcores:nm能为container分配的最多cpu个数。 27.
一、概述 Helm 针对 Kubernetes 的 Helm 包管理器。Helm 的一般操作:
helm search: 搜索 chart
helm pull: 下载 chart 到本地目录查看
helm install: 上传 chart 到 Kubernetes
helm list: 列出已发布的 chart
# 查看帮助 helm --help 官方文档:https://helm.sh/zh/docs/helm/helm/ 二、Helm仓库(helm repo) 添加、列出、删除、更新和索引 chart 仓库。
1)添加 chart 仓库 helm repo add bitnami https://charts.bitnami.com/bitnami 2)列出已添加的仓库 helm repo list 3)从 chart 仓库中更新本地可用 chart 的信息 helm repo update bitnami 4)删除一个或多个仓库 helm repo remove bitnami 三、创建 chart(helm create) 使用给定名称创建新的 chart,该命令创建 chart 目录和 chart 用到的公共文件目录。
引言 Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介, 也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。
比如 kubectl 如果想向 API Server 请求资源,需要过三关,第一关是认证(Authentication),第二关是鉴权(Authorization), 第三关是准入控制(Admission Control),只有通过这三关才可能会被 K8S 创建资源。
一、K8S安全框架介绍 访问K8S集群的资源需要过三关:认证、鉴权、准入控制 普通用户若要安全访问集群API Server,往往需要证书、 Token或者用户名+密码;Pod访问,需要ServiceAccount K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段 都支持插件方式,通过API Server配置来启用插件。 1. Authentication:用于识别用户身份, 方式有: SSL证书,token, 用户名+密码等
2. Authorization:确认是否对资源具有相关的权限
3. Admission Control: 判断操作是否符合集群的要求
当kubectl ,ui,程序 等请求某个 k8s 接口,先认证(判断真伪),鉴权(是否有权限这么做?),
准入控制(能不能个这么干?)
二、认证(Authentication) 三种客户端身份认证:
HTTPS 证书认证:基于CA证书签名的数字证书认证 kube-apiserver etcd kubelet 连接kube-apiserver
kube-proxy连接 kube-apiserver
均采用 https传输方式
HTTP Token认证:通过一个Token来识别用户 客户端携带一个token来请求server端,如果server端含有这个token,那么认证成功否则失败
HTTP Base认证:用户名+密码的方式认证 比较原始的方式,在k8s中基本很少使用
三、授权鉴权(Authorization) RBAC(Role-Based Access Control,基于角色的访问控制):
负责完成授权(Authorization)工作。
文章目录 k8s安装遇到错误: failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kub加入集群报错 k8s安装遇到错误: failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kub 这是在kubeadm 进行初始化的时候,我一直以为需要kubelet启动成功才能进行初始化,其实后来发现只有初始化后才能成功启动。
出现这两个问题的原因完全是初始化配置的问题,ip地址一定要是你本机上的ip,哪怕是虚拟ip,你也让它先飘到该主机上。这只是提供思路,我自己弄了半天,弄过kubelet和docker的驱动,网上找过很多但都没有用,因为我有一台主机成功了,其他两台死活出现这个问题,就是我把配置文件同步弄过去的时候ip地址都要改成本机上的。还有什么timeout 40s啥的都遇到过,最终修改初始化配置后都成功了。
[root@master ~]# systemctl status kubelet.service ● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: inactive (dead) (Result: exit-code) since 四 2022-07-28 17:47:56 CST; 2h 2min ago Docs: https://kubernetes.io/docs/ Process: 20968 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS (code=exited, status=1/FAILURE) Main PID: 20968 (code=exited, status=1/FAILURE) 7月 28 17:47:56 master systemd[1]: Unit kubelet.
文章目录 一、K8S的网络模型与集群通信1 K8S网络模型与实现方案2 pod 内容器通信3 pod与pod通信3.1 pod在同一主机3.2 pod 在不同主机下 4 pod 与service通信5 service 是如何做到服务发现的?6 外网与service通信 二、k8s与各网络插件集成(flannel calico canal kube-router romana cni-genie)1 flannel2 calico 本次实验使用与k8s一个etcd集群生境环境建议使用单独的一套集群3 canal4 kube-router5 romana6 CNI-Genie7 组件小结总结: 引言: 再来亿点点知识 一、K8S的网络模型与集群通信 1 K8S网络模型与实现方案 k8s集群中的每一个Pod(最小调度单位)都有自己的IP地址,即ip-per-pod模型。
在ip-per-pod模型中每一个pod在集群中保持唯一性,我们不需要显式地在每个 Pod 之间创建链接, 不需要处理容器端口到主机端口之间的映射。从端口分配、命名、服务发现、 负载均衡、应用配置和迁移的角度来看,Pod 可以被视作独立虚拟机或者物理主机。
如下图,从表面上来看两个容器在docker网络与k8s网络中与client通信形式。
k8s是一套庞大的分布式系统,为了保持核心功能的精简(模块化)以及适应不同业务用户的网络环境,k8s通过CNI(Container Network Interface)即容器网络接口集成各种网络方案。这些网络方案必须符合k8s网络模型要求:
节点上的 Pod 可以不通过 NAT 和其他任何节点上的 Pod 通信
节点上的代理(比如:系统守护进程、kubelet)可以和节点上的所有Pod通信
备注:仅针对那些支持 Pods 在主机网络中运行的平台(比如:Linux):
那些运行在节点的主机网络里的 Pod可以不通过 NAT 和所有节点上的 Pod 通信
如此操作,是不是有点像美团?将配送业务外包(CNI)给三方公司(实现方案),骑手是通过哪种飞机大炮(网络)送餐的我不管,只要符合准时、不撒漏(模型要求)等相关规矩这就是一次合格的配送。
CNI 做两件事,容器创建时的网络分配,和当容器被删除时释放网络资源。 常用的 CNI 实现方案有 Flannel、Calico、Weave以及各种云厂商根据自身网络推出的CNI插件如华为的 CNI-Genie、阿里云Terway。
出现明明写了get、set方法,但是还是报错说无法set的原因是: 报错信息:
当我在进行测试MyBatis的高级映射之多对一的映射时,发现自己明明get\set方法都写了,但是就是报错,说不能set property ’ sname’ 。后来发现原来是resultMap中的properties属性中多了一个空格,
最后总结一下出现这种报错的三种原因:
没写get或set方法property中引号里面多了空格property中属性名称写错了(注意:这里的property中的属性名称需要和你的pojo属性类里面变量的名称一致)
组与权限 Linux的用户与权限一.账户管理1.0 创建用户useradd1.1 示例:1.1.1添加一般用户1.1.2.为新添加的用户添加组1.1.3.创建一个系统用户1.1.4.为新添加的用户指定home目录下1.1.5.建立用户且定制ID1.1.6.添加一个不能登录的账号 2.0 用户账号存储文件2.1每一行对应一个用户的账号记录2.2 各个字段含义如下图,他们各自用“:”号隔开 3.0 用户账号文件/etc/shadow3.1 每一行对应一个用户的密码记录 4.0 chage命令4.1 示例:4.2 小结: 5.0账号的初始设置5.1文件来源 6.0 设置更改用户命令passwd6.1 示例:6.2 扩展: 7.0 usermod命令7.1 示例: 8.0 删除用户指令/suerdel8.1 示例: 二. 用户账号和组账号Linux基于用户身份对资源访问进行控制1.0 用户账号2.0 组文件存放位置3.0 UID 和 GID3.1 如何查看用户的UID ,GID和组 4.0 组账号管理4.1 添加组账号命令groupadd4.2 扩展:4.3 添加,设置,删除组成员/gpasswd4.3.1 示例: 5.0 查询帐号信息5.1 finger命令5.2 w,who.users命令5.2.1 w5.2.2 who5.2.3 users 三. 文件/目录的权限和归属1.0 三种权限:2.0 查看文件/目录的权限和归属3.0 设置文件和目录的权限chmod3.13.1.1.将文件77.txt去除所有人不可读所有者可写权限:chmod ugo-r 77.txt3.1.2.设置所有人可读 所有者可写:chmod a+r 77.txt3.1.3.文件拥有者添加可执行操作:chmod u+x 77.txt3.1.4.所有人只可读 chmod 444 77.txt 4.0 权限掩码umask4.1 umask作用4.2示例: 5.0设置目录与文件归属/chown总结: Linux的用户与权限 前言 :在Linux操作系统中任何文件都属于某一特定的用户,而任何用户都隶属于至少一个用户组。用户是否有权限对某文件进行访问、读写及执行,受到系统严格约束。这种清晰、严谨的用户与用户组管理系统在很大程度上保证了Linux系统的安全性。
目标 登录Prometheus的9090端口页面的时候,需要输入用户名和密码,才能进入Prometheus页面。
设置密码 Prometheus配置密码不能是明文,必须经过bcrypt程序对密码进行Hash处理。
gen-pass.py vim gen-pass.py 内容如下:
import getpass import bcrypt password = getpass.getpass("password: ") hashed_password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()) print(hashed_password.decode()) 安装bcrypt模块 pip3 install bcrypt 设置密码 python3 gen-pass.py web.yml sudo vim /etc/prometheus/web.yml 内容如下:
basic_auth_users: admin: $2b$12$hNf2lSsxfm0.i4a.1kVpSOVyBCfIB51VRjgBUyv6kdnyTlgWj81Ay promtool验证密码 promtool check web-config /etc/prometheus/web.yml /etc/prometheus/web.yml SUCCESS 文件夹权限 sudo chown -R prometheus:prometheus /etc/prometheus 修改Sys V配置 sudo vim /etc/systemd/system/prometheus.service 添加一行内容如下:
--web.config.file=/etc/prometheus/web.yml 整个文件内容如下:
[Unit] Description=Prometheus Wants=network-online.target After=network-online.target [Service] User=prometheus Group=prometheus Type=simple ExecStart=/usr/local/bin/prometheus \ --config.file /etc/prometheus/prometheus.yml \ --storage.
目录:导读 前言一、场景案例二、登录接口三、测试数据准备四、CSV数据文件设置五、查看结果 前言 我们在压测登录接口的时候,如果只用一个账号去设置并发压测,这样的结果很显然是不合理的,一个用户并发无法模拟真实的情况
如果要压测登录接口,肯定得准备几百,甚至上千的账号去登录,测试的结果才具有可参考性
一、场景案例 我现在有一个登录接口,接口登录接口文档基本信息
访问地址:http://127.0.0.1:8000/api/v1/login/
请求类型:POST
请求头部:Content-Type: application/json
请求参数:{“username”:”test”, “password”:”123456”}
我现在要压测这个登录接口,需设置30,50,80,100的并发数,那至少需要准备100个账号和密码
二、登录接口 先保证一个账号和密码的时候能正常的请求成功
添加HTTP信息头管理器,添加 post 请求类型 Content-Type: application/json
查看结果
三、测试数据准备 上面的单个用户能请求成功,接下来准备测试数据,自己先去注册批量账号和密码,我这里以10个账号和密码为例
账号和密码按以下格式,中间逗号隔开,保存为login_user_psw.txt
test1,123456
test2,123456
test3,123456
test4,123456
test5,123456
test6,123456
test7,123456
test8,123456
test9,123456
test10,123456
四、CSV数据文件设置 添加配置元件,CSV数据文件设置
导入txt的数据文件,用2个变量user和psw中间参数默认是逗号隔开
接下来把账号和密码引用改成的变量
CSV数据文件设置参数说明:
文件名:导入你的txt文件绝对路径
文件编码:一般选UTF-8
变量名:你自己设置的变量,如果只有一个变量那就只写一个,有多个变量的时候中间用英文的逗号隔开
忽略首行:如果你的第一行就是测试的账号,默认False就行,如果第一行是title栏那就设置True忽略
分隔符:也就是你txt文件里面分割参数的符合,一般用英文逗号
是否运行带引用号:一般不用改,默认Fasle
遇到文件结束时循环:它会循环从txt文件取值,如果全部取完了想继续那就是True,如果想文件的数据用完就结束,比如注册不可以重复用,那就设置False
线程共享模式:默认所有的线程就行
五、查看结果 比如我把线程数设置为3,一个线程数就是代表1个用户
查看结构树,会有3个请求返回的结果,分别用不同的账号去登录了
1. SSM整合 1.1 配置流程 步骤1: 创建maven的web项目 步骤2: 添加依赖: <dependencies> <!--spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.6</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.23</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.
前言 Qt的五(四)种连接方式,在上一篇已经讲明,本篇主要分析在源码上是如何实现这几种连接方式的。本次源码为Qt 5.15.2搞懂务必认真阅读最后添加注释后的代码 connect时会做什么? 已知connect是可以实现一个信号连接多个槽的,并且Qt会为每一个信号创建一个槽链表。
所以其内部当发现(触发)connect时,就会把connect的“接收者和槽”加入到对应的信号的槽链表上。存储的就是接收者及其槽的索引(函数地址)。当然每一个接收对象也会记录与之连接信号,以便销毁时会通知信号将其断开。(后续会专门补这块的源码分析)
获取信号对应的槽 通常我们在跳转到一个信号的定义时,都会看到类似这种的代码
// SIGNAL 0 void TestMoc::testMocSignal(int _t1, int _t2) { void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t1))), const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t2))) }; QMetaObject::activate(this, &staticMetaObject, 0, _a); } 这里要重点关注QMetaObject::activate的第三个参数0,会根据这个索引值,把发送者(this)、信号函数的参数,传给activate函数,
void TestMoc::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { if (_c == QMetaObject::InvokeMetaMethod) { auto *_t = static_cast<TestMoc *>(_o); Q_UNUSED(_t) switch (_id) { case 0: _t->testMocSignal((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; case 1: _t->testMocSignal2((*reinterpret_cast< int(*)>(_a[1]))); break; default: ; } } else if (_c == QMetaObject::IndexOfMethod) { //····· } } QMetaObject::activate 最终是执行doActivate执行槽函数
Android开发基础-轮播图的实现-推荐1.5倍速_哔哩哔哩_bilibili
大家去看这个博主的,我照着做成功了,贼牛
ubuntu系统中的pycharm中目前集成的ros2相关第三方库不多,需要进行配置,以下为配置方法:
1. 首先确保ubuntu系统中已经安装ROS2
2. Pycahrm中配置rclpy包
2.1 进入pycahrm中的设置settings
2.2 进入项目解释器->下拉选择python解释器->选择show All,点击进入
2.3 点击1指向的图标,跳转小界面,点击其中的+号 ,添加/opt/ros/foxy/lib/python3.8/site-packages,这个路径包含rclpy的安装路径,点击site-packages可以找到rclpy包,至此可以添加成功路径
如果安装在其他路径,也是相同的方法找到对应的包安装路径进行添加,其他的包类似操作
文章目录 1、引入pom2、创建一个ssh连接配置3、修改application.properties配置文件 1、引入pom <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency> 2、创建一个ssh连接配置 package cn.com.baidu.jswyj.system.common.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.apache.log4j.Logger; import org.springframework.boot.context.embedded.ServletContextInitializer; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import org.springframework.stereotype.Component; import java.io.IOException; import java.util.Properties; @Component public class SshConfiguration implements ServletContextInitializer { protected final Logger log = Logger.getLogger(this.getClass()); public SshConfiguration() { try { Properties p = new Properties(); p.load(getClass().getResourceAsStream("/application.properties")); //如果配置文件包含ssh.forward.enabled属性,则使用ssh转发 if(p.getProperty("ssh.forward.enabled")!=null){ log.info("ssh forward is opend."); log.info("ssh init ……"); Session session = new JSch().getSession(p.getProperty("ssh.forward.username"),p.getProperty("ssh.forward.host"),Integer.valueOf(p.getProperty("ssh.forward.port"))); session.
在学习C语言中,我们可以到使用三种循环,分别是:for,while和do while。使用循环可以重复执行多条语句。这些语句被循环的次数是由循环的条件控制的,因此也被称为控制表达式,控制表达式是一种标量类型的表达式,同理也可以将其认定为算术表达式的一种。假设控制表达式的结果为0,则循环的条件为false,反之则为true。此外,语句 break 和 continue 用于在一次循环还未执行完时,跳转出循环或返回到循环头部。
目录
一.for循环
二.while循环
三.do while循环
总结
一.for循环 for循环位于顶部,是一种驱动循环
for(初始表达式;循环条件;条件修改){ 代码; } for循环头部中的三个表达式可以省略一个或多个。
但要注意的是:for(; ; )是一种死循环,因为没有控制表达式,所以循环条件永远为true。
例:用1,2,3来组成不相同且不重复的三位数
#include<stdio.h> int main(void) { int hund=0; int ten=0; int single; printf("\n"); for(hund=1;hund<4;hund++) /* */ { for(ten=1;ten<4;ten++) { for(single=1;single<4;single++) { if(hund!=ten&&hund!=single&&single!=ten) /* */ { printf("%d,%d,%d\n",hund,ten,single); } } } } getchar(); return 0; } 二.while循环 while循环:和for循环一样,都是顶部驱动的循环,先计算循环条件(也就是控制表达式)。如果为 true,则进行循环,然后再次计算控制表达式。如果控制表达式为 false,程序跳过循环,而去执行循环后面的语句。
while(循环条件){ 语句; } 例:写出1到9这些数
#include <stdio.h> int main () { int a = 1; while( a < 10) { printf("
ros下使用PCL教程 ROS下使用PCL步骤1. 创建工作空间2. 创建ROS包3. 创建代码ROS代码框架4. 配置CMakeLists.txt文件5. 从PCL教程中下载pcl处理代码,放到ROS代码框架中(放在回调函数中)。 最近打算做一点点云数据处理相关的工作,所以就用到PCL(点云库),ubantu已经自己带了PCL库,我用的是uantu20.04.4+Ros noetic+pcl 1.10+vscode。PCL官网提供的教程是单独PCL在cmke编译的,要在ros框架下使用则需要将PCL官方教程与ROS匹配。ROS官方提供教程。以下是在ROS下跑通第一个PCL程序整理:
ROS下使用PCL步骤 1. 创建工作空间 mkdir -p ~/PCL_ws/src cd ~/PCL_ws catkin_make code .#(在vscode中打开) 2. 创建ROS包 打开vscode后直接创建ROS包。
查看vscode中创建ROS包
也可以使用命令行创建
catkin_creat_pkg my_PCL_tutorial PCL_conversions PCL_ros roscpp sensor_msgs 配置package.xml文件
<build_depend>libpcl-all-dev</build_depend> <exec_depend>libpcl-all</exec_depend> 3. 创建代码ROS代码框架 src文件夹下创建cpp文件src/pcl_text.cpp,不会参考上一个链接[查看vscode中创建ROS包]。
1 #include <ros/ros.h> 2 // PCL specific includes 3 #include <sensor_msgs/PointCloud2.h> 4 #include <pcl_conversions/pcl_conversions.h> 5 #include <pcl/point_cloud.h> 6 #include <pcl/point_types.h> 7 8 ros::Publisher pub; 9 10 void 11 cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input) 12 { 13 // Create a container for the data.
zookeeper集群配置 1. 配置准备2. 下载并解压2.1 下载2.2 解压 3. 修改配置文件3.1 创建以下目录3.1 拷贝zoo_sample.cfg3.2 修改zoo.cfg 4. 配置服务ID5. 配置环境变量6. 配置其他两台机器6.1 将/soft目录拷贝到其他两台机器6.2 同理将/usr/local/zookeeper也拷贝过去6.3 修改myid文件为对应的服务ID6.4 配置环境变量 1. 配置准备 jdk1.8虚拟机3台 2. 下载并解压 2.1 下载 官网URL,速度可能比较慢,注意一定要下载带bin的,已经编译好的,不带bin的是源码
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.5.10/apache-zookeeper-3.5.10-bin.tar.gz 2.2 解压 tar -zxvf apache-zookeeper-3.5.10-bin.tar.gz 3. 修改配置文件 3.1 创建以下目录 mkdir -p /soft/data/tmp/zookeeper 3.1 拷贝zoo_sample.cfg cp zoo_sample.cfg zoo.cfg 3.2 修改zoo.cfg 修改dataDir
# 默认是/tmp/zookeeper,/tmp目录下的是临时文件,会被定期清理 dataDir=/soft/data/tmp/zookeeper 在zoo.cfg最后添加如下内容
# 0是服务ID,2182是zk的实际端口,2188是leader端口 server.0=192.168.0.111:2182:2188 server.1=192.168.0.112:2182:2188 server.2=192.168.0.113:2182:2188 4. 配置服务ID cd /soft/data/tmp/zookeeper echo 0 > myid 5. 配置环境变量 vi /etc/profile 在文件最后添加
Jquery或许在前端技术中由于它不太好的性能以及其他原因逐渐被淘汰,但是Jquery在html单页面的应用中依然有着一定的优势,在本章主要简单展示Jquery的两种用于调用接口发起请求的方式。正常情况下,直接采用第一种方式即可,操作性更高,更符合业务需求。
在用Jquery 提供的api方法时,必须先引入Jquery的包,如在html文件中利用script标签引入Jq包
<script src="https://code.jquery.com/jquery-3.5.1.min.js" async></script> // 其中async是指异步引入,从而不阻塞页面的渲染 js文件中
import 'https://code.jquery.com/jquery-3.5.1.min.js"' 一、$.ajax $.ajax({ url: 'http://localhost:8000/api/xxx/xxxx', // 请求地址 type: 'post', // 请求方式 data: '', //携带到后端的参数 contentType: 'application/x-www-form-urlencoded', // 传参格式(默认为表单) json为application/json dataType: 'json', //期望后端返回的数据类型 success: function (res) { console.log('res', res); }, // 成功的回调函数 res就是后端响应回来的数据 error: function(err) { console.log('err', err); } // 失败的回调函数 }) 二 、$.getJSON $.getJSON('http://localhost:8000/api/xxx/xxxx', function (json) { console.log('json', json); }); // jQuery.getJSON(url, data, success(data, status, xhr)) // url 必需。规定将请求发送的哪个 URL。 // data 可选。规定连同请求发送到服务器的数据。 // success(data,status,xhr) 可选。规定当请求成功时运行的函数。 // 额外的参数: // response - 包含来自请求的结果数据 // status - 包含请求的状态 // xhr - 包含 XMLHttpRequest 对象 // 该函数是简写的 Ajax 函数,等价于: $.