Python str转float

#利用map和reduce编写一个str2float函数,把字符串‘123.456’转换成浮点数123.456 def str2float(s): def fn(x,y): return x*10+y n=s.index('.') s1=list(map(int,[x for x in s[:n]])) s2=list(map(int,[x for x in s[n+1:]])) return reduce(fn,s1)+reduce(fn,s2)/(10**len(s2))#乘幂 print('\'123.456\'=',str2float('123.456'))

常见的图像相似度比较哈希算法实现(Python&OpenCV)

简述 相似图像搜索的哈希算法有三种: 均值哈希算法差值哈希算法感知哈希算法 均值哈希算法 步骤 缩放:图片缩放为8*8,保留结构,出去细节。灰度化:转换为256阶灰度图。求平均值:计算灰度图所有像素的平均值。比较:像素值大于平均值记作1,相反记作0,总共64位。生成hash:将上述步骤生成的1和0按顺序组合起来既是图片的指纹(hash)。顺序不固定。但是比较时候必须是相同的顺序。对比指纹:将两幅图的指纹对比,计算汉明距离,即两个64位的hash值有多少位是不一样的,不相同位数越少,图片越相似。 代码实现: #均值哈希算法 def aHash(img): #缩放为8*8 img=cv2.resize(img,(8,8),interpolation=cv2.INTER_CUBIC) #转换为灰度图 gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #s为像素和初值为0,hash_str为hash值初值为'' s=0 hash_str='' #遍历累加求像素和 for i in range(8): for j in range(8): s=s+gray[i,j] #求平均灰度 avg=s/64 #灰度大于平均值为1相反为0生成图片的hash值 for i in range(8): for j in range(8): if gray[i,j]>avg: hash_str=hash_str+'1' else: hash_str=hash_str+'0' return hash_str 差值哈希算法 差值哈希算法前期和后期基本相同,只有中间比较hash有变化。 步骤 1. 缩放:图片缩放为8*9,保留结构,出去细节。 2. 灰度化:转换为256阶灰度图。 3. 求平均值:计算灰度图所有像素的平均值。 4. 比较:像素值大于后一个像素值记作1,相反记作0。本行不与下一行对比,每行9个像素,八个差值,有8行,总共64位 5. 生成hash:将上述步骤生成的1和0按顺序组合起来既是图片的指纹(hash)。顺序不固定。但是比较时候必须是相同的顺序。 6. 对比指纹:将两幅图的指纹对比,计算汉明距离,即两个64位的hash值有多少位是不一样的,不相同位数越少,图片越相似。 #差值感知算法 def dHash(img): #缩放8*8 img=cv2.resize(img,(9,8),interpolation=cv2.INTER_CUBIC) #转换灰度图 gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) hash_str='' #每行前一个像素大于后一个像素为1,相反为0,生成哈希 for i in range(8): for j in range(8): if gray[i,j]>gray[i,j+1]: hash_str=hash_str+'1' else: hash_str=hash_str+'0' return hash_str 感知哈希算法 感知哈希算法可以参考 相似性︱python+opencv实现pHash算法+hamming距离(simhash)(三) 讲的很详细了。

Oracle数据库日期格式转换函数

把日期格式转换to_char(FZRQ,’yyyy-mm-dd hh:mi:ss’) eg: select YSZBH, CYDW, to_char(FZRQ,'yyyy-mm-dd hh:mi:ss') as FZRQ, to_char(yxrq,'yyyy-mm-dd hh:mi:ss') as yxrq, KH, PWH, to_char(hjrq,'yyyy-mm-dd hh:mi:ss') as hjrq, HJZT, CYR, BEIZHU, ZXSJ, ZXYY, HJFS, to_char(lrrq,'yyyy-mm-dd hh:mi:ss') as lrrq, WXPT, GHDWDM, QYDDM, DDDDM from t_lz_ysz where yszbh='3213213' Oracle 默认时间格式 & Date格式转换 默认时间格式: 1、Oracle的日期格式 Oracle缺省的时间格式即时间数据的显示形式,与所使用的字符集有关。一般显示年月日,而不显示时分秒。 向表中插入数据时,如果不使用转换函数,则时间字段的格式必须遵从会话环境的时间格式,否则不能插入。 DATE格式转换: 一、在使用Oracle的to_date函数来做日期转换时,很多Java程序员也许会直接的采用“yyyy-MM-dd HH:mm:ss”的格式作为格式进行转换,但是在Oracle中会引起错误:“ORA 01810 格式代码出现两次”。 如:select to_date( ‘2005-01-01 13:14:20 ‘, ‘yyyy-MM-dd HH24:mm:ss ‘) from dual; 原因是:SQL中不区分大小写,MM和mm被认为是相同的格式代码,所以Oracle的SQL采用了mi代替分钟。 select to_date( ‘2005-01-01 13:14:20 ‘, ‘yyyy-MM-dd HH24:mi:ss ‘) from dual;

前端读取excel文件

由html5的FileReader这个对象来完成 FileReader接口的方法: readAsBinaryString file 将文件读取为二进制编码 readAsText file,[encoding] 将文件读取为文本,其中第二个参数是文本的编码方式,默认值为 UTF-8 readAsDataURL file 将文件读取为DataURL abort (none) 中断读取操作(无论读取成功或失败,方法并不会返回读取结果,这一结果存储在result属性中) 复制代码 相关事件: onabort 中断 onerror 出错 onloadstart   开始 onprogress 正在读取 onload 成功读取 onloadend 读取完成,无论成功失败 复制代码 核心代码: var reader = new FileReader(); //读取操作就是由它完成. reader.readAsBinaryString(file);//读取文件的内容,也可以读取文件的URL reader.onload = function (evt) { //当读取完成后回调这个函数,然后此时文件的内容存储到了result中,直接操作即可 var data = evt.target.result, } 复制代码 在上传文件之前,我们拿到文件内容,使用js-xlsx,来读取文件内容 npm install js-xlsx 在文件中, var XLSX = require('xlsx'); var workbook = XLSX.read(data, { type: 'binary' }), // 以二进制流方式读取得到整份excel表格对象 复制代码 在reader.

手写识别KNN(java)

起初以为手写识别仅与机器学习有关,做了这个才知道有KNN算法。 KNN: 概念摘自百度 邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。 kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 kNN方法在类别决策时,只与极少量的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合。 为了判断距离最近,引入欧氏距离和余弦距离。(可以自己再查查) 欧氏距离: 将两点之间距离公式拓展到N维,即抽象出来两物体距离为两点间距离公式的延展....emmm公式打不出来了 余弦距离 个人觉得余弦距离与其说是距离不如理解为趋势,余弦距离是空间两个向量夹角的余弦值来作为比较依据。 IO流 按操作数据类型分为字符流和字节流 按流分为输入流和输出流 字符流处理文本数据,字节流处理媒体数据 FileInputStream FileOutputStream 纯文本输入输出最为方便,这里的输入输出参考于程序 流使用后一定关闭 思路 1.数据存储 数据存储分两类:“学习”样本数据的存储,识别样本的存储; 在我点击“学习”按钮后,在界面画数字“1”,它会被截图保存,然后转为灰度,保存在二维数组中,输出到文本文档。 在我点击“识别”按钮后,在界面画数字“1”,它会被截图保存,然后转为灰度,保存在二维数组中,输出到文本文档。 2.knn,计算欧氏距离 我们需要从学习群文档中得到所有的数组数据,在与得到的一组测试数据比较,欧氏距离最小的极为同类。输出就好 源代码(1.0版本,它的问题是每次识别前都要录入新的样本) import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.AWTException; import java.awt.Rectangle; import java.awt.Robot; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; public class DrawFrame extends JFrame{ public static void main(String[] args) { // TODO Auto-generated method stub DrawFrame h=new DrawFrame(); h.

SpringBoot使用RabbitMQ示例Demo

声明:本示例的理论知识基于上一篇文章 SpringBoot使用RabbitMQ的准备工作: 声明:本人测试时,使用软硬件环境为:Windows7、Jdk1.8、Eclipse、rabbitmq-server-3.6.1、 SpringBoot 2.0.3.RELEASE。 第一步:在SpringBoot的pom.xml中引入AMQP高级消息队列协议的依赖。 注:消息生产者、消息消费者如果不在同一个项目(服务)中,那么都必须有此步骤。 注:这里可以不指定AMQP版本,SpringBoot会自动导入与该SpringBoot版本相搭配的AMQP的版本。 第二步:配置系统配置文件 给出文字版: #------------------------------------SpringBoot 服务名、端口号 spring.application.name=rabbit-mq-producer server.port=8489 #------------------------------------RabbitMQ基本配置 # RabbitMQ的主机地址(默认为:localhost) spring.rabbitmq.host=localhost # 指定该用户要连接到的虚拟host端(注:如果不指定,那么默认虚拟host为“/”) spring.rabbitmq.virtual-host = /vhost_A # amqp协议端口号:5672; 集群端口号:25672;http端口号:15672; spring.rabbitmq.port=5672 # 登录到RabbitMQ的用户名、密码 spring.rabbitmq.username=JustryDeng spring.rabbitmq.password=xxxxxx #------------------------------------RabbitMQ可选配置(注:这里只用到了特别少的几个) # broker端没有收到消费者的ACK(即:消费者异常时)时,是否再次向消费者投递消息(默认为false) # 为false时,如果没有收到消费者的ACK,那么会无限投递;设置为true时,默认投递时次数为3此 spring.rabbitmq.listener.simple.retry.enabled=true # 设置向消费者投递消息的最大次数 spring.rabbitmq.listener.simple.retry.max-attempts=2 # 投递消息的间隔(单位ms) spring.rabbitmq.listener.simple.retry.initial-interval=2000 注:消息消费者必须要有此步骤;如果消息生产者与消息消费者处于不同的项目或不同的服务等情况,那么消息生 产者也需要配置RabbitMQ的基本配置项; 注:如果消息生产者与消息消费者处于同一个项目或服务下(即:消息生产者与消息消费者共用同一个配置文件), 那么消息生产者就不需要再配置了; 注:更多关于RabbitMQ的配置,可详见https://blog.csdn.net/en_joker/article/details/80103519。 SpringBoot使用RabbitMQ示例: 声明:不管是以下的哪一种策略,如果一个消息的推送目标有多个Queue,那么这些Queue之间会进行竞争,最终该 消息只会被其中一个Queue消费。特别注意:如果同一个消息消费者在多处启动(即:Queue、Exchange等都一 样),那么也会发生竞争,最终该消息只会被其中某处的Queue消费。 Fanout策略: 目录结构: Consumer: QueueConfiguration.java配置类中的相关配置为: FanoutExchangeAndBindingConfiguration.java配置类中的相关配置为: DemoMessageListener中对应的消费消息的方法为: Producer: 单元测试SimulationMessageProducerTest.java中的对应测试代码为: 注:当消息生产者与消息消费者处于不同的项目或不同的服务等时,那么消息生产者也需要配置RabbitMQ的基本配置项,来 定位到RabbitMQ Server。详见准备步骤里系统配置文件中的RabbitMQ的基本配置部分。 注:上图中的方法作用是:将Object对象转化为AMQP能发送的消息数据;三个参数分别是交换机名字、路由键、消息内容对象。 .convertAndSend(String exchangeName,String routingKey,Object obj) 提示:当不采用direct或topic策略时,没有路由键,那么对应路由键参数位置使用双引号即可。

阿里c++一面面经

1 多态,虚函数与虚函数表 2 智能指针的作用及实现 3 sizeof,不能使用sizeof的情况下判断系统的位数? 4 三次握手,四次挥手,中间的等待 5 空class的大小,包含int和虚函数的大小 6 链表是否有环,O(1)时间复杂度删除指定节点,海量数据处理(topk) 7 线程安全(单例模式, 懒汉,饿汉) 8 vector的动态增长? 9 memcpy的内存重叠 10 空的类是否占用内存? 11 linux下运行c++的方式 12 堆排序,二叉树 13 new delete,delete [], 14 拷贝构造函数的参数为什么必须用引用? 转载于:https://www.cnblogs.com/muyangshaonian/p/9650477.html

Docker-01 简介与安装

2013年发布至今, Docker 一直广受瞩目,被认为可能会改变软件行业。 但是,许多人并不清楚 Docker 到底是什么,要解决什么问题,好处又在哪里?今天就来详细解释,帮助大家理解它,还带有简单易懂的实例,教你如何将它用于日常开发。 Docker简介 Docker是一个开源的容器引擎,它有助于更快地交付应用。 Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用 Docker可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。 Docker的优点如下: 1、简化程序 Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,便可以实现虚拟化。Docker改变了虚拟化的方式,使开发者可以直接将自己的成果放入Docker中进行管理。方便快捷已经是 Docker的最大优势,过去需要用数天乃至数周的 任务,在Docker容器的处理下,只需要数秒就能完成。 2、避免选择恐惧症 如果你有选择恐惧症,还是资深患者。Docker 帮你 打包你的纠结!比如 Docker 镜像;Docker 镜像中包含了运行环境和配置,所以 Docker 可以简化部署多种应用实例工作。比如 Web 应用、后台应用、数据库应用、大数据应用比如 Hadoop 集群、消息队列等等都可以打包成一个镜像部署。 3、节省开支 一方面,云计算时代到来,使开发者不必为了追求效果而配置高额的硬件,Docker 改变了高性能必然高价格的思维定势。Docker 与云的结合,让云空间得到更充分的利用。不仅解决了硬件管理的问题,也改变了虚拟化的方式。 Docker的架构 Docker daemon( Docker守护进程) Docker daemon是一个运行在宿主机( DOCKER-HOST)的后台进程。可通过 Docker客户端与之通信。 Client( Docker客户端) Docker客户端是 Docker的用户界面,它可以接受用户命令和配置标识,并与 Docker daemon通信。图中, docker build等都是 Docker的相关命令。 Images( Docker镜像) Docker镜像是一个只读模板,它包含创建 Docker容器的说明。它和系统安装光盘有点像,使用系统安装光盘可以安装系统,同理,使用Docker镜像可以运行 Docker镜像中的程序。 Container(容器) 容器是镜像的可运行实例。镜像和容器的关系有点类似于面向对象中,类和对象的关系。可通过 Docker API或者 CLI命令来启停、移动、删除容器。 Registry Docker Registry是一个集中存储与分发镜像的服务。构建完 Docker镜像后,就可在当前宿主机上运行。但如果想要在其他机器上运行这个镜像,就需要手动复制。此时可借助 Docker Registry来避免镜像的手动复制。 一个 Docker Registry可包含多个 Docker仓库,每个仓库可包含多个镜像标签,每个标签对应一个 Docker镜像。这跟 Maven的仓库有点类似,如果把 Docker Registry比作 Maven仓库的话,那么 Docker仓库就可理解为某jar包的路径,而镜像标签则可理解为jar包的版本号。

空的死循环为什么会让cpu100%

while (1) { //空代码块 } 上面这个代码相信很多人都写过,这个代码的后果就是cpu会100%(具体数值要看cpu核数和操作系统对这个的表示方法,有的2核会显示50%,有的2核会显示100%),如果是单核那么你的电脑会相当卡了。解决这个问题的办法很简单 while (1) { sleep(1); } 加上一个sleep(1),让她休眠一秒就好了。现在都是多任务操作系统了,电脑上不会只有这一个进程,cpu不是按时间片轮转来执行吗?就算是单核,cpu利用率也不应该是100%啊,为什么会这样呢?我们知道一个线程有三种状态: 假设现在加上这个 空的死循环线程 有100个线程 ,它们的优先级相同,其它99个线程有空闲的也有不是空闲的。 运行之后,cpu 根据时间片来执行这些线程,每当执行完某个线程的部分代码即将要进入空闲状态时,这个空的死循环会不断的向cpu申请资源,cpu立即去执行这个空的死循环,导致cpu没有空闲的状态,最后会100% (cpu从一个线程切换到另一个线程,也要消耗cpu)。 打个比方,现在有一个环卫工人,负责打扫5条街,本来是打扫完一条街可以休息10分钟(一条街40分钟内没有垃圾)。但是现在由于第二条街人口剧增,每当环卫工人准备休息的时候,街道办就打电话来说赶紧去打扫第二条街,如此一来环卫工人再也没有休息的时间了。 最后 由于春运快到了,给大家安利一个抢火车票的小程序心到抢票,微信扫码关注点击立即抢票即可 个人亲测效率很高,大家也可以加他们官方微信 xdticket 咨询。

线程进程是怎样使用多核的

最近由于有抢票的需求,对于一个用户而言,用一个死循环,一个刷票就好了,刷到了就break退出。但是现在我要考虑同时给很多人抢,那么必须要考虑并发。但是这是一个耗时的任务,很可能几天都不能结束这个任务,所以这个和普通的java web并发不同。我在思考如何设置这个线程模型时引出了一个问题,之前还一直都没思考过这个。 多核时,一个线程是始终由一个cpu核运行还是每个cpu核都会运行该线程呢? 先来看看进程的三种状态 对于这个问题,先假设第一种情况成立(线程始终由某一个核执行) 那么对于一个四核cpu来说,一个线程A假如第一次是有cpu0执行,那么后续直到执行完毕,A永远由cpu0执行。 再假设第二种情况成立(线程由不同的核执行)。 那么对于一个四核cpu来说,一个线程A假如第一次是有cpu0执行,那么第二次可能由cpu1执行,第三次可能由cpu2执行,第四次可能由cpu3执行,每个cpu交替执行,直到A执行完成。 那么,到底哪种假设是正确的呢?,为此我做了一个简单的测试。 我用xcode写了一个简单的oc代码 #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; while (1) { //死循环用来查看cpu利用率 } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end 工程命名cputest,运行模拟器,打开mac上活动监视器观察 可以看到cpu使用率达到了98.3%,咋一看像是使用了一个cpu核,如果这时候你认为假设一是正确的那就错了。可能你会很诧异,明明都快到100%,为什么不是!!!我来告诉你答案,接下来我用查看多核cpu的每个核使用率方法(见我上篇文章mac查看多核cpu利用率) 是不是很惊讶,这个双核四线程里没有一个核达到了98.3%,最高也才50%吧。那么由此我们可以得出结论了,第二种假设是正确的,多核cpu情况下,一个线程不是由某一个核一直执行完成的。 此处需要解释下%cpu = 98.3%是怎么来的, 它是由四核(有两个核是虚拟的)的利用率相加得来的。 但是在实际工作中,你可能会有某些特殊要求,为了优化项目,不得不让某个进程一直由cpu的某一个核执行直到完成。事实上这样也是可以的,你可以指定进程由某一cpu核来完成执行。详情可以搜索 taskset 命令。 另附上知乎 “一个进程能不能在多个核上跑?” 的链接 https://www.zhihu.com/question/31683094 最后 由于春运快到了,给大家安利一个抢火车票的小程序心到抢票,微信扫码关注点击立即抢票即可 个人亲测效率很高,大家也可以加他们官方微信 xdticket 咨询。

C语言判断题

1.在if语句的三种形式中,如果要想在满足条件时执行一组(多个)语句,则必须把这一组语句用{}括起来组成一个复合语句。 (T) 2.任何表达式语句都是表达式加分号组成的。 (T) 3.do-while循环的while后的分号可以省略。 (F) 4.case语句后如没有break,顺序向下执行。 (T) 5.增1减1运算符的前缀运算和后缀运算的表达式值是相同的。 (F) 6.函数的实参可以是常量,变量或表达式。 (T) 7.如果函数定义出现在函数调用之前,可以不必加函数原型声明。 (T) 8.C 语言程序中可以有多个函数 , 但只能有一个主函数。 (T) 9.函数返回值的类型是由在定义函数时所指定的函数类型。 (T) 10.局部变量如果没有指定初值,则其初值不确定。 (T) 11.若有定义int a[]={2,4,6,8,10},p=a;a的值是数组首地址,则*(p+1)的值是4。 (T) 12.指针数组的每个元素都是一个指针变量。 (T) 13.关于C语言指针的运算:指针只有加减操作,没有乘除操作。指针可以加常数、减常数;相同类型的指针可以相加、相减。 (F) 14.假设有定义如下: int array[10]; 则该语句定义了一个数组array。其中array的类型是整型指针(即: int *)。(F) (题目来源:PTA,由王琪琛整理作答,侵删)

linux命令-date显示或设置时间

简介 昨天在处理单点认证问题的时候,由于服务器的时间比真实的时间慢了几分钟,导致了认证一直不成功,就采用date去设置了一下时间,顺便把date指令学习了一下 帮助信息 在终端输入date –help查看帮助信息 date –help 指令 date [OPTION]... [+FORMAT] or: date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]] 选项 -d 按照指定的字符串输出时间,如date -d “1990/09/18” -f 逐行输出指定文件中的时间 -I[TIMESPEC] 以ISO 8601 格式显示日期/时间。TIMESPEC为”date”(只显示日期)、”hours”、”minutes”、”senconds”(显示时间精度)之一,默认为”date”。 -r 显示指定文件的最后修改时间 -R 按照RFC-2822日期格式显示时间 -s 按照指定字符串设置时间 -u 按照Coordinated Universal Time (UTC)格式设置或输出时间 format参数格式 %% a literal % 注:输出一个%符号 %a locale’s abbreviated weekday name (e.g., Sun) 注:星期几的缩写,如Sat周六,Sun周日 %A locale’s full weekday name (e.g., Sunday) 注:星期几的全称,如Sunday周日 %b locale’s abbreviated month name (e.g., Jan) 注:月份的缩写,如Aug八月 %B locale’s full month name (e.

如何将类数组转换为真正的数组

开发过程中,有很多时候获取到的是类似数组的对象。比如元素的集合(elementcollection,nodeList,以及今天开发时发现classList也是类数组)。有时我们需要类数组去调用数组的方法,怎么办? 一、遍历类数组,依次将元素放入一个空数组。 类数组本身虽然不是数组,但是有interator接口,所以可遍历。(interator指可遍历、可迭代) 例如: 页面有三个div,divEle是一个nodeList,即元素集合,并非纯数组。可以用let of遍历。然后依次放入一个空数组。这样divArr就是div元素集合的数组。 二、用扩展运算符或者Array.from()方法转换 es6新增了扩展运算符(...)以及Array.from()方法,可以直接将类数组转换为真正的数组。 关于扩展运算符以及Array.from()的详细用法,可参考阮一峰老师的《es6标准入门》一书。 扩展运算符的使用前提,是对象有Interator接口,这和let of的前提是一样的。但是用扩展运算符和Array.from()无疑简洁很多。 需要特别指出的是,Array.from()方法可以将任意具有length属性的对象转换成真正的数组(类数组有length属性)。具体转换形式可参考阮一峰老师的《es6标准入门》一书。 三、利用apply展开 apply方法的第二个参数是数组,也可以是类数组,在调用的时候会将第二个参数依次展开。 过程类似扩展运算符。 以上三种方法推荐扩展运算符,方式非常的简洁。

React Native Jenkins 自动化打包

这是最近做的RN项目 jenkins 自动化打包成功实现 构建 Execute shell (脚本如下) env #/usr/bin/security default-keychain -d user -s /Users/ett/Library/Keychains/login.keychain #/usr/bin/security unlock-keychain -p * /Users/ett/Library/Keychains/login.keychain export ETT_APP_NAME=kmOnline export ETT_WORKSPACE_NAME=ETTMallWork export ETT_PROJECT_NAME=ETTMallWork export ETT_SCHEME=ETTMallWork export ETT_PROVISIONING_PROFILE=kmOnlineTestAdhotProfile export ETT_BUILD_TYPE=.SNAPSHOT export ETT_CONFIGURATION=Release ############################################################################################################### #rm -rf node_modules #npm cache verify #mkdir node_modules cp -r /Users/ett/Desktop/kumeng/node_modules $WORKSPACE npm install react-native bundle --entry-file index.js --bundle-output ./ios/main.jsbundle --platform ios cd $WORKSPACE/ios export ETT_JENKINS_TIME=$(date +%m%d) export ETT_GIT_COMMIT=${GIT_COMMIT:0:7} export ETT_GIT_REV=`git rev-list HEAD | wc -l | awk '{print $1}'`

iOS 时间计算

获取6个月之后的时间 NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *comps = nil; comps = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:tran.transactionDate]; NSDateComponents *adcomps = [[NSDateComponents alloc] init]; [adcomps setYear:0]; [adcomps setMonth:6]; [adcomps setDay:0]; NSDate *newdate = [calendar dateByAddingComponents:adcomps toDate:tran.transactionDate options:0];

解决 DbVisualizer Unknown system variable 'query_cache_size' 错误

本人环境:ubuntu 16.04 问题: 安装DbVisualizer 后连接docker中mysql服务出现错误 Unknown system variable 'query_cache_size' 问题原因: 自带mysql驱动版本过老,导致query_cache_size变量无效报错 解决方案: 下载最新mysql驱动并替换原驱动 下载地址:http://central.maven.org/maven2/mysql/mysql-connector-java/8.0.11/mysql-connector-java-8.0.11.jar 打开DbVisualizer安装目录找到 jdbc文件夹下的mysql文件夹备份原jar包并拷贝新jar包驱动重命名为 mysql.jar 重启即可链接成功!

Android 异常分析

转载一篇比较好的总结android异常的文章,感谢原创作者! 其中包含:ANR,SWT,JE,NE,KE,EED等异异常和分析方法。 Android异常分析 http://www.mamicode.com/info-detail-1768679.html

keras基本开发环境搭建

1. Linux 发行版 linux有很多发行版,本文强烈建议读者采用新版的Ubuntu 16.04 LTS 一方面,对于大多数新手来说Ubuntu具有很好的图形界面,与乐观的开源社区;另一方面,Ubuntu是Nvidia官方以及绝大多数深度学习框架默认开发环境。 个人不建议使用Ubuntu其他版本,由于GCC编译器版本不同,会导致很多依赖无法有效安装。 Ubuntu 16.04 LTS下载地址:http://www.ubuntu.org.cn/download/desktop 通过U盘安装好后,进行初始化环境设置。 2. Ubuntu初始环境设置 安装开发包 打开终端输入: # 系统升级 >>> sudo apt update >>> sudo apt upgrade # 安装python基础开发包 >>> sudo apt install -y python-dev python-pip python-nose gcc g++ git gfortran vim 安装运算加速库 打开终端输入: >>> sudo apt install -y libopenblas-dev liblapack-dev libatlas-base-dev 3. CUDA开发环境的搭建(CPU加速跳过) 如果您的仅仅采用cpu加速,可跳过此步骤 - 下载CUDA8.0 下载地址:https://developer.nvidia.com/cuda-downloads 之后打开终端输入: >>> sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb >>> sudo apt update >>> sudo apt -y install cuda 自动配置成功就好。

线索二叉树原理及前序、中序线索化(Java实现)

本文转自:https://blog.csdn.net/UncleMing5371/article/details/54176252 一、线索二叉树原理 前面介绍二叉树原理及特殊二叉树文章中提到,二叉树可以使用两种存储结构:顺序存储和二叉链表。在使用二叉链表的存储结构的过程中,会存在大量的空指针域,为了充分利用这些空指针域,引申出了“线索二叉树”。回顾一下二叉链表存储结构,如下图: 通过观察上面的二叉链表,存在着若干个没有指向的空指针域。对于一个有n个节点的二叉链表,每个节点有指向左右节点的2个指针域,整个二叉链表存在2n个指针域。而n个节点的二叉链表有n-1条分支线,那么空指针域的个数=2n-(n-1) = n+1个空指针域,从存储空间的角度来看,这n+1个空指针域浪费了内存资源。 从另外一个角度来分析,如果我们想知道按中序方式遍历二叉链表时B节点的前驱节点或者后继节点时,必须要按中序方式遍历二叉链表才能够知道结果,每次需要结果时都需要进行一次遍历,是否可以考虑提前存储这种前驱和后继的关系来提高时间效率呢? 综合以上两方面的分析,可以通过充分利用二叉链表中的空指针域,存放节点在某种遍历方式下的前驱和后继节点的指针。我们把这种指向前驱和后继的指针成为线索,加上线索的二叉链表成为线索链表,对应的二叉树就成为“线索二叉树(Threaded Binary Tree)” 。 二、构建线索二叉树过程 1、我们对二叉树进行中序遍历(不了解二叉树遍历请参考二叉树及特殊二叉树介绍),将所有的节点右子节点为空的指针域指向它的后继节点。如下图: 通过中序遍历我们知道H的right指针为空,并且H的后继节点为D(如上图第1步),I的right指针为空,并且I的后继节点为B(如上图第2步),以此类推,知道G的后继节点为null,则G的right指针指向null。 2、接下来将这颗二叉树的所有节点左指针域为空的指针域指向它的前驱节点。如下图: 如上图,H的left指针域指向Null(如第1步),I的前驱节点是D,则I的left指针指向D,以此类推。 通过上面两步完成了整个二叉树的线索化,最后结果如下图: 通过观察上图(蓝色虚线代表后继、绿色虚线代表前驱),可以看出,线索二叉树,等于是把一棵二叉树转变成了一个“特殊的双向链表“(后面会解释为什么叫特殊的双向链表),这样对于我们的新增、删除、查找节点带来了方便。所以我们对二叉树以某种次序遍历使其变为线索二叉树的过程称做是线索化。如下图: 仔细分析上面的双向链表,与线索化之后的二叉树相比,比如节点D与后继节点I,在完成线索化之后,并没有直接线索指针,而是存在父子节点的指针;节点A与节点F,在线索化完成之后,节点A并没有直接指向后继节点F的线索指针,而是通过父子节点遍历可以找到最终的节点F,前驱节点也存在同样的问题,正因为很多节点之间不存在直接的线索,所以我将此双向链表称做“特殊的双向链表”,再使用过程中根据指针是线索指针还是子节点指针来分别处理,所以在每个节点需要标明当前的左右指针是线索指针还是子节点指针,这就需要修改节点的数据结构。修改后的数据结构如下: class Node { String data; //数据域 Node left; //左指针域 Node right; //右指针域 byte leftType; //左指针域类型 0:指向子节点、1:前驱或后继线索 byte rightType; //右指针域类型 0:指向子节点、1:前驱或后继线索 } 最终的二叉链表修改为如下图的样子: 三、线索二叉树的代码(Java实现) 下面是中序线索化二叉树的实现代码: /** * @Title: 二叉树相关操作 * @Description: * @Author: Uncle Ming * @Date:2017年1月6日 下午2:49:14 * @Version V1.0 */ public class ThreadBinaryTree { private Node preNode; //线索化时记录前一个节点 //节点存储结构 static class Node { String data; //数据域 Node left; //左指针域 Node right; //右指针域 boolean isLeftThread = false; //左指针域类型 false:指向子节点、true:前驱或后继线索 boolean isRightThread = false; //右指针域类型 false:指向子节点、true:前驱或后继线索 Node(String data) { this.

逻辑智力测试题内附详细答案

假设有一个池塘,里面有无穷多的水。现有2个空水壶,容积分别为5升和6升。问题是如何只用这2个水壶从池塘里取得3升的水。 由满6向空5倒,剩1升,把这1升倒5里,然后6剩满,倒5里面,由于5里面有1升水,因此6只能向5倒4升水,然后将6剩余的2升,倒入空的5里面,再灌满6向5里倒3升,剩余3升。 【2】周雯的妈妈是豫林水泥厂的化验员。一天,周雯来到化验室做作业。做完后想出去玩。"等等,妈妈还要考你一个题目,"她接着说,"你看这6只做化验用的玻璃杯,前面3只盛满了水,后面3只是空的。你能只移动1只玻璃杯,就便盛满水的杯子和空杯子间隔起来吗?"爱动脑筋的周雯,是学校里有名的"小机灵",她只想了一会儿就做到了。请你想想看,"小机灵"是怎样做的? 设杯子编号为ABCDEF,ABC为满,DEF为空,把B中的水倒进E中即可。 【3】三个小伙子同时爱上了一个姑娘,为了决定他们谁能娶这个姑娘,他们决定用手枪进行一次决斗。小李的命中率是30%,小黄比他好些,命中率是50%,最出色的枪手是小林,他从不失误,命中率是100%。由于这个显而易见的事实,为公平起见,他们决定按这样的顺序:小李先开枪,小黄第二,小林最后。然后这样循环,直到他们只剩下一个人。那么这三个人中谁活下来的机会最大呢?他们都应该采取什么样的策略? 小林在轮到自己且小黄没死的条件下必杀黄,再跟菜鸟李单挑。 所以黄在林没死的情况下必打林,否则自己必死。 小李经过计算比较(过程略),会决定自己先打小林。 于是经计算,小李有873/2600≈33.6%的生机; 小黄有109/260≈41.9%的生机; 小林有24.5%的生机。 哦,这样,那小李的第一枪会朝天开,以后当然是打敌人,谁活着打谁; 小黄一如既往先打林,小林还是先干掉黄,冤家路窄啊! 最后李,黄,林存活率约38:27:35; 菜鸟活下来抱得美人归的几率大。 李先放一空枪(如果合伙干中林,自己最吃亏)黄会选林打一枪(如不打林,自己肯定先玩完了)林会选黄打一枪(毕竟它命中率高)李黄对决0.3:0.280.4可能性李林对决0.3:0.60.6可能性成功率0.73 李和黄打林李黄对决0.3:0.40.7*0.4可能性李林对决0.3:0.7*0.6*0.70.7*0.6可能性成功率0.64 【4】一间囚房里关押着两个犯人。每天监狱都会为这间囚房提供一罐汤,让这两个犯人自己来分。起初,这两个人经常会发生争执,因为他们总是有人认为对方的汤比自己的多。后来他们找到了一个两全其美的办法:一个人分汤,让另一个人先选。于是争端就这么解决了。 可是,现在这间囚房里又加进来一个新犯人,现在是三个人来分汤。必 须寻找一个新的方法来维持他们之间的和平。该怎么办呢?按:心理问题,不是逻辑问题 是让甲分汤,分好后由乙和丙按任意顺序给自己挑汤,剩余一碗留给甲。这样乙和丙两人的总和肯定是他们两人可拿到的最大。然后将他们两人的汤混合之后再按两人的方法再次分汤。 【5】在一张长方形的桌面上放了n个一样大小的圆形硬币。这些硬币中可能有一些不完全在桌面内,也可能有一些彼此重叠;当再多放一个硬币而它的圆心在桌面内时,新放的硬币便必定与原先某些硬币重叠。请证明整个桌面可以用4n个硬币完全覆盖。 要想让新放的硬币不与原先的硬币重叠,两个硬币的圆心距必须大于直径。也就是说,对于桌面上任意一点,到最近的圆心的距离都小于2,所以,整个桌面可以用n个半径为2的硬币覆盖。 把桌面和硬币的尺度都缩小一倍,那么,长、宽各是原桌面一半的小桌面,就可以用n个半径为1的硬币覆盖。那么,把原来的桌子分割成相等的4块小桌子,那么每块小桌子都可以用n个半径为1的硬币覆盖,因此,整个桌面就可以用4n个半径为1的硬币覆盖。 【6】一个球、一把长度大约是球的直径2/3长度的直尺.你怎样测出球的半径?方法很多,看看谁的比较巧妙 【7】五个大小相同的一元人民币硬币。要求两两相接触,应该怎么摆? 底下放一个1,然后2 3放在1上面,另外的4 5竖起来放在1的上面。 【8】猜牌问题S先生、P先生、Q先生他们知道桌子的抽屉里有16张扑克牌:红桃A、Q、4黑桃J、8、4、2、7、3草花K、Q、5、4、6方块A、5。约翰教授从这16张牌中挑出一张牌来,并把这张牌的点数告诉P先生,把这张牌的花色告诉Q先生。这时,约翰教授问P先生和Q先生:你们能从已知的点数或花色中推知这张牌是什么牌吗?于是,S先生听到如下的对话:P先生:我不知道这张牌。Q先生:我知道你不知道这张牌。P先生:现在我知道这张牌了。Q先生:我也知道了。听罢以上的对话,S先生想了一想之后,就正确地推出这张牌是什么牌。请问:这张牌是什么牌? 方块5 【9】一个教授逻辑学的教授,有三个学生,而且三个学生均非常聪明!一天教授给他们出了一个题,教授在每个人脑门上贴了一张纸条并告诉他们,每个人的纸条上都写了一个正整数,且某两个数的和等于第三个!(每个人可以看见另两个数,但看不见自己的)教授问第一个学生:你能猜出自己的数吗?回答:不能,问第二个,不能,第三个,不能,再问第一个,不能,第 二个,不能,第三个:我猜出来了,是144!教授很满意的笑了。请问您能猜出另外两个人的数吗? 经过第一 轮,说明任何两个数都是不同的。第二轮,前两个人没有猜出,说明任何一个数都不是其它数的两倍。现在有了以下几个条件:1.每个数大于02.两两不等3.任意一个数不是其他数的两倍。每个数字可能是另两个之和或之差,第三个人能猜出144,必然根据前面三个条件排除了其中的一种可能。假设:是两个数之差,即x-y=144。这时1(x,y>0)和2(x!=y)都满足,所以要否定x+y必然要使3不满足,即x+y=2y,解得x=y,不成立(不然第一轮就可猜出),所以不是两数之差。因此是两数之和,即x+y=144。同理,这时1,2都满足,必然要使3不满足,即x-y=2y,两方程联立,可得x=108,y=36。 这两轮猜的顺序其实分别为这样:第一轮(一号,二号),第二轮(三号,一号,二号)。这样分大家在每轮结束时获得的信息是相同的(即前面的三个条件)。 那么就假设我们是C,来看看C是怎么做出来的:C看到的是A的36和B的108,因为条件,两个数的和是第三个,那么自己要么是72要么是144(猜到这个是因为72的话,108就是36和72的和,144的话就是108和36的和。这样子这句话看不懂的举手): 假设自己(C)是72的话,那么B在第二回合的时候就可以看出来,下面是如果C是72,B的思路:这种情况下,B看到的就是A的36和C的72,那么他就可以猜自己,是36或者是108(猜到这个是因为36的话,36加36等于72,108的话就是36和108的和): 如果假设自己(B)头上是36,那么,C在第一回合的时候就可以看出来,下面是如果B是36,C的思路:这种情况下,C看到的就是A的36和B的36,那么他就可以猜自己,是72或者是0(这个不再解释了): 如果假设自己(C)头上是0,那么,A在第一回合的时候就可以看出来,下面是如果C是0,A的思路:这种情况下,A看到的就是B的36和C的0,那么他就可以猜自己,是36或者是36(这个不再解释了),那他可以一口报出自己头上的36。(然后是逆推逆推逆推),现在A在第一回合没报出自己的36,C(在B的想象中)就可以知道自己头上不是0,如果其他和B的想法一样(指B头上是36),那么C在第一回合就可以报出自己的72。现在C在第一回合没报出自己的36,B(在C的想象中)就可以知道自己头上不是36,如果其他和C的想法一样(指C头上是72),那么B在第二回合就可以报出自己的108。现在B在第二回合没报出自己的108,C就可以知道自己头上不是72,那么C头上的唯一可能就是144了。 史上最雷人的应聘 者 【10】某城市发生了一起汽车撞人逃跑事件,该城市只有两种颜色的车,蓝15%绿85%,事发时有一个人在现场看见了,他指证是蓝车,但是根据专家在现 场分析,当时那种条件能看正确的可能性是80%那么,肇事的车是蓝车的概率到底是多少? 15%*80%/(85%×20%+15%*80%) 【11】有一人有240公斤水,他想运往干旱地区赚钱。他每次最多携带60公斤,并且每前进一公里须耗水1公斤(均匀耗水)。假设水的价格在出发地为0,以后,与运输路程成正比,(即在10公里处为10元/公斤,在20公里处为20元/公斤......),又假设他必须安全返回,请问,他最多可赚多少钱? f(x)=(60-2x)*x,当x=15时,有最大值450。 450×4 【12】现在共有100匹马跟100块石头,马分3种,大型马;中型马跟小型马。其中一匹大马一次可以驮3块石头,中型马可以驮2块,而小型马2头可以驮一块石头。问需要多少匹大马,中型马跟小型马?(问题的关键是刚好必须是用完100匹马) 6种结果 【13】1=5,2=15,3=215,4=2145那么5=? 因为1=5,所以5=1. 【14】有2n个人排队进电影院,票价是50美分。在这2n个人当中,其中n个人只有50美分,另外n个人有1美元(纸票子)。愚蠢的电影院开始卖票时1分钱也没有。问:有多少种排队方法使得每当一个拥有1美元买票时,电影院都有50美分找钱 注:1美元=100美分拥有1美元的人,拥有的是纸币,没法破成2个50美分 本题可用递归算法,但时间复杂度为2的n次方,也可以用动态规划法,时间复杂度为n的平方,实现起来相对要简单得多,但最方便的就是直接运用公式:排队的种数=(2n)!/[n!(n+1)!]。 如果不考虑电影院能否找钱,那么一共有(2n)!/[n!n!]种排队方法(即从2n个人中取出n个人的组合数),对于每一种排队方法,如果他会导致电影院无法找钱,则称为不合格的,这种的排队方法有(2n)!/[(n-1)!(n+1)!](从2n个人中取出n-1个人的组合数)种,所以合格的排队种数就是(2n)!/[n!n!]- (2n)!/[(n-1)!(n+1)!] =(2n)!/[n!(n+1)!]。至于为什么不合格数是(2n)!/[(n-1)!(n+1)!],说起来太复杂,这里就不讲了。 【15】一个人花8块钱买了一只鸡,9块钱卖掉了,然后他觉得不划算,花10块钱又买回来了,11块卖给另外一个人。问他赚了多少? 2元 【16】有一种体育竞赛共含M个项目,有运动员A,B,C参加,在每一项目中,第一,第二,第三名分别的X,Y,Z分,其中X,Y,Z为正整数且X>Y>Z。最后A得22分,B与C均得9分,B在百米赛中取得第一。求M的值,并问在跳高中谁得第二名。 因为ABC三人得分共40分,三名得分都为正整数且不等,所以前三名得分最少为6分,40=5*8=4*10=2*2 0=1*20,不难得出项目数只能是5.即M=5. A得分为22分,共5项,所以每项第一名得分只能是5,故A应得4个一名一个二名.22=5*4+2,第二名得1分,又B百米得第一,所以A只能得这个第二. B的5项共9分,其中百米第一5分 ,其它4项全是1分,9=5+1=1+1+1.即B除百米第一外全是第三,跳高第二必定是C所得. 【17】前提: 1 有五栋五种颜色的房子

C# 二维码生成 ( QRCoder )

二维码 1.前言 seaconch 最近在搞二维码方面的一些东西,所以接触了一些二维码相关,那么既然用过了就要有用过了的样子 其实关于二维码的文章真的多的数不胜数,有很多写的很认真,很好,但这就像是学习一样,别人会不代表自己就没有学习和记录的价值,所以说学习不在早晚 引入包 1.通过NuGet引入QRCoder a)首先,我们新建一个 类库 项目,seaconch这里命名为 chestnut_qrcode b)之后通过 NuGet 引入 QRCoder 包 c)见图操作 d)安装成功后,项目引用中就会出现 QRCoder 的引用 e)这时候引入工作已经完成,不过可以顺手创建一个 Encoder.cs 静态公共类 二维码生成类 1.前期准备 这里先说一下生成二维码需要的三个类: QRCodeGeneratorQRCodeDataQRCode 他们的 职责 分别是什么呢? QRCodeGenerator :用来通过指定的方式生成二维码存储的数据对象,也就是 QRCodeData 二维码中间的 Matrix,之后 QRCode 得到 QRCodeData 并生成二维码 2.编码 Encoder.cs 全部代码如下: using System.Drawing; namespace chestnut_qrcode { /// <summary> /// 二维码编码器 /// </summary> public static class Encoder { /// <summary> /// 生成二维码 /// </summary> /// <param name="msg">信息</param> /// <param name="

SpringBoot简单项目搭建,从数据读取数据展示到页面

springboot快速搭建web项目,无需繁琐xml配置,热部署,无需重启服务器,简单部署只需打jar包即可,有很多的优点! 刚接触到springboot花费了好几个小时,撸完一个又一个的配置坑,最终实现从数据库成功读取数据展示到页面! 希望对你能有所帮助! 首先搭建springboot环境,eclipse需要用到 spring-tool-suite 插件 1,首先插件安装 官网下载 https://spring.io/tools/sts/ Eclipse市场下载:Help->Eclicpse Marketplace 搜索 spring-tool-suite 安装即可 2,安装完之后显示 或者查看菜单栏显示 出现这个说明安装成功 3,创建工程 首先Java,maven 环境是准备好的。 第一步 第二步 项目命名,Java版本,包等 第三步 选择web,然后下一步,这里选择的springboot版本是2.1.0(根据个人环境选择) 第四步 finish即可 创建完成的项目结构 右键运行SpringBootDemosApplication 方法,显示如下则内容说明项目搭建成功。 默认tomcat端口为8080 这里写一个简单的实例,运用一下springboot框架。 所有的Java代码必须跟主程序同级或者在主程序所在包下 首先写个测试方法,随便测是一些数据。 首先需要在pom文件里添加一些依赖 这里依赖是下文中例子用到的依赖 <dependencies> <!-- Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- MyBatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <!--启动时启动内置tomcat --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <!--对Jsp支持 --> <!-- <dependency> <groupId>org.apache.tomcat.embed</groupId>

python中使用BeautifulSoup模块+CSS选择器获取中彩网福彩3D的开奖数据

在上篇博客中,我们使用了BeautifulSoup模块获取中彩网福彩3D的开奖数据,在编写爬虫程序的过程中发现,如果只使用BeautifulSoup模块中的find_all函数来匹配标签解析网页时,工作量较大而且容易出错,这和find_all函数本身的工作原理以及输入输出有关。通过查找,我们发现将BeautifulSoup模块和CSS选择器结合起来使用会提高网络爬虫的编写和运行效率,所以,同样以爬取中彩网中福彩3D的开奖数据为例,讲解BeautifulSoup模块如何与CSS选择器结合使用。首先,将介绍CSS选择器的工作原理和使用方法。 CSS选择器的工作原理和使用方法 CSS选择器的工作原理是:我们在编写CSS时要遵守一些固定的规范,如标签名不加任何修饰符,类名前面加“.”,id名前面加“#”。我们同样可以利用类似的方法筛选元素,用到的方法是soup.select(),返回值的数据类型为列表。 CSS选择器的使用方法如下: from bs4 import BeautifulSoup # html内容 html = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title" name="dromouse"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p> """ # 创建BeautifulSoup对象用于解析网页 soup = BeautifulSoup(html, 'lxml') 1)通过标签名查找

CentOS Linux 7.4中polkit服务启动失败

错误描述: 最近新装系统后,真机电脑需要安装ftp和chrony等软件,装包,修改配置文件后,启动服务时出现报错: Error getting authority:Eroor initializing authority:Error calling StartServiceByName for org.freedesktop.PolicyKit1:Timeout was readhed(g-io-error-quark, 24) 后续在redhat客户门户网站找到对应解决办法: https://access.redhat.com/solutions/1543343 1.确保polkitd系统用户和组的存在 将以下2个复合命令复制、粘贴到根终端以检查并有条件地创建用户 [root@room9pc01 ~]# /dev/null && echo -e "\e[1;32mpolkitd group already exists\e[0m" || { groupadd -r polkitd && echo -e "\e[1;33mAdded missing polkitd group\e[0m" || echo -e "\e[1;31mAdding polkitd group FAILED\e[0m"; } [root@room9pc01 ~]# /dev/null && echo -e "\e[1;32mpolkitd user already exists\e[0m" || { useradd -r -g polkitd -d / -s /sbin/nologin -c "

xshell如何传输文件

前言: 在测试工作中经常会遇到这样一个情景:软件有导入功能,且导入的数据有附件。如果只是单纯导入excel表并不能实现其附件的导入,这时候就有必要将附件通过xshell连接服务器,将附件上传至服务器,通过这样的方式实现导入,其具体的步骤如下: xshell如何传输文件--向服务器上传文件: 1、打开xshell工具,连接到服务器 a、输入服务器的ip、账号、密码 2、yum安装lrzsz工具:其命令为:yum -y install lrzsz 3、查看是否安装成功,其命令为:rpm -qa|grep lrzsz 出现以上信息,说明安装成功。 3、创建目录 4、上传文件,其命令为:rz 就会打开本地选择文件对话框,选择文件,确定就可以上传到当前所在目录。 如果覆盖原文件,其命令为:rz -y 5、查看上传的文件是否成功,可通过:ls 6、配置文件路径: 7、导入整理好的excel文件即可 xshell如何传输文件--从服务器下载文件 1、下载,其命令为:sz #sz {文件} 弹出选择本地保存文件对话框。 2、Alt+P打开属性框,打开【文件传输】,这里可以调整传输的一些属性。下载文件,可以执行下载目录,下载文件时就不会再询问。上传文件,可以直接拖动文件到xshell上传,很方便

常用正则表达式汇总—(数字匹配/字符匹配/特殊匹配)

来源于知乎专栏:https://zhuanlan.zhihu.com/p/29619457这个是我在知乎上看到前辈的专题,里面的专栏帮助了我很多,推荐大家去看看。文章底部有很熟悉的一张正则表附图 1. 校验数字的表达式 1 数字:^[0-9]*$ 2 n位的数字:^\d{n}$ 3 至少n位的数字:^\d{n,}$ 4 m-n位的数字:^\d{m,n}$ 5 零和非零开头的数字:^(0|[1-9][0-9]*)$ 6 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$ 7 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$ 8 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$ 9 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$ 10 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$ 11 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$ 12 非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$ 13 非负整数:^\d+$ 或 ^[1-9]\d*|0$ 14 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$ 15 非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ 16 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ 17 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ 18 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$ 19 浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ 2. 校验字符的表达式 1 汉字:^[\u4e00-\u9fa5]{0,}$ 2 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$ 3 长度为3-20的所有字符:^.

c# winform给Button等本身没有tooltiptext属性的控件添加tooltip提示

1. 对于没有tooltiptext属性的控件来说,要如何添加提示语呢? 在网上查了,大部分介绍都是在控件的MouseEnter事件中写代码: ToolTip p = new ToolTip(); p.ShowAlways = true; p.SetToolTip(this.button1, "要显示的文字"); 但是如果一个窗口有很多控件,岂不是要写很多重复的代码。 可以优化为每个控件使用同一个mouseenter事件,代码为 private void 控件_MouseEnter(object sender, EventArgs e) { ToolTip p = new ToolTip(); p.ShowAlways = true; if ((Control)sender==btn_返回)p.SetToolTip((Control)sender, "取消"); if ((Control)sender==btn_受理)p.SetToolTip((Control)sender, "受理订单"); .....其他控件 } 2. 实际上,.net本身已经给我们提供了tooltip控件,很方便的就可以添加提示语了。 2.1 拖一个tooltip到窗口中后,窗口中的所有控件都会自动添加一个属性:tooltip1上的ToolTip,只要在每个控件的这个属性填上对应的提示语就行了。 实际效果: 2.2 在添加提示语后去构造函数里面查看,代码其实很简单。窗口添加一个tooltip后,使用SetToolTip方法就行了 this.toolTip1.SetToolTip(this.btn_显示下一单, "受理订单并显示下一单"); 2.3 于是我自己用代码尝试了一下: public Form_上下班设定() { InitializeComponent(); ToolTip tooltip1 = new ToolTip(); tooltip1.IsBalloon = true; tooltip1.SetToolTip(lbl_设定, "保存设定"); tooltip1.SetToolTip(txt_堂食歇业公告, "顾客将会看到你的公告,请不要乱写!"); } 实际效果: 所以,tootip,根本不需要使用MouseEnter事件。 3. 总结:有些方法能实现同样的效果,但不一定是最佳的。.

Oracle system 用户无法登录问题

新手刚用Oracle数据库时,可能会遇到system用户无法登录情况。 问题原因:1.可能输入默认密码时输入错误(比较低级,一般不会范)。 2.可能你在安装的时候设置了密码,但是在登录的时候密码不正确,可能是你在安装时的字符集设置的原因。 (若还有其他,请留言让更多的人看到)。 解决:1.使用sysdba账号登录(运行cmd-->sqlplus / as sysdba) 2. 解除锁定账号(例如解除system用户) alter user system account unlock; 3. 为system用户设置新密码(例如设置密码为(推存设置):manager) alter user system identified by manager; 本人测试如下图所示:

【Shiro】权限控制注解

Shiro共有5个注解: RequiresAuthentication: 使用该注解标注的类,实例,方法在访问或调用时,当前Subject必须在当前session中已经过认证。 RequiresGuest: 使用该注解标注的类,实例,方法在访问或调用时,当前Subject可以是“gust”身份,不需要经过认证或者在原先的session中存在记录。 RequiresPermissions: 当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。 RequiresRoles: 当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法。如果当天Subject不同时拥有所有指定角色,则方法不会执行还会抛出AuthorizationException异常。 RequiresUser 当前Subject必须是应用的用户,才能访问或调用被该注解标注的类,实例,方法。 使用方法: Shiro的认证注解处理是有内定的处理顺序的,如果有个多个注解的话,前面的通过了会继续检查后面的,若不通过则直接返回,处理顺序依次为(与实际声明顺序无关): RequiresRoles RequiresPermissions RequiresAuthentication RequiresUser RequiresGuest 例如:你同时声明了RequiresRoles和RequiresPermissions,那就要求拥有此角色的同时还得拥有相应的权限。 需要注意的是,shiro注解可以放到Controller层方法上,也可以放到Service层方法上。但在日常开发中,往往会在Service层添加“@Transactional”注解,为的是当Service发送数据库异常时,所有数据库操作可以回滚。当在Service层添加“@Transactional”注解后,执行Service方法前,会开启事务。此时的Service已经是一个代理对象了,此时如果我们将Shiro的权限注解加载Service层是不合适的,此时需要加到Controller层。这是因为不能让Service是“代理的代理”,如果强行注入,会发生类型转换异常。因此尽量加在Controller层比较好。 下面用@RequiresPermissions为例,将注解加在controller层,看在项目中是怎么用的,其他四种都是类似的。 当方法前可能需要多个权限时,可以自定义注解。如下,就表示RequiresPermissions可以有多个权限标识,默认的逻辑关系为与,即需要同时满足多个权限标识才能执行相关方法,逻辑关系也可修改为或。 package com.yealink.version.shiro; import org.apache.shiro.authz.annotation.Logical; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by yl1794 on 2018/6/13. */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface RequiresPermissions { String[] value(); Logical logical() default Logical.AND; } 在controller的方法前加上注解,逻辑关系为或 @RequiresPermissions(value={"version:delete","version:delete2"},logical = Logical.OR) @GetMapping("/delete/{id}") @ResponseBody public Result delete(@PathVariable String id){ versionService.deleteVersion(id); return success(); } 此时当用户同时具有version:delete,version:delete2权限标识时,才可执行delete方法,否则会提示如下报错。从打印的信息可以看出,当前用户aaa,具有的权限标识中并没有version:delete,因此会报错AuthorizationException。

参数估计

参数估计是什么? 现在有一些样本x,假设他们服从某种分布(例如高斯分布),但是我们并不知道该分布的参数,我们通过这些样本估计出未知的参数,这就是参数估计。 有什么前提? 样本是独立同分布的,且训练样本足够充分。 如果样本不是同一个分布,那么我们的假设(他们服从某种分布)就是错误的。 如果训练样本过少,估计出来的参数就会有偏差。 最大似然估计 反过来考虑,假设存在某个数据流满足高斯分布,我们从中抽出部分样本x,很直观的,我们可以用x的均值和方差来作为数据流的均值和方差的近似值,而当我们把样本的数量逼近无穷时,估计的参数值就收敛于真实值。 而当我们拥有样本x,并假设其满足某种分布时,同样可以用样本来估计参数值。 贝叶斯估计 最大似然估计仅仅使用了样本信息,而贝叶斯估计在其之上,又对参数进行了约束。 贝叶斯估计假设参数不再是一个固定的值,而是一个服从某种分布的变量,通过样本和参数的分布,对参数的值进行估计。 反过来考虑,假设存在某个数据流满足高斯分布,同时该高斯分布的参数值不是确定的,而是满足另一个高斯分布的随机变量。也就是说,每次对该数据流进行采样时,面对的都是一个随机的高斯分布,而该高斯分布的参数满足另外一个高斯分布。 递归 贝叶斯估计对样本的参数进行了约束,假设样本服从的分布的参数是随机变量,服从第二个分布,同样我们可以假设第二个分布的参数也是随机变量,服从第三个分布…由此可以嵌套若干层。

修改 Outlook 数据文件默认保存位置

Outlook 数据文件分为PST文件和脱机OST文件两类,个人邮箱情况还算好,办公邮箱的话,每天邮件数量都非常可观,各种附件很快就会把数据文件撑到几十GB的大小。由于Outlook默认把数据文件存储在系统分区中,对于我这种比较忌讳在系统分区放置读写频繁的缓存类型文件的人来说,是无法容忍的,但是Outlook本身又没有提供可以更改默认保存位置的选项,所以,万事靠自己,不能顺奸的话,那就只好强奸咯。 实现自定义Outlook数据文件保存位置的方法分为两类,一类是尚未设置任何邮件账户,这个最简单,一类是已经设置了邮件账户需要变更数据文件位置的,这个相对复杂些,需要动强的了,下面分别讲解。 一、尚未创建邮件账户时,修改数据文件默认保存位置 首先前往下述地址下载微软提供的官方配置工具 Office Customization Tool,注意有32位和64位的区分,下载后根据自己的系统和软件环境安装对应的软件包即可。 Office 2013 Administrative Template files (ADMX&ADML) and Office Customization Tool 下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=35554 Office 2016 Administrative Template files (ADMX/ADML) and Office Customization Tool 下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=49030 下载完成后,执行安装(实际上就是文件释放的过程),安装过程不作详细说明,安装结束后,去到安装时指定的文件释放目录中,找到ADMX件夹,文件夹内是Office相关的"Group Policy Administrative Template (ADMX/ADML)",意即“组策略管理模板文件”,方便我们通过系统提供的组策略编辑器直接修改相关配置。 将ADMX录下的"outlk16.admx"文件以及zh-cn子目录中的"outlk16.adml"文件分别拷贝到系统分区"C:\Windows\PolicyDefinitions"目录下对应的目录结构中: .\admx\outlk16.admx > C:\Windows\PolicyDefinitions .\admx\zh-cn\outlk16.adml > C:\Windows\PolicyDefinitions\zh-CN 拷贝完成之后,运行“GPEDIT.MSC”启动组策略编辑器 按上图所示路径展开到“PST 文件默认位置”或“OST 文件默认位置”,此处以PST为例,双击打开配置对话框 选择“已启用”,并在下方选项中填入你预设的数据文件保存位置,我这里因为是虚拟机环境,仅有一个系统分区,所以还是设置在系统分区了,建议保存在非系统分区中。对于一些比较老旧的机器而言,该分区的文件系统格式应为NTFS,避免因FAT32分区单文件4GB限制造成的数据文件存取错误。 补充说明:Outlook 2003/2007 的数据文件大小限制为20GB,Outlook 2010/2013/2016 的数据文件大小限制为50GB 参考链接:https://support.microsoft.com/en-us/help/832925/how-to-configure-the-size-limit-for-both-pst-and-ost-files-in-outlook 修改完成后保存退出,后台跟踪定位到如上图所示的注册表修改项,之后所有的邮件账户数据文件都会默认存储到你所指定的目录中了。但需要注意的是,此操作并不会触发数据迁移,也就是之前已经创建的邮件账户数据文件保存位置不会发生改变。 二、修改已经创建过的邮件账户数据文件保存位置 本文以Outlook 2016为例,首先安装Outlook,之后进入控制面板按上图所示步骤创建配置文件,之后根据向导一步一步其实安装好后直接启动Outlook就会自动创建配置文件的,这个随个人喜好,都行。 打开账户设置,可以看到账户数据文件默认保存位置,请先记录下默认位置,修改后需要将原账户的数据文件移动到修改后的默认数据文件保存位置中,如下: %USERPROFILE%\AppData\Local\Microsoft\Outlook 如上图所示,请记下这个跟随数据文件一同创建的XML文档的文件名,其实在注册表中也可以查到,这种方式要相对简单明了一些,接下来打开注册表编辑器。 按上图展开至与刚才记下的XML文档同名的注册项下,修改"001f6610"的键值,替换成想要的目录即可。 修改完成后,将数据文件拷贝到修改后的位置,然后重启Outlook,可以看到已经成功修改了数据文件位置。

C/C++ unsigned 详细探讨

unsigned常应用于无符号数的表示,初学者可能并不知道其在具体应用中的潜在威胁,本文通过一些实例来具体说明。 unsigned char text_digit = -11; unsigned修饰无符号数,-11的补码是11的原码(0000 1011)取反加一:1111 0101(十进制为245) 再此特别注意在if()语句中使用无符号数,若当成负数来看往往会造成很严重的后果 还得注意 unsigned 修饰不同的类型所代表的的大小都不一样。 样例改为 int 总结:unsigned int a和 int b加法运算注意溢出,做减法运算所得到的值自动转换为unsigned类型,c语言中不同精度的值的运算,所得结果往高精度的方向转换而unsigned的精度高于有符号,while(a -b) 这个是死循环,永远为真,因为 不管a>b还是a<b,最后结果都是无符号数。无符号数永远大于0.

vue路由传值及接收传递数据

传递数据 <template> <div id="app"> <router-link :to="{path: '/page', query:{page}}">router-link传值</router-link> <div @click='goPage()'>方法传值</div> </div> </template> JS <script> export default { data () { return { page:‘传递数据’ } } methods:{ goPage(){ //路由传值 this.$router.push({name:'page',params:{msg:page}}) }, } } </script> 接收数据 <template> <div id="page"> {{$route.query.page)}} </div> </template> <script> export default { data () { return { } }, created(){ console.log(this.$route.query) console.log(this.$route.params.msg) } } </script> 喜欢上方小程序,需要源码的,添加博主微信私信小编.

Socket的学习(二)AF_UNIX实现本地通信

参考文章: [1]Unix Domain Socket– IPC通信机制 [2]How fast are Unix domain sockets? [3]read()函数参数理解 一、Unix域的Socket通信及其优点 基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC 更有效率及可靠 : 不需要经过网络协议栈不需要打包拆包、计算校验和、维护序号和应答等,可靠性更强UNIX Domain Socket传输效率比通过loopback地址快将近一倍 二、预备知识 socket通信基本概念LINUX文件操作函数 对于知识一,已经在前面介绍过了。Linux文件操作函数用到了两个:read()和write()。简单介绍一下: read - 从文件描述符里读取数据 #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); fd:文件描述符,对于本文而言是socket套接字 buf:缓冲区指针 count:预期读取的字节数 返回值:表示实际读到的字节数(字符串结束符 '\0’不算) write - 从文件描述符里写入数据 #include <unistd> ssize_t read(int fd, void *buf, size_t count); fd:文件描述符,对于本文而言是socket套接字 buf:缓冲区指针 count:预期写入的字节数 返回值:表示实际写入的字节数(字符串结束符 '\0’不算) 三、程序的功能及其实现 程序的功能是实现客户端发送一个整型数据,服务端返回一个倒序的整型数据。 需要解决的问题: 创建服务端和客户端数据处理 数据处理部分函数实现: int num_reverse(int num) { int S=0,sum=0; while(num) { S=num%10; sum=10*sum+S; num = num / 10; } return sum; } 服务端函数:

理解 es6 class 中 constructor 方法 和 super 的作用

首先,ES6 的 class 属于一种“语法糖”,所以只是写法更加优雅,更加像面对对象的编程,其思想和 ES5 是一致的。 function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function() { return '(' + this.x + ',' + this.y + ')'; } 复制代码 等同于 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } } 复制代码 其中 constructor 方法是类的构造函数,是一个默认方法,通过 new 命令创建对象实例时,自动调用该方法。一个类必须有 constructor 方法,如果没有显式定义,一个默认的 consructor 方法会被默认添加。所以即使你没有添加构造函数,也是会有一个默认的构造函数的。一般 constructor 方法返回实例对象 this ,但是也可以指定 constructor 方法返回一个全新的对象,让返回的实例对象不是该类的实例。

Python爬虫初学:requests库安装(”pip“不是内部或外部命令时,也不是可运行的程序或批处理文件“)

python下载之后,开始了自己的佛系学习之旅。 requests库的安装,适用于win系统: 以管理员身份打开cmd,输入pip install requests,按回车结束。注意:当出现””pip“不是内部或外部命令时,也不是可运行的程序或批处理文件“时,请自行百度判断原因,如果是 环境变量配置问题,解决方法如下: 右击“此电脑”,打开属性,点击“高级系统设置”, 点击环境变量 双击“系统变量”中的“path” 选中最上方的,选择“编辑文本” 在变量值一栏后面打英文分号(不要忘了,划重点)将自己python存储路径复制过来,这种文件的路径哦(如图) 加入路径后如图 这时就可以正常下载requests库了。

第四章 基本C#特性

第四章 基本C#特性 本章我将讨论一些在web应用开发中用到, 但会造成迷惑的C#特性. 但这不是介绍C#, 所以我仅仅为每个特性提供一个简单的例子, 以便你能够看懂本书后面的代码, 以及在自己的项目中应用. 下面的表格概括了这一章节. (主要是因为不熟悉C#语言或C#新版本的语法糖, 比如转行的某语言程序员….后面又臭又长又啰嗦的手把手教学懒得翻译了, 直接提关键点) | - | - | | 问题 | 解决方案 | | 避免访问空引用的属性 | 空条件操作符 | 简化C#属性 | 自动属性 | 简化字符串拼接 | 内插字符串 | 在一步中创建对象并为属性赋值 | 对象或集合初始化器 | 测试一个对象的类型或特征 | 模式匹配 | 向无法更改的类中添加函数 | 扩展属性 | 简化委托和单语句方法 | lambda表达式 | 使用不明确的类型 | var关键字 | 创建对象而不定义类型 | 匿名类 | 简化异步方法 | async和await关键字 | 获取类方法或熟悉的名字而不定义字符串 | nameof表达式 准备示例项目 创建一个名为LanguageFeatures的项目, 使用ASP.NET COre Web Application模板, 创建一个空项目.

常见的HTTP状态码(HTTP Status Code)说明

作为一个前端开发人员对于一些服务器返回的HTTP状态的含义都必须了如指掌。不仅知道200、404和500,还要把常见的状态码都进行了解,这样在工作中遇到问题才能处理的得心应手。 一、HTTP状态码分类 HTTP状态码HTTP状态码共分为5种类型,由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。 分类描述1开头信息,服务器收到请求,需要请求者继续执行操作2开头成功,操作被成功接收并处理3开头重定向,需要进一步的操作以完成请求4开头客户端错误,请求包含语法错误或无法完成请求5开头服务器错误,服务器在处理请求的过程中发生了错误 二、HTTP状态码列表 状态码状态码英文名称描述100Continue继续。客户端应继续其请求101Switching Protocols切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议200OK请求成功。一般用于GET与POST请求201Created已创建。成功请求并且创建了新的资源202Accepted已接受。已经接受请求,但未处理完成203Non-Authoritative Information非授权信息。请求成功。但返回的meta信息不在原始的服务器,是一个副本204No Content无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档205Reset Content重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域206Partial Content部分内容。服务器成功处理了部分GET请求300Multiple Choices多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择301Moved Permanently永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替302Found临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI303See Other查看其它地址。与301类似。使用GET和POST请求查看304Not Modified未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源305Use Proxy使用代理。所请求的资源必须通过代理访问306Unused已经被废弃的HTTP状态码307Temporary Redirect临时重定向。与302类似。使用GET请求重定向400Bad Request客户端请求的语法错误,服务器无法理解401Unauthorized请求要求用户的身份认证402Payment Required保留,将来使用403Forbidden服务器理解请求客户端的请求,但是拒绝执行此请求404Not Found服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”的个性页面405Method Not Allowed客户端请求中的方法被禁止406Not Acceptable服务器无法根据客户端请求的内容特性完成请求407Proxy Authentication Required请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权408Request Time-out服务器等待客户端发送的请求时间过长,超时409Conflict服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突410Gone客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置411Length Required服务器无法处理客户端发送的不带Content-Length的请求信息412Precondition Failed客户端请求信息的先决条件错误413Request Entity Too Large由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息414Request-URI Too Large请求的URI过长(URI通常为网址),服务器无法处理415Unsupported Media Type服务器无法处理请求附带的媒体格式416Requested range not satisfiable客户端请求的范围无效417Expectation Failed服务器无法满足Expect的请求头信息500Internal Server Error服务器内部错误,无法完成请求501Not Implemented服务器不支持请求的功能,无法完成请求502Bad Gateway充当网关或代理的服务器,从远端服务器接收到了一个无效的请求503Service Unavailable由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中504Gateway Time-out充当网关或代理的服务器,未及时从远端服务器获取请求505HTTP Version not supported服务器不支持请求的HTTP协议的版本,无法完成处理 三、总结 常用的HTTP状态码:2XX-请求成功、3XX-重定向、301-永久重定向、302-临时重定向、303-请求其他资源、4XX-客户端错误、401-未认证、403-被拒绝、404-资源不存在、405-不允许使用该方法、5XX服务器端错误、500-服务器内部错误、502-错误网关、503-服务不可用、504-网关超时。 以上这些状态码会经常用于判断服务的可用性上,也很方便适用于前后端联调时出错的判断。

【IoT】分区表(Partition Tables):ESP32 FLASH 分区功能简析

1、背景: ESP32 是一款蓝牙与 WIFI 合一的 IoT 芯片,并且支持 OTA 在线升级功能,在实际产品开发过程中需要对 FLASH 分区定制才能更好地满足产品需求,做刚刚好的产品。 ESP32 系统可以运行多个应用程序,同时包括大量的数据(校正数据、文件系统、参数保存等),分区表存放在 FLASH 偏移地址 0x8000。 2、分区表简析 分区表长度为 0xC00 字节,最多支持 95 个分区入口,使用 MD5 校验,笔者使用的 ESP32 模组是 ESP-WROOM-32,该模组集成了 4MB SPI Flash,在编译esp32程序时,通过make menuconfig -> PartitionTable 可以看到三种分区选择: 工厂程序(无OTA分区): 偏移地址 0x10000 处存放出厂固件,bootloader 启动时默认加载该偏移地址应用程序 # Espressif ESP32 Partition Table # Name, Type, SubType, Offset, Size nvs, data, nvs, 0x9000, 0x6000 phy_init, data, phy, 0xf000, 0x1000 factory, app, factory, 0x10000, 1M 工厂程序(双OTA分区): otadata 分区存储 OTA 升级数据,用于启动时判断加载哪个入口的应用程序:factory、ota_0,ota_1

深入浅出 VuePress(一):如何做到在 Markdown 中使用 Vue 语法

前言 在 vuepress 刚出时,我就觉得这是个很值得追更的开源项目。果不其然,里面众多的前端编程技巧让我受益良多。 于是在周末这种日子里,人家追剧我追码。 今天,我就和大家分享下 vuepress 是如何做到在 Markdown 中使用 Vue 语法的。 原理 众所周知,Markdown 是一种标记语言,类似于 HTML,它也有对应的语法和词法。而 Vue 说白了也是一种语法,关键在于,Markdown 和 Vue 代码都可以被解释成 HTML。 聪明的读者应该想到了:添加一个中间过程,让 Vue 转成 Markdown 或者让 Markdown 转成 Vue,是不是就可以实现在 Markdown 中使用 Vue 语法了呢? 让我们再考虑一下两个方案的实现难点: Vue -> Markdown:template 和 style 部分还好,可 js 部分怎么办?Markdown -> Vue:可以将 markdown 代码解释成 html 或者 js 混入到 vue 代码中。 很显然,第二种方案实现起来更靠谱些,所以尤雨溪也是这样选的: 在语法之间的转换工作上,webpack 的 loader 可是很擅长的。所以,vuepress 自定义了一个 markdownLoader 来将 Markdown 转成 Vue,再通过 vue-loader 得到最终的 HTML。 代码实现 markdownLoader 这是一个自定义的 loader,可参考如何编写一个 loader?

解决Cannot create JDBC driver of class '' for connect URL 'null'问题

解决:启动项目后,修改 Tomcat下的conf下的server.xml如下(注意用户名,密码,url),后 重启服务器(restart)。 <Context docBase="E:\Tomcat\apache-tomcat-7.0.42\wtpwebapps\jdyd" path="/jdyd" debug="5" crossContext="true" reloadable="true" source="org.eclipse.jst.jee.server:jdyd"> <Resource name="jdbc/jdyd" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="scott" password="tiger" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@192.168.81.128:1521:orcl"/> </Context> 注意:是修改server.xml后是重启Tomcat服务器,不是重新build项目。

解析TCP之滑动窗口(动画演示)

概述 滑动窗口实现了TCP流控制。首先明确滑动窗口的范畴:TCP是双工的协议,会话的双方都可以同时接收和发送数据。TCP会话的双方都各自维护一个发送窗口和一个接收窗口。各自的接收窗口大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。各自的发送窗口则要求取决于对端通告的接收窗口,要求相同。 滑动窗口解决的是流量控制的的问题,就是如果接收端和发送端对数据包的处理速度不同,如何让双方达成一致。接收端的缓存传输数据给应用层,但这个过程不一定是即时的,如果发送速度太快,会出现接收端数据overflow,流量控制解决的是这个问题。 窗口的概念 发送方的发送缓存内的数据都可以被分为4类: 1. 已发送,已收到ACK 2. 已发送,未收到ACK 3. 未发送,但允许发送 4. 未发送,但不允许发送 其中类型2和3都属于发送窗口。 接收方的缓存数据分为3类: 1. 已接收 2. 未接收但准备接收 3. 未接收而且不准备接收 其中类型2属于接收窗口。 窗口大小代表了设备一次能从对端处理多少数据,之后再传给应用层。缓存传给应用层的数据不能是乱序的,窗口机制保证了这一点。现实中,应用层可能无法立刻从缓存中读取数据。 滑动机制 发送窗口只有收到发送窗口内字节的ACK确认,才会移动发送窗口的左边界。 接收窗口只有在前面所有的段都确认的情况下才会移动左边界。当在前面还有字节未接收但收到后面字节的情况下,窗口不会移动,并不对后续字节确认。以此确保对端会对这些数据重传。 遵循快速重传、累计确认、选择确认等规则。 发送方发的window size = 8192;就是接收端最多发送8192字节,这个8192一般就是发送方接收缓存的大小。 模拟动画 模拟特点 找到了一个模拟TCP窗口发送的动画的地址,稍微有缺陷:1. 丢包率如果设得太高,有时无论重发多少次都不能恢复正常 2. 窗口最大可为10,其实应该为9 明确发送端和接收端,发送A~S数据包,我们不会从头到尾分析,因为过程比较长。 1. 简化了窗口大小,双方窗口大小都一直是4 2. 设置一定的丢包率,否则没什么值得分析的,包括sender发送的数据包和receiver回复的ACK包。 3. 简化重传机制,出现丢包则直接重传,不等3个冗余ACK和超时。 4. 既不是选择重传也不是退回N步,重传的包是随机的 发 分析滑动窗口机制 首先发送端发送A,B,C,D四个包,但是A,B丢失,只有C,D到达接收端。 接收端没有收到A,所以不回复ACK包。发送端重传A,B,C,D四个包,这次全都到达了。 接收端先获得A,发ACK包A,但是中途丢失;获得B后,根据累计确认的原则,发D的ACK包,然后窗口滑动。再次获得C,D后,连续回复2个D的ACK包,其中C对应的ACK包丢失。 发送端连收2个D的ACK包,说明4个包对方都已收到,窗口滑动,发E,F,G,H包,其中G包丢失。现在整个序列的状态:ABCD是已发送已确认,EFGH是已发送未确认,I~S是不能发送。 接收端先收到E,发ACK包;收到F后发F的ACK包;未收到G,还是发F的ACK包;收到H,还是发F的ACK包。不幸的是,三个ACK包全都丢失。 发送端收到E的ACK包,窗口向右滑动一位;然后再发送F,G,H,I,其中F丢失。 接收端获得I,因为没有G,只好回复F的ACK包。相继收到G,H包。 接收端根据累计确认,连发两个I包,其中H对应的丢失。窗口向右滑动。 发送端接收I的ACK包后,向右滑动四位。发送J,K,L,M四个包,后面不再分析。 从上面的过程中,我们可以得到以下结论: 1. TCP连接是通过数据包和ACK实现的,我们作为第三者可以看到双方发包的过程,但接受者在收到之前不知道发送方发的是什么,同样的,发送方在收到ACK前也不知道对方是否成功接收。 发送方没有收到接收方发回的ACK,就不能向右滑动。假设发送方向接收方发了ABCD就滑动,只要对方没收到A,就不能滑动,那么就会出现二者不同步的局面。 滑动窗口提高了信道利用率,TCP是发送报文段为单位的,假如每发一个报文就要等ACK,那么对于大数据包,等待时间就太长了。只要发送的报文在滑动窗口里面,不用等每个ACK回来就可以向右滑动。本例中,开始接收端空着AB,只有CD,此时不能滑动;之后接收到EF和H,直接向右滑动2位,不必等G到位。 窗口大小不能大于序号空间大小的一半。目的是为了不让两个窗口出现交迭,比如总大小为7,窗口大小都为4,接收窗口应当滑动4,但只剩3个序号,导致两个窗口交迭。 有一种情况没出现:发送方发ABCD,接收方都收到然后向右滑动,但回复的ACK包全丢了。发送方未收到任何ACK, timeout后会重发ABCD,此时的接收方按累计确认的原则,收到ABCD后只会重发D的ACK,发送方收到后向右滑动。 对比滑动窗口和拥塞窗口 滑动窗口是控制接收以及同步数据范围的,通知发送端目前接收的数据范围,用于流量控制,接收端使用。拥塞窗口是控制发送速率的,避免发的过多,发送端使用。因为tcp是全双工,所以两边都有滑动窗口。 两个窗口的维护是独立的,滑动窗口主要由接收方反馈缓存情况来维护,拥塞窗口主要由发送方的拥塞控制算法检测出的网络拥塞程度来决定的。 拥塞窗口控制sender向connection传输数据的速率,使这个速率为网络拥堵状况的函数。

用python生成随机数的几种方法

本篇博客主要讲解如何从给定参数的的正态分布/均匀分布中生成随机数以及如何以给定概率从数字列表抽取某数字或从区间列表的某一区间内生成随机数,按照内容将博客分为3部分,并附上代码。 1 从给定参数的正态分布中生成随机数 当考虑从正态分布中生成随机数时,应当首先知道正态分布的均值和方差(标准差),有了这些,就可以调用python中现有的模块和函数来生成随机数了。这里调用了Numpy模块中的random.normal函数,由于逻辑非参简单,所有直接贴上代码如下: import numpy as np # 定义从正态分布中获取随机数的函数 def get_normal_random_number(loc, scale): """ :param loc: 正态分布的均值 :param scale: 正态分布的标准差 :return:从正态分布中产生的随机数 """ # 正态分布中的随机数生成 number = np.random.normal(loc=loc, scale=scale) # 返回值 return number # 主模块 if __name__ == "__main__": # 函数调用 n = get_normal_random_number(loc=2, scale=2) # 打印结果 print(n) # 结果:3.275192443463058 2 从给定参数的均匀分布中获取随机数的函数 考虑从均匀分布中获取随机数的时候,要事先知道均匀分布的下界和上界,然后调用Numpy模块的random.uniform函数生成随机数。 import numpy as np # 定义从均匀分布中获取随机数的函数 def get_uniform_random_number(low, high): """ :param low: 均匀分布的下界 :param high: 均匀分布的上界 :return: 从均匀分布中产生的随机数 "

Linux (Ubuntu)使用vi和vim方向键变成了ABCD

ubuntu下 vi输入方向键会变成ABCD,这是ubuntu预装的是vim tiny版本,安装vim full版本即可解决。 首先,卸载了原有的vim $ sudo apt-get remove vim-common 然后,安装新的vim-full $ sudo apt-get install vim 以上命令执行完后即可解决问题。

unity中如何获取不规则物体的尺寸

最近在做不规则物体的直径方面的,比如血管的直径,不规则物体的长宽高,这方面的, 主要运用顶点之间的关系进行测量的。 代码如下: using UnityEngine; using System.Collections; public class b : MonoBehaviour { // Use this for initialization public Collider cd; void Start() { cd = GetComponent<MeshCollider>(); Debug.Log("X:"+ cd.bounds.size.x); Debug.Log("Y:"+ cd.bounds.size.y); Debug.Log(":"+ cd.bounds.size.z); } // Update is called once per frame void Update() { } } 首要要获取Collider : 有两种方法 :写脚本 cd = GetComponent(); 另一种就是直接在图形界面中拖入。 然后记住 cd.bounds.size.x 就好了。 Transform 中的scale乘上初始尺寸就为实际长度了。 (如果初始值为0,那么改变scale就不会有变化,就像相机) 转自:https://blog.csdn.net/wzjssssssssss/article/details/53339100

数据可视化之Echarts-lines3D动态轨迹渲染

数据可视化之Echarts-lines3D动态轨迹渲染 谈到数据可视化,不得不提到近两年超级火的ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。 最近一直在学习数据可视化方面的东西,希望和大家分享一些小收获吧。本篇主要是针对大量轨迹数据进行快速渲染。需要用到echarts.js、echartsgl.js和mapbox-gl.js文件。好吧,先来几张效果图: 1、轨迹数据介绍 上图中的示例数据为某商场内的模拟轨迹数据。这里我直接转换成了echarts对应的数据格式,具体如下: var myguiji=[ {'coords':[[122.12255,37.505043],...[122.12255,37.505028]],'lineStyle':{}}, {'coords':[[122.12255,37.505043],...[122.12255,37.505028]],'lineStyle':{}}, {'coords':[[122.12255,37.505043],...[122.12255,37.505028]],'lineStyle':{}} ] 首先整体是一个大的数组,数组里边存放N个json对象。每个json对象包含两个属性名称'coords'和'lineStyle'。 'coords':存放一条轨迹的各个轨迹点的经纬度;'lineStyle':对应轨迹的样式,可以单独对每条轨迹进行单独的样式设置;需要注意的是,当 'coords'里的经纬度点个数大于2时,需要在series下指定polyline: true 2、地图渲染 这里我们使用mapbox的地图充当底图,需要我们引用mapbox的相关文件: <script src="js/mapbox-gl.js"></script> 然后需要一个mapbox asses token,这个自己可以申请一个。 mapboxgl.accessToken = '... ...' 初始化一个echarts对象,并绑定dom元素: var myChart = echarts.init(document.getElementById('container')); 设置mapbox参数: mapbox: { center: [122.12251,37.505028], //地图视图中心点坐标 zoom: 18, //缩放级别 altitudeScale: 2, //海报高度 style: 'mapbox://styles/mapbox/dark-v9', //mapbox地图类型 postEffect: { enable: true, SSAO: { enable: true, radius: 2, intensity: 1.5 } }, light: { main: { intensity: 1, shadow: true, shadowQuality: 'high' }, ambient: { intensity: 0.

关于高德地图 所有省的 adcode

今天有地图需要用的所有省的adcode,就整理了一下,需要的拿走! var adcode = [ {adcode: "110000", name: "北京市"}, {adcode: "120000", name: "天津市"}, {adcode: "130000", name: "河北省"}, {adcode: "140000", name: "山西省"}, {adcode: "150000", name: "内蒙古自治区"}, {adcode: "210000", name: "辽宁省"}, {adcode: "220000", name: "吉林省"}, {adcode: "230000", name: "黑龙江省"}, {adcode: "310000", name: "上海市"}, {adcode: "320000", name: "江苏省"}, {adcode: "330000", name: "浙江省"}, {adcode: "340000", name: "安徽省"}, {adcode: "350000", name: "福建省"}, {adcode: "360000", name: "江西省"}, {adcode: "370000", name: "山东省"}, {adcode: "410000", name: "河南省"}, {adcode: "

android日历提醒之简单实用

前言:我们在自己的项目开发中,经常会有预约提醒、定时提醒等方面的需求,这时我们可以使用安卓自己的系统日历来实现。 通过代码向系统日历中写入日历事件、设置提醒,就可以实现到特定时间时提醒用户的功能。 当然了,网上的关于系统日历使用的文章还是挺多的,但是我浏览了一遍,发现没有可以直接拿过来就可以在项目中使用的,所以就有了今天的博客,致力于如果对面的你需要的话就可以直接复制该文章的代码简单快速的实现你的功能。。。 系统日历提醒的大大大的好处是:由于提醒功能是交付给系统日历来做,不会出现应用被杀的情况,会准时提醒需要的事件!!! 总的来说使用系统的日历功能需要做下面的工作: 1.咱们的程序需要有读写日历权限; 2.如果咱们的程序没有日历账户需要先在日历系统创建自己的账户; 3.最后自己实现日历事件的增删改查、提醒功能; 第一步:申请权限 为了实现在项目中可以调用系统日历和插入日程事件,我们首先在AndroidManifest.xml文件中添加相关权限,如下: <uses-permission android:name="android.permission.READ_CALENDAR"/> <uses-permission android:name="android.permission.WRITE_CALENDAR"/> 在这里,既然说到权限自然绕不过去咱们安卓的高版本动态权限校验和请求授权的事情,请看下面; public void fetchPermission(int requestCode) { int checkSelfPermission; try { checkSelfPermission = ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_CALENDAR); } catch (RuntimeException e) { e.printStackTrace(); return; } // 如果有授权,走正常插入日历逻辑 if (checkSelfPermission == PackageManager.PERMISSION_GRANTED) { insertCalendar(); // 该方法的实现在文章的后面 return; } else { // 如果没有授权,就请求用户授权 ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_CALENDAR}, requestCode); } } 下面的代码就是请求的结果回调的处理: @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.

mysql删除用户的两种方法

drop drop user XXX;删除已存在的用户,默认删除的是'XXX'@'%'这个用户,如果还有其他的用户如'XXX'@'localhost'等,不会一起被删除。如果要删除'XXX'@'localhost',使用drop删除时需要加上host即drop user 'XXX'@'localhost'。 delete delete from user where user='XXX' and host='localhost';其中XXX为用户名,localhost为主机名。 区别 drop不仅会将user表中的数据删除,还会删除其他权限表的内容。而delete只删除user表中的内容,所以使用delete删除用户后需要执行FLUSH PRIVILEGES;刷新权限,否则下次使用create语句创建用户时会报错。

C# winform 中控件禁用,但显示不变灰

Winform中对控件进行禁用,可以达到不接收鼠标的需要,同时可以显示控件的颜色,可以使控件进行正常的显示。 [System.Runtime.InteropServices.DllImport("user32.dll ")] public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int wndproc); [System.Runtime.InteropServices.DllImport("user32.dll ")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); public const int GWL_STYLE = -16; public const int WS_DISABLED = 0x8000000; public static void SetControlEnabled(Control c, bool enabled) { if (enabled) { SetWindowLong(c.Handle, GWL_STYLE, (~WS_DISABLED) & GetWindowLong(c.Handle, GWL_STYLE)); } else { SetWindowLong(c.Handle, GWL_STYLE, WS_DISABLED + GetWindowLong(c.Handle, GWL_STYLE)); } } private void button2_Click(object sender, System.EventArgs e) { SetControlEnabled(this.

SqlServer 行转列,列转行 以及PIVOT函数快速实现行转列,UNPIVOT实现列转行

SqlServer 行转列,列转行 以及PIVOT函数快速实现行转列,UNPIVOT实现列转行 一 、列转行 创建所需的数据 CREATE TABLE [StudentScores]( [UserName] NVARCHAR(20), --学生姓名 [Subject] NVARCHAR(30), --科目 [Score] FLOAT, --成绩 ) INSERT INTO [StudentScores] SELECT '张三', '语文', 50 INSERT INTO [StudentScores] SELECT '张三', '数学', 90 INSERT INTO [StudentScores] SELECT '张三', '英语', 70 INSERT INTO [StudentScores] SELECT '张三', '生物', 95 INSERT INTO [StudentScores] SELECT '李四', '语文', 80 INSERT INTO [StudentScores] SELECT '李四', '数学', 92 INSERT INTO [StudentScores] SELECT '李四', '英语', 86 INSERT INTO [StudentScores] SELECT '李四', '生物', 88

实际项目开发-GitLab CI持续集成

1.概述 Gitlab是常用的开源git代码管理工具之一,随着发展也推出了ci/cd解决方案.顾名思义具体来说ci/cd主要完成以下两个工作: 注:从8.0版本开始,GitLab 持续集成(CI)完全集成到GitLab中,且默认所有的项目开启。 ci(持续构建):代码提交后触发自动化的单元测试,代码预编译,构建镜像,上传镜像等. cd(持续发布):持续发布则指将构建好的程序发布到各种环境,如预发布环境,正式环境. 2.结构 gitlab ci/cd是由独立的runner程序完成,runner采用go语言编写,因此可以很好的进行跨平台,通常可以将runner部署到任何gitlab server之外的服务器,从而避免对gitlab server的影响. 3.gitlab ci/cd流程 gitlab通过在项目的根目录放置.gitlab-ci.yml文件来触发pipline,文件书写遵循yml语法,因此,概括来说gitlab ci/cd只需要两步: 写好.gitlab-ci.yml文件,并放置到项目根目录配置好gitlab runner.完成后,提交代码时会自动根据gitlab-ci.yml的触发条件进行执行相应的stage. 从此刻开始,在每一次push到Git仓库的过程中,Runner会自动开启pipline,pipline将显示在项目的Pipline页面中。 .gitlab-ci.yml文件会告诉GitLab Runner 做什么。默认情况下,它运行一个pipeline,分为三个阶段:build,test,deploy。你并不需要用到所有的阶段,没有job的阶段会被忽略。 如果一切运行正常(没有非零的返回值),您将得到与commit关联的漂亮的绿色标记。这使得在查看代码之前,很容易就能看出是否有一个提交导致了测试失败。 大多数项目使用GitLab CI服务来运行测试套件,这样如果开发人员发现问题就会及时得到反馈。 4.具体在代码中怎么实现 1)创建一个简单的.gitlab-ci.yml .gitlab-ci.yml是用来配置CI在我们的项目中做些什么工作。它位于项目的根目录。在任何的push操作,GitLab都会寻找.gitlab-ci.yml文件,并对此次commit开始jobs,jobs的内容来源于.gitlab-ci.yml文件。因为.gitlab-ci.yml是存在于我们的项目仓库中,并且受版本控制的,所以旧版本也可以执行成功,且使用CI可以让forks更容易,分支可也以拥有不同的pipelines和jobs,而且对于CI来说只会拥有单一的来源。你也可以在我们的博客中找到我们为什么使用.gitlab-ci.yml的原因。 stages: - sonar sonar: stage: sonar script: - mvn -q -Dmaven.multiModuleProjectDirectory=$MAVEN_HOME clean org.jacoco:jacoco-maven-plugin:prepare-agent test checkstyle:checkstyle sonar:sonar -Dsonar.branch.name=$CI_COMMIT_REF_NAME -Dsonar.branch.target=master tags: - java except: - /^(deploy|release|tag){1}.*$/ 2) 推送.gitlab-ci.yml到GitLab 3)到Pipelines页面查看 Running with gitlab-runner 10.7.2 (b5e03c94) on OpenShift Runner b7f20de2 Using Kubernetes namespace: gitlab Using Kubernetes executor with image maven:3-jdk-8 .

FASTDFS分布式文件存储服务器搭建

linux环境Ubuntu16.04 1. 在指定目录下创建fastdfs 安装文件夹 mkdir /wjw #下载tar.zp软件包并安装 mkdir /wjw/testfile #上载文件测试文件夹 mkdir /wjw #fastdfs根文件 mkdir /wjw/fastdfs/track #tracker文件配置路径 mkdir /wjw/fastdfs/storage #storage配置路径 mkdir /wjw/fastdfs/clintlog #client配置路径 2. 安装libfastcommon 1. 解压安装 libfastcommon https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz ar -zxvf V1.0.7.tar.gz cd libfastcommon-1.0.7 ./make.sh ./make.sh install 安装FastDFS https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz tar -zxvf V5.05.tar.gz cd fastdfs-5.05 ./make.sh ./make.sh install 3.Tracker、Storage、Client、HTTP服务 1. 配置Tracker服务 cd /etc/fdfs ls cp tracker.conf.sample tracker.conf # 配置跟踪文件 vi tracker.conf # 进入conf文件 修改配置文件 base_path=/data/fastdfs/track # 修改跟踪路径 http.server_port=80 # 修改端口号 方式启动服务,查看监听:

vue.js 的一些问题

1.必须加key要不然有警告。 2.先注册组件,再新建Vue. 例如: Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }) var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { text: 'Vegetables' }, { text: 'Cheese' }, { text: 'Whatever else humans are supposed to eat' } ] }Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option. (found in root instance)

TextBox设置只读后保留字体颜色

本来我是要显示一段客户留言,只看不能修改。 由于客户留言长度不一,使用textbox可以有滚动条,在内容多时可以看到完整的内容。但是在设置ReadOnly=true后,字体颜色变黑了,很难看。 于是想着使用label,但是发现label没有滚动条,在内容很多的时候无法显示完全。本来还想着重写label,加个滚动条。 关于TextBox的字体颜色网上好多都是说什么window的消息机制,就是没有解决方案。 后来瞄到了一个方法,终于解决了。 记下过程: TextBox在设置只读后,不论原来的forecolor是什么,都会变成灰不溜秋的背景和黑色的字体。 认真观察了下,TextBox刚拖到界面的时候,BackColor会随同界面的BackColor。 但是在设置ReadOnly=true后,BackColor就变成Control了。并且字体显示变成黑色的了。 其实只要把BackColor改变一下,就能正常显示字体了

c++builder codeguard使用方法

最近程序总是出现各种非法访问错误,想找这种错误又比较麻烦,之前有看到网上介绍BCB自带的codeguard工具,据说挺好用的,就研究了一下,只是测试了个很简单的例子,感觉还挺好的,下面是测试过程: 创建一个程序: #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { char *p = new char; //申请内存,没有释放 } //--------------------------------------------------------------------------- 开启codeguard调试: 右键工程Options F9启动程序,结果弹出提示:Nonshared DATA segment required 网上找了好久都没有解决办法,最后在embarcadero论坛上找到一个解决办法,下面是网址 https://forums.embarcadero.com/thread.jspa?messageID=519396&tstart=0#519396 Options-C++Linker-Dynamic RTL 设置为false Options-Packages-Runtime packages 去掉Build with runtime packages前面的“√” 重新编译后启动正常,关闭程序后,可以在exe目录下找到一个cgl后缀的文件,打开内容如下 Error 00176. 0x300010 (Thread 0x13DC): Resource leak: The object (0x2483390) was never deleted The object (0x02483390) [size: 1 bytes] was created with new Call Tree: 0x00401E2C(=Project1.

TS错误信息列表

错误信息列表 code类型英文描述中文描述1002错误Unterminated string literal.未终止的字符串文本。1003错误Identifier expected.应为标识符。1005错误'{0}' expected.应为“{0}”。1006错误A file cannot have a reference to itself.文件不能引用自身。1009错误Trailing comma not allowed.不允许使用尾随逗号。1010错误'*/' expected.应为 "*/"。1012错误Unexpected token.意外的标记。1014错误A rest parameter must be last in a parameter list.rest 参数必须是参数列表中的最后一个参数。1015错误Parameter cannot have question mark and initializer.参数不能包含问号和初始化表达式。1016错误A required parameter cannot follow an optional parameter.必选参数不能位于可选参数后。1017错误An index signature cannot have a rest parameter.索引签名不能包含 rest 参数。1018错误An index signature parameter cannot have an accessibility modifier.索引签名参数不能具有可访问性修饰符。1019错误An index signature parameter cannot have a question mark.索引签名参数不能包含问号。1020错误An index signature parameter cannot have an initializer.

本地开发Vue项目 用axios请求本地服务器数据,解决跨域问题

本地生成的数据 url: http://127.0.0.1/VIP_221/?c=list&cs=cp vue项目怎么请求到我的这个数据呢? 步骤1:在文件夹config下的index.js配置proxyTable, proxyTable: { '/api': { target: 'http://127.0.0.1/VIP_221/?c=list&cs=cp',//目标接口域名 changeOrigin: true,//是否跨域 pathRewrite: { '^/api': ''//重写接口,后面可以使重写的新路径,一般不做更改 } } }, 如图所示: 为什么要用proxyTable?因为跨域 在平时项目的开发环境中,经常会遇到跨域的问题,尤其是使用vue-cli这种脚手架工具开发时,由于项目本身启动本地服务是需要占用一个端口的,所以必然会产生跨域的问题。 用axios请求数据 首先安装axios npm install axios --save -D 在需要用到axios的地方引入axios 运行npm run dev 可以看已经请求到数据

Asp.Net Core 使用Quartz基于界面画接口管理做定时任务

今天抽出一点点时间来造一个小轮子,是关于定时任务这块的。 这篇文章主要从一下几点介绍: 创建数据库管理表 创建web项目 引入quarzt nuget 包 写具体配置操作,实现定时任务处理 第一步:创建一个空web项目,引入quarzt nuget 包 创建TB.AspNetCore.Quartz web项目和TB.AspNetCore.Data 类库,在web项目中引入Quartz nuget包 第二部:数据库创建一张管理表 创建数据库的表结构如图所示,接下来我们在Data项目里添加mysql数据库驱动nuget包 打开PM,执行数据库反向工程命令,从数据库生成model实体 Scaffold-DbContext "Server=你的服务器地址;Database=你的数据库;User=数据库用户名;Password=你的数据库密码;" "Pomelo.EntityFrameworkCore.MySql" -OutputDir Entity **2.1.1 建议不要选用,防坑! 将链接字符串换成你自己的,我们又新添加了一个service文件夹和一个Enum文件夹 其中,BaseService 里封装了针对数据操作的基本crud,quartz里封装了关于定时任务的配置,enum里枚举了任务状态,具体代码如下 下面是baseservice里具体方法 下面是任务调度中心代码 其他几个文件的细节代码我就不再粘贴,详细代码会推到github上去,接下来写一个控制器看看效果! 第四部:项目运行截图 具体详细的东西,也没有说的十分清晰,具体的代码可以到github上去查看, 项目github地址:https://github.com/TopGuo/TB.AspNetCore.Quarzt 原文地址:https://www.cnblogs.com/gdsblog/p/9286779.html .NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

sqlplus不是内部或外部命令

在虚拟机中安装Oracle数据库,在主机中连接时,会报sqlplus不是内部或外部命令....错误; 这是因为本机没有安装,这时需要解压以下两个文件,配置本地环境。 地址:https://pan.baidu.com/s/1lz7ycKG820I8fN4VZOlYMA 这是64位。 解压后,将文件目录添加到path路径下(就像添加JDK路径一样)。 其实主要是下面两个文件起作用。 添加完path路径后,重新打开命令窗口(最好是以管理员身份打开),连接即可。

Java NIO之DirectByteBuffer

转载自:tomas家的小拨浪鼓 堆外内存 之 DirectByteBuffer 详解 堆外内存 堆外内存是相对于堆内内存的一个概念。堆内内存是由JVM所管控的Java进程内存,我们平时在Java中创建的对象都处于堆内内存中,并且它们遵循JVM的内存管理机制,JVM会采用垃圾回收机制统一管理它们的内存。那么堆外内存就是存在于JVM管控之外的一块内存区域,因此它是不受JVM的管控。 在讲解DirectByteBuffer之前,需要先简单了解两个知识点 java引用类型,因为DirectByteBuffer是通过虚引用(Phantom Reference)来实现堆外内存的释放的。 PhantomReference 是所有“弱引用”中最弱的引用类型。不同于软引用和弱引用,虚引用无法通过 get() 方法来取得目标对象的强引用从而使用目标对象,观察源码可以发现 get() 被重写为永远返回 null。 那虚引用到底有什么作用?其实虚引用主要被用来 跟踪对象被垃圾回收的状态,通过查看引用队列中是否包含对象所对应的虚引用来判断它是否 即将被垃圾回收,从而采取行动。它并不被期待用来取得目标对象的引用,而目标对象被回收前,它的引用会被放入一个 ReferenceQueue 对象中,从而达到跟踪对象垃圾回收的作用。 关于java引用类型的实现和原理可以阅读之前的文章Reference 、ReferenceQueue 详解 和Java 引用类型简述 关于linux的内核态和用户态 内核态:控制计算机的硬件资源,并提供上层应用程序运行的环境。比如socket I/0操作或者文件的读写操作等用户态:上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源。系统调用:为了使上层应用能够访问到这些资源,内核为上层应用提供访问的接口。 因此我们可以得知当我们通过JNI调用的native方法实际上就是从用户态切换到了内核态的一种方式。并且通过该系统调用使用操作系统所提供的功能。 Q:为什么需要用户进程(位于用户态中)要通过系统调用(Java中即使JNI)来调用内核态中的资源,或者说调用操作系统的服务了? A:intel cpu提供Ring0-Ring3四种级别的运行模式,Ring0级别最高,Ring3最低。Linux使用了Ring3级别运行用户态,Ring0作为内核态。Ring3状态不能访问Ring0的地址空间,包括代码和数据。因此用户态是没有权限去操作内核态的资源的,它只能通过系统调用外完成用户态到内核态的切换,然后在完成相关操作后再有内核态切换回用户态。 DirectByteBuffer ———— 直接缓冲 DirectByteBuffer是Java用于实现堆外内存的一个重要类,我们可以通过该类实现堆外内存的创建、使用和销毁。 DirectByteBuffer该类本身还是位于Java内存模型的堆中。堆内内存是JVM可以直接管控、操纵。 而DirectByteBuffer中的unsafe.allocateMemory(size);是个一个native方法,这个方法分配的是堆外内存,通过C的malloc来进行分配的。分配的内存是系统本地的内存,并不在Java的内存中,也不属于JVM管控范围,所以在DirectByteBuffer一定会存在某种方式来操纵堆外内存。 在DirectByteBuffer的父类Buffer中有个address属性: // Used only by direct buffers // NOTE: hoisted here for speed in JNI GetDirectBufferAddress long address; address只会被直接缓存给使用到。之所以将address属性升级放在Buffer中,是为了在JNI调用GetDirectBufferAddress时提升它调用的速率。 address表示分配的堆外内存的地址。 unsafe.allocateMemory(size);分配完堆外内存后就会返回分配的堆外内存基地址,并将这个地址赋值给了address属性。这样我们后面通过JNI对这个堆外内存操作时都是通过这个address来实现的了。 在前面我们说过,在linux中内核态的权限是最高的,那么在内核态的场景下,操作系统是可以访问任何一个内存区域的,所以操作系统是可以访问到Java堆的这个内存区域的。 Q:那为什么操作系统不直接访问Java堆内的内存区域了? A:这是因为JNI方法访问的内存区域是一个已经确定了的内存区域地质,那么该内存地址指向的是Java堆内内存的话,那么如果在操作系统正在访问这个内存地址的时候,Java在这个时候进行了GC操作,而GC操作会涉及到数据的移动操作[GC经常会进行先标志在压缩的操作。即,将可回收的空间做标志,然后清空标志位置的内存,然后会进行一个压缩,压缩就会涉及到对象的移动,移动的目的是为了腾出一块更加完整、连续的内存空间,以容纳更大的新对象],数据的移动会使JNI调用的数据错乱。所以JNI调用的内存是不能进行GC操作的。 Q:如上面所说,JNI调用的内存是不能进行GC操作的,那该如何解决了? A:①堆内内存与堆外内存之间数据拷贝的方式(并且在将堆内内存拷贝到堆外内存的过程JVM会保证不会进行GC操作):比如我们要完成一个从文件中读数据到堆内内存的操作,即FileChannelImpl.read(HeapByteBuffer)。这里实际上File I/O会将数据读到堆外内存中,然后堆外内存再讲数据拷贝到堆内内存,这样我们就读到了文件中的内存。 static int read(FileDescriptor var0, ByteBuffer var1, long var2, NativeDispatcher var4) throws IOException { if (var1.

nginx负载均衡反向代理tar包安装,添加nginx_upstream_check_module模块

很久没写了,今天弄了一下nginx负载均衡反向代理,添加淘宝的nginx_upstream_check_module模块,把步骤记录一下。 一、安装nginx 1、安装c++ 以及相关组件,如果已经安装,则忽略 安装c++编译环境, $ yum install -y gcc gcc-c++ 相关组件 $ yum install -y pcre pcre-devel openssl openssl-devel zlib zlib-devel 2、下载安装nginx 2.1 下载nginx安装包,目前阿里的upstream_check_modul补丁包只支持到1.12,所以下载的版本建议为nginx-1.12.2 创建下载包存放路径 $ cd /opt $ mkdir nginx $ cd nginx 下载nginx安装包文件并解压 $ wget http://nginx.org/download/nginx-1.12.2.tar.gz $ tar -xzvf nginx-1.12.2.tar.gz 2.2 下载nginx Health Ckeck模块,并解压。 模块连接介绍:http://tengine.taobao.org/document_cn/http_upstream_check_cn.html $ wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master $ unzip master 若没有unzip命令,下载即可,yum install -y unzip 2.3 安装 $ cd nginx-1.12.2 $ patch -p1 < /opt/nginx/nginx_upstream_check_module-master/check_1.12.1+.patch 如果patch命令不存在,则下载 yum install -y patch $ .

将spring boot项目成jar包,并把配置文件等放在jar包外部

接上篇:如何使用maven打包spring boot项目,打成jar包 前面说了如何将springboot项目打包成jar包,但是这样打包会将所有文件都放入jar包。当我们部署在其他地方需要修改配置时就比较麻烦,那么怎么实现将配置文件打包在外面呢?首先看下我项目的配置文件路径结构: 目标是将自定义config文件下的properties文件和默认application.properties文件放在jar包外 下面是教程: 1.首先在pom.xml文件中添加两个plugin: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix></classpathPrefix> <mainClass>com.Application</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <!-- The configuration of the plugin --> <configuration> <descriptors> <descriptor>src/main/resources/config/package.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix></classpathPrefix> <mainClass>com.Application</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <!-- The configuration of the plugin --> <configuration> <descriptors> <descriptor>src/main/resources/config/package.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> 上面配置中的2个plugin分别是:

iOS常用方法——一个好用的获取导航栏高度和Tabbar高度的分类

开发中经常需要知道导航栏(系统)的高度和Tabbar的高度,一般是用来计算在ViewController中的位置和高度,我们可以写一个UIVIewController的分类,这样在调用的时候就很方便。代码如下: #import "UIViewController+MYViewControllerBar.h" @implementation UIViewController (MYViewControllerBar) -(float)mStatusbarHeight{ //状态栏高度 return [[UIApplication sharedApplication] statusBarFrame].size.height; } -(float)mNavigationbarHeight{ //导航栏高度+状态栏高度 return self.navigationController.navigationBar.frame.size.height + [[UIApplication sharedApplication] statusBarFrame].size.height; } -(float)mTabbarHeight{ //Tabbar高度 return self.tabBarController.tabBar.bounds.size.height; } @end

OSError: [WinError 126] 找不到指定的模块 —— 解决办法

我的python程序在使用ctypes库调用C++程序创建的dll时,会产生如下错误: OSError: [WinError 126] 找不到指定的模块 经百度后发现,引起此类问题的主要原因有二: (1)没有找到该DLL文件,路径不对或者被杀毒软件隔离; (2)你的DLL动态库依赖于其他其他DLL动态库无法被系统找到。在Python里面载入dll时,如果这个dll还依赖于其它的dll的话,这些相关的dll也得要能被Python的进程访问到。 解决方法: 对于原因一,可以把文件路径改为绝对路径;把杀毒软件关闭重新操作。 对于原因二,最基本的解决方式是把相关的DLL 动态库也导进来,这样问题基本就能解决。如果无法确定相关DLL 动态库,引起这类问题的原因很可能是由于你的目标主机没有安装相关的C++环境。解决方法:下载Visual C++ Redistributable运行库,64位版本下载地址为 https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=48145 最终,下载这个运行库后问题完美解决。 转载于:https://www.cnblogs.com/yucen/p/9343555.html

Python读取txt文本出现“ ‘gbk‘ codec can‘t decode byte 0xbf in position 2: illegal multibyte sequence”

1、通过python读取temp.txt时 出现如下错误: 错误的意思是: Unicode的解码(Decode)出现错误(Error)了,以gbk编码的方式去解码(该字符串变成 Unicode),但是此处通过gbk的方式,却无法解码(can’t decode )。“illegal multibyte sequence”意思是非法的多字节序列,即没法(解码)了。 此种错误,可能是要处理的字符串本身不是gbk编码,但是却以gbk编码去解码 。 比如,字符串本身是utf-8的,但是却用gbk去解码utf-8的字符串,所以结果不用说,则必然出错。 通过查阅资料,有提出在读取文本的时候加入参数‘b’,不会提示错误,通过输出读取的数据显 示。 针对以上的这个问题,查阅网上资料,可以按照如下的步骤进行尝试: (1)在打开文本时候,可以指明打开方式: file = open(path, encoding='gbk') (2)如果上一步还不能解决 可能是文本中出现的一些特殊符号超出了gbk的编码范围,可以选 择编码范围更广的‘gb18030’,如: file = open(path, encoding='gb18030') (3)如果上一步还不能解决 说明文中出现了连‘gb18030’也无法编码的字符,可以使用‘ignore’属性忽略非法字符,如: file = open(path, encoding='gb18030', errors='ignore') 或者 file=open(path).read().decode(‘gb18030’,’ignore’)

css改变滚动条样式

#show1{ overflow-x: hidden; overflow-y: hidden; } #show1 ::-webkit-scrollbar { width: 5px; } #show1 ::-webkit-scrollbar-track { background-color: rgba(225,225,225,0.5); } /* 滚动条的滑轨背景颜色 */ #show1 ::-webkit-scrollbar-thumb { background-color: rgba(225,225,225,0.7); } /* 滑块颜色 */ #show1 ::-webkit-scrollbar-button { background-color: rgba(225,225,225,0.5); } /* 滑轨两头的监听按钮颜色 */ #show1 ::-webkit-scrollbar-corner { background-color: #fff; } /* 横向滚动条和纵向滚动条相交处尖角的颜色 */ 转载于:https://www.cnblogs.com/xiaonangua/p/9283963.html

GPIO的8种工作模式详细介绍!

我们在用STM32这颗MCU的时候,用的最多的也是最基础的应该就是GPIO外设了,而在STM32的HAL库中GPIO有8种工作模式 4种输入状态,4种输出状态(2种复用输出2种普通输出),分别对应如下: 如图1所示,浮空输入模式 #define GPIO_MODE_INPUT 0x00000000U / *!<输入浮动模式* / 当GPIO采用浮空输入模式时,STM32的引脚状态是不确定的,此时STM32得到的电平状态完全取决于GPIO外部的电平状态,所以说在GPIO外部的引脚悬空时,读取该端口的电平状态是个不确定的值。 2,模拟输入模式 #define GPIO_MODE_ANALOG 0x00000003U / *!<模拟模式* / 这个很好理解,最常用的场合是ADC模拟输入,不像其他输入模式只有0和1,模拟输入模式可以读取到很细微变化的值。 3,带上拉,下拉输入模式 #define GPIO_MODE_IT_RISING 0x10110000U / *!<具有上升沿触发检测的外部中断模式* / #define GPIO_MODE_IT_FALLING 0x10210000U / *!<具有下降沿触发检测的外部中断模式* / #define GPIO_MODE_IT_RISING_FALLING 0x10310000U / *!<具有上升沿/下降沿触发检测的外部中断模式* / 我查到STM32的数据手册中关于上下拉的电阻的介绍是电阻阻值都在30-50K之间。 为什么要用带上拉或者下拉输入的模式呢?因为浮空模式时,在GPIO外部连接的电路未工作时,STM32读取的GPIO状态是不确定的,所以可以采用带上拉或者下拉输入的模式先给MCU一个确定的状态,当外部电路电平状态发生变化时,易于MCU的判断。这样可以增强MCU的抗干扰能力 下面开始介绍输出模式: 4,推挽输出模式 #define GPIO_MODE_OUTPUT_PP 0x00000001U / *!<输出推拉模式* / 推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。这种结构既可以输出高电平,,也可以输出低电平,可以用于连接数字器件。 推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小,效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。 5,开漏输出模式 #define GPIO_MODE_OUTPUT_OD 0x00000011U / *!<输出开漏模式* / 我们重点讲开漏输出,一般开漏输出模式时,如果外部不接上拉电阻时,只能输出低电平,所以要想输出高电平必须要外接上拉电阻。这样做的有一个好处,可以用来匹配不同的电平信号,也就是用于不同电压的系统之间的通信;另外,因为要输出高电平需要有外部的上拉电阻,所以在进行通信时,通信的速度也受到上拉电阻阻值的影响,阻值小时,通信速度可以很快,阻值大时,通信速度变慢,但也不能为了通信速度把上拉电阻用的很小,也要注意在电阻很小时,功耗会变大,所以要平衡好这个度。 如图6所示,复用推挽,开漏输出模式 #define GPIO_MODE_AF_PP 0x00000002U / *!<备用功能推拉模式* / #define GPIO_MODE_AF_OD 0x00000012U / *!<Alternate Function Open Drain Mode * /

大数据生态圈及重要组件

Spark:计算引擎,框架媒介,调用配置所处位置下的机器的硬件设施来实现调用配置。使用内存来存储数据,运算快,断电丢失。对应于Hadoop圈中的MapReduce Hbase:分布式、面向列的数据库,存储和读取媒介,来源于BigTable(一个结构化数据的分布式存储系统),但HBase是一个非结构化数据存储的数据库。是Hadoop项目的子项目 非结构化、面向列、稀疏 Hadoop:分布式系统基础框架,管理者。MapReduce使用硬盘存储数据 Storm:流式实时计算框架,实时处理大数据流。不同于Hadoop和Spark,Storm不进行数据的收集和存储工作,它直接通过网络实时的接受数据并且实时的处理数据,然后直接通过网络实时的传回结果。 大数据:量大类多的数据集 大数据的技术基础:MapReduce(分布式计算框架)、Google File System(分布式文件系统)和BigTable(数据存储系统) 结构化数据:数字、符号等数据 非结构化数据:文本、图像、声音、视频等数据 大数据分析:可视化分析(百度地图春节人口迁移大数据)、数据挖掘算法(沃尔玛啤酒与尿布、推荐、广告)、预测性分析能力(金融分析、股票预测、气象预测)、语义引擎(siri)、数据质量管理(去假留真) 分布式计算:把一组计算机通过网络相互连接组成分散系统,然后将需要处理的大量数据分散成多个部分,交由分散系统内的计算机组同时计算,最后将这些计算结果合并得到最终的结果。 服务器集群:由互相连接在一起的服务器群所组成的一个并行式或分布式系统。服务器集群中的服务器运行同一个计算任务。因此,从外部看,这群服务器表现为一台虚拟的服务器,对外提供统一的服务。 生态圈及其组件: 蓝色代表Hadoop生态系统组件,黄色Spark生态组件。Hadoop提供了Spark许多没有的功能,比如分布式文件系统,而Spark 提供了实时内存计算,速度非常快。 HDFS:Hadoop的分布式文件系统组件,运行在通用硬件上,使大量数据分布式存储到成千上百台机器 Hive、SparkSQL、Pig:数据仓库系统 YARN:为不同任务分配资源 MLlib:Spark机器学习组件

SpringCloud-API网关服务

摘要正文 1 使用Zuul作为API网关 1.1 如何搭建Zuul项目1.2 如何配置路由规则1.3 如何实现请求过滤 2 使用Gateway作为API网关 2.1 如何加入Spring Cloud Gateway2.2 请求转发的匹配条件 Zuul和Gateway转发不同之处 摘要 路由是微服务架构不可或缺的一部分,本文将会介绍如何使用Zuul或Gateway为SpringCloud构建的微服务提供路由。 参考文档:http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html#_spring_cloud_gateway 正文 1 使用Zuul作为API网关 1.1 如何搭建Zuul项目 创建SpringBoot工程并加入依赖 <dependency> <groupId>org.springframe.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> 创建启动类,通过@EnableZuulProxy注解开启Zuul路由转发功能 @EnableZuulProxy @SpringCloudApplication public class ZuulApplication{ public static void main(String[] args){ new SpringApplicationBuilder(ZuulApplication.class).web(true).run(args); } } Zuul项目已经搭建完成,下面开始配置路由规则。 1.2 如何配置路由规则 默认情况,Zuul会为每个ServiceId添加映射,例如:存在一个ServiceId为user-service的服务,Zuul默认将/USER-SERVICE/**的请求转发到user-service服务的/**上。通过配置zuul.ignored-services可以设置忽视配置的服务映射,*表示忽视全部列表。 下面是配置路由规则的几种方式 zuul.routes.user-service=/api-user/** 将/api-user/**的请求转发到user-service服务上zuul.routes.users.path=/api-user/** zuul.routes.users.serviceId=user-service 将/api-user/**的请求转发到user-service服务上zuul.routes.users.path=/api-user/** zuul.routes.users.url=http://user-service.com/ 将/api-user/**的请求转发到http://user-service.com/地址上 1.3 如何实现请求过滤 通过继承ZuulFilter实现类,实现抽象方法,定义拦截器,注册到Spring容器达到请求过滤到目的。 public class MyFilter extends ZuulFilter{ @Override public String filterType() { // 返回拦截器执行的时期。 // pre路由请求前 // route路由请求时 // post路由请求后 return null; } @Override public int filterOrder() { // 返回过滤器执行顺序 return 0; } @Override public boolean shouldFilter() { // 返回过滤器是否生效 return false; } @Override public Object run() { // 过滤器具体逻辑 RequestContext ctx = RequestContext.

A星算法的c语言及源代码学习,室内环境求最短路径

前段时间用stm32F407制作开发智能仓库小车使用到的这个算法 借鉴于以下两个网站,个人感觉确实很不错 A星算法详解(个人认为最详细,最通俗易懂的一个版本) https://blog.csdn.net/hitwhylz/article/details/23089415 A*算法(附c源码) https://www.cnblogs.com/mingbujian/p/4915546.html

PQ(product quantization) 算法---(一)

转自:http://vividfree.github.io/ 1. 引言 Product quantization,国内有人直译为乘积量化,这里的乘积是指笛卡尔积(Cartesian product),意思是指把原来的向量空间分解为若干个低维向量空间的笛卡尔积,并对分解得到的低维向量空间分别做量化(quantization)。这样每个向量就能由多个低维空间的量化code组合表示。为简洁描述起见,下文用PQ作为product quantization的简称。 The idea is to decomposes the space into a Cartesian product of low dimensional subspaces and to quantize each subspace separately. A vector is represented by a short code composed of its subspace quantization indices. 2011年,Herve Jegou等学者在PAMI上发表了PQ方法的第一篇正式paper[1],用于解决相似搜索问题(similarity search)或者也可以说是近邻搜索(nearest neighbor search)问题。其实这几位作者在2009年的INRIA(即法国国家信息与自动化研究所)的技术报告上已经发表PQ方法。这里插一段题外话,[1]的一作Herve Jegou和二作Matthijs Douze均在2015年跳槽去了Facebook AI research,并在今年3月份合作开源了Faiss相似搜索工具[4]。 近几年,深度学习技术被广泛用于图像识别、语音识别、自然语言处理等领域,能够把每个实体(图像、语音、文本)转换为对应的embedding向量。一般来说,相似的实体转换得到的embedding向量也是相似的。对于相似搜索问题,最简单的想法是暴力穷举法,如果全部实体的个数是n,n是千万量级甚至是上亿的规模,每个实体对应的向量是D,那么当要从这个实体集合中寻找某个实体的相似实体,暴力穷举的计算复杂度是O(n×D),这是一个非常大的计算量,该方法显然不可取。所以对大数据量下高维度数据的相似搜索场景,我们就需要一些高效的相似搜索技术,而PQ就是其中一类方法。 PQ是一种量化(quantization)方法,本质上是数据的一种压缩表达方法(其实通信学科的一个主要研究工作就是研究信号的压缩表达),所以该方法除了可以用在相似搜索外,还可以用于模型压缩,特别是深度神经网络的模型压缩上。由于相似搜索不仅要考虑如何量化的问题,还要考虑如何检索(search)的问题,而模型压缩可能更主要的是考虑如何量化的问题,不用太关注如何检索这个问题,所以这篇文章会主要站在相似搜索上的应用来介绍PQ方法。至于模型压缩,可以找找近几年研究神经网络模型压缩的paper或者一些互联网公司(比如百度, Snap等)发出的一些资料[3]。 2. 相似搜索的若干种方法 参考文献[5][6]很好的总结了相似搜索的几类方法,这里简要总结几个核心点。可以将方法分为三大类: 基于树的方法 KD树是其下的经典算法。一般而言,在空间维度比较低时,KD树的查找性能还是比较高效的;但当空间维度较高时,该方法会退化为暴力枚举,性能较差,这时一般会采用下面的哈希方法或者矢量量化方法。哈希方法 LSH(Locality-Sensitive Hashing)是其下的代表算法。文献[7]是一篇非常好的LSH入门资料。对于小数据集和中规模的数据集(几个million-几十个million),基于LSH的方法的效果和性能都还不错。这方面有2个开源工具FALCONN和NMSLIB。矢量量化方法 矢量量化方法,即vector quantization。在矢量量化编码中,关键是码本的建立和码字搜索算法。比如常见的聚类算法,就是一种矢量量化方法。而在相似搜索中,向量量化方法又以PQ方法最为典型。对于大规模数据集(几百个million以上),基于矢量量化的方法是一个明智的选择,可以用用Faiss开源工具。 3. Product Quantization算法的核心 文献[1]详细介绍了PQ算法的过程和时间复杂度分析,这篇博客的第3节和第4节简要总结下其中的若干要点。 在介绍PQ算法前,先简要介绍vector quantization。在信息论里,quantization是一个被充分研究的概念。Vector quantization定义了一个量化器quantizer,即一个映射函数q,它将一个D维向量x转换码本cookbook中的一个向量,这个码本的大小用k表示。

牛客网刷题(纯java题型 1~30题)

应该是先extend,然后implement class test extends A implements B { public static void main(String[] args) { } } 复制代码 java中四类八种基本数据类型 整数类型:byte,short,int,long 浮点类型: float,double 逻辑型: boolean 字符类型: char 浏览器根据html中指定的编码格式对参数进行编码,Tomcat根据指定的格式对参数进行解码 ,所以getParameter得到的参数的编码是由客户端和web容器配置共同决定的 重载,指的是@overload 重写,指的是@override 重写override是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写! 重载overload,是用在同一函数体中,方法名称不变,方法签名改变 构造函数是不可以使用final修饰的,所以我觉得构造函数不可以是内联函数 (不知道这么说是否正确) 所谓的内联函数,就是函数在被调用的地方直接展开,编译器在调用的时候不用像一般函数那样,参数压栈,返回时参数出栈以及资源释放等,这样提高了程序执行速度,对应java语言中也有一个关键字final来知名那个函数式内联的.内联部已订好,当被指定为内联的方法体很大的时候,展开的开销可能就已经超过了普通函数调用的时间,引入内联反而降低了性能,因此在选择这个关键字的时候需要慎重,不过,在以后高版本的JVM中,在处理内敛的时候做出了优化,他会根据方法的规模来决定是否展开调用 构造函数可以是内联函数 构造函数可以设置默认的参数 构造函数在定义类对象的时候自动执行 FileInputStream,从文件中以字节流读取 FileReader,从文件中以字符流读取 FileWriter,向文件中,写入字符 接口中的变量,默认是public static final 接口中的方法,默认是public abstract Collection类型的集合只能装入Object类型的数据,题中传入的是0,但是会自动装箱为Integer JVM形成对象后会放入堆中,listlist1和listlist2都指向堆中的同一个对象 instanceof是用来判断对象的类型,也就是对象属于哪个类的实例,因为指向的是同一个对象,所以都为Integer对象,也就是都为true Super super = new Sub(); // 向上转型不需要向值类型转换 Sub sub = (Sub)new Super(); // 向下转型必须要强制类型转换 这道题考察的是多态,对于多态,可以总结为: 1,父类引用指向子类对象 2,父类引用只能调用父类的field和method,不能调用子类的field和method,会报错 3,上面说只能调用父类中的field和method,如果子类中的method覆盖了父类中的method,那么使用父类的引用,调用的将是子类中重写的method,而不是父类中的method; 如果子类field与父类field重名,使用父类的引用,调用field的话,调用的是父类中的field的值 3,子类"覆盖"父类的变量不会报错 getDeclaredMethods(): Returns an array containing {@code Method} objects reflecting all the declared methods of the class or interface represented by this {@code Class} object, including public, protected, default (package) access, and private methods, but excluding inherited methods.

Internal server error 500 问题解决思路

我们系统在一次升级之后,生产环境大量出现Internal server error 500错误,具体场景: 在APP上使用拍照功能后,APP通过Http协议上传压缩后的照片到服务端,但是上传过程中大量出现Internal server error 500错误,很多照片都传不上去。 经过一番排查之后,我们最终成功解决了这个问题,最后的原因有些出乎意料,这里卖个关子先不说出来。下面是我们解决问题的整体步骤以及思路。 明确错误含义 首先明确这个错误的含义,参考HTTP状态码的描述。 500 Internal Server Error 通用错误消息,服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。没有给出具体错误信息。 根据这个描述,基本可以排除客户端以及网络因素,需要重点关注服务端的状态。 我们系统服务端的架构如下图: 接下来就要根据这个架构由前往后一层一层排查。 检查HAProxy 重点排查HAProxy当前是否可用,负荷是否超标,包括下面的一些指标。 排查项结果CPU是否正常正常内存是否正常正常线程数是否超过配置上限正常连接数是否超过配置上限正常 排查之后发现一切正常,与版本更新前的数据作比较,也没有出现大幅度波动。 而在查看请求日志时,发现大量500错误信息,说明HAProxy出异常的可能性较小,错误更可能来自HAProxy之后的环节。 检查Jetty 重点排查jetty的配置信息。 排查项结果配置是否有变动正常应用占用的线程数是否超过上限正常应用占用的线程数是否超过上限正常 虽然jetty配置信息检查正常,但是在access.log中存在大量500错误,定位到这里,有两种可能的原因: 应用代码逻辑问题。部分异常信息没有被拦截住,直接抛给Jetty,导致500错误。Jetty逻辑问题。请求没有到达应用,而是由于Jetty自身的某些逻辑导致请求被直接返回了。 检查应用 为了验证是否第一个原因,我们继续走查了应用代码,发现所有的异常都被正确处理了,不存在继续往上抛的情况。另外,也检查了图片保存的代码,确认文件连接都正确释放了。 因此,由于应用逻辑问题导致错误的可能性很小,那么第二个原因的嫌疑最大,就是Jetty逻辑问题。 如果直接排查Jetty的源码,太费时费力,这个时候最好的办法是实时抓包,看看Jetty和应用服务之间到底发生了什么。 使用tcpdump抓包 使用tcpdump命令抓取从jetty到应用服务之间所有的数据包,将结果输出到临时文件中。 tcpdump -i eth0:0 -s0 host 1X.XXX.XXX.XX -w /tmp/out1.cap 使用wireshark打开out1.cap文件,查找出现500错误的数据包,然后很意外的看到了下面的逻辑。 通过这段代码我们发现,jetty对于请求数据的大小做了限制,超过200000 byte的时候就会报错,返回错误码500。 App这次更新后,上传了很多大于200000 byte的图片,于是便出现了大量的500错误。 找到问题根源,修正起来就很简单了,在WEB-INF目录下添加jetty-web.xml 文件解决,文件内容如下: <?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//MortBay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> <Configure id="WebAppContext"class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="maxFormContentSize"type="int"> 0 </Set> </Configure> 总结 出现Internal server error 500错误,往往意味着服务端出现一些未知异常,但是在排查的时候我们不能仅仅只是关注应用服务,而是要关注从服务端接收请求开始,一直到应用服务的整条链路。

Sqlserver递归查询所有上级或所有下级成员

--菜单目录结构表 create table tb_menu( id int not null, --主键id title varchar(50), --标题 parent int --parent id ); --查找所有上级节点 with cte_parent(id,title,parent) as ( select id,title,parent from tb_menu where id = 1 --列出子节点查询条件 union all select a.id,a.title,a.parent from tb_menu a inner join cte_parent b --执行递归,这里就要理解下了 on a.id=b.parent ) select * from cte_parent; ---------------------------------------------- --查找下级节点带level with cte_child(id,title,parent,level) as ( select id,title,parent,0 as level from tb_menu where id = 1--列出父节点查询条件 union all select a.

Sqlserver清理缓存和内存

--清除存储过程缓存 DBCC FREEPROCCACHE --清除会话缓存 DBCC FREESESSIONCACHE --清除系统缓存 DBCC FREESYSTEMCACHE('All') --清除所有缓存 DBCC DROPCLEANBUFFERS GO --打开高级配置 exec sp_configure'show advanced options', 1 GO --设置最大内存MB 2G exec sp_configure 'max server memory', 2048 EXEC ('RECONFIGURE' ) --设置执行时间 WAITFOR DELAY '00:00:10' --设置最大内存MB 20G EXEC sp_configure 'max server memory', 20480 EXEC ('RECONFIGURE' ) GO --关闭高级配置 exec sp_configure'show advanced options',0 GO

关于sql的一些优化,记住以下这些,不要看网上的一些以讹传讹!

1. in 在a in (b, c, d, ... , null)中, 括号里面的比较值里面存在NULL的话, 看其它比较值里面是否有跟a相等的值存在, 如果有则返回true, 否则返回false. 2. not in 在 a not in (b, c, d,..., null)中,如果括号里面存在NULL的话, 则一律返回false. 3. exists 在 exists的关联查询条件里面如果存在NULL的话,则内部查询是查询不出结果的,不符合exists至少有一行结果集返回的判断, 因此返回false. 4. not exists 在not exists的关联查询条件里面如果存在NULL的话,则内部查询也是查询不出结果的,符合not exists对于没有结果集返回的预期判断, 因此返回true. 和DBA共同讨论,结合数据库处理数据逻辑,数据加以验证

shell 字符串转数组

test.sh脚本如下: apps="${1}" #按“T”分隔 arr=(${apps//T/ }) for app in ${arr[@]} do apps2="${app}" #按“,”分隔 arr2=(${apps2//,/ }) for app2 in ${arr2[@]} do echo "${app2}" done done 调用并输出: sh test.sh 1,2T11,12T111,112 1 2 11 12 111 112

MATLAB面向对象编程创建专用图表

开发高级 MATLAB 可视化效果通常需要管理多个低层的图形对象,包含动态更新图形的应用程序更是如此。这种应用程序可能需要非常耗时的编程。Chart 对象可提供高级应用程序编程接口(API),实现可视化的自定义创建。图表可为最终用户提供方便的可视化 API,无需用户执行低层图形编程。 本文以包含最佳拟合线的散点图为主要示例,通过分步指导展示如何使用 MATLAB 面向对象的编程创建和实现自定义图表,包括: ● 编写标准图表模板 ● 编写构造方法 ● 使用 private 属性封装图表数据和图形 ● 使用 Dependent 属性创建高级可视化 API ● 管理图表生命周期 ● 使用继承简化附加图表的开发 图表示例 MATLAB 提供几种图表,包括 heatmap 图和 geobubble 图,前者显示叠放在彩色网格上的矩阵值,后者可快速在地图上绘制离散数据点。 此外,我们还创建几种特定于应用程序的图表。您可以从 File Exchange 中随本文使用的 MATLAB 代码一起,下载这些图表。 创建二维散点图:函数或图表 假设我们要创建包含对应最佳拟合线的二维散点图。我们可以使用 scatter 函数显示离散 (x,y) 数据点,并使用 Statisticsand Machine Learning Toolbox™ 中的 fitlm 函数计算最佳拟合线。 以上代码可满足静态可视化的需求。但是,如果应用程序要求对数据进行动态修改,我们会遇到几个难题: ● 如果使用长度与当前 XData 相同的新数组替换 XData 或 Ydata,最佳拟合线不会动态更新。 ● 如果 Scatter 对象 s 的任一数据属性(XData 或 YData)设置为长度比当前数组长或短的数组,该对象会发出警告且不会执行图形更新。 我们可以通过设计一个图表 ScatterFit 来解决这些难题。 构建图表代码:函数或类 函数将代码封装为可重用单元,用户无需重复代码即可创建多个图表。 注意,此函数需要输入两个数据(x 和 y)。您可以指定图形父项 f(例如,图形)作为第一个输入参数。 ● scatterfit(x,y) 指定输入的两个数据 ● scatterfit(f,x,y) 指定图形父项和数据 在第一种情况下,该函数展示自动生成的行为,即将自动创建图表的图形。

Input.GetAxis("Mouse X")始终取值为0的原因

最近在修改一个BUG,鼠标旋转摄像机,但是就是在某些提供下无法正常表现, Win 7 32 Win 8 32 Win 8 64 Win10 32 绞尽脑汁,逐步定位问题,发现是 Input.GetAxis("Mouse X") 和Input.GetAxis("Mouse Y")的问题。 为什么在这几个系统下, 这2个始终取值为0. 终于。。。 终于。。。 翻山越岭,查阅了很多资料,在一个老外论坛发现了这个问题。 https://forum.unity.com/threads/input-getaxis-mouse-x-always-return-0.135951/ 查看评论发现这是一个unity的bug,在某些windows系统下, 如果windows系统是虚拟机操作环境,这种就出现问题。 好吧最终定位问题,是QA同学是远程桌面测试。。。。 这种还是本机直接测试吧!!! 毕竟很少出现远程其他电脑去玩游戏的现象。。。

Mac下使用终端查看某个端口号对应的进程和杀死进程

查看端口号对应的进程 打开终端,输入lsof -i tcp:port,port即为端口号,如5037 如果端口号未被占用,回车之后结果如图: 如果端口号被占用,则会出现占用该端口号的进程和进程的id,举个例子: 这样我们就可以根据进程id来杀死进程了。 杀死端口号对应的进程 如果某个端口号正在被使用,使用上面的命令就可以查看到具体的进程,想要杀死这个端口号对应的进程,就需要用到命令:kill PID 进程id,PID就是上面我们查到的的PID。 下面是杀死5037端口号对应的进程的操作: 最后可以看到,5037端口对应的进程是空的,也就是5037端口号未被占用。

android应用中ByteBuffer拷贝遇到的坑

android 系统中,ByteBuffer与byte数组的相互转化中,遇到一个拷贝的过程。 开始的时候,采用wrap接口把byte数组转化未ByteBuffer。从底层代码来看,该接口的缓冲区的内容是相互共享的,ByteBuffer中内容发生变化,都会导致byte数组的内容变化。 用put接口,才会把byte数组的内容拷贝到ByteBuffer中。

海康威视多摄像头实时视频预览(基于SDK的二次开发)

项目背景 很久没有做工程项目了,最近突然接单,要做多摄像头下运动物体入侵检测及拌线检测,本文测试用到的摄像头是海康威视的DS-2CD23**D摄像头。 环境配置: 1.下载SDK 2.vs2010开发环境 3..opencv2.4.8 具体配置自行百度吧。下面贴上我这边的主要配置,需要注意的是需要在x64环境下编译。 将摄像头插入以太网口后,那么我们就可以通过官方提供的“设备网络搜索软件“——SADP工具,这个软件可以在海康威视的官方网站下载最新版本。本篇文章的很大程度上参照了lonelyrains的教程,在此基础上进行改进,同时在此表示感谢。 1.先在官网下载到SDK开发包: 下载下来SDK后我们解压,就可以看到里面包含一些开发文档以及一些Demo示例: 2.VS2010下环境配置 首先,配置属性---常规 1)输出目录:$(SolutionDir)\bin\ 2.)中间目录:$(SolutionDir)\Temp\Compile\$(ProjectName)\$(ConfigurationName) 接着,配置属性---调试 VC++目录 包含目录: ..\include opencv目录也要包含进来,继承值里如果没有的话 库目录: 接着C/C++ 常规--附加包含目录 ../include/ 链接器--常规 --附加库目录 ../lib/ 链接器--输入--附加依赖项 HCNetSDK.lib ws2_32.lib PlayCtrl.lib winmm.lib GdiPlus.lib IPHlpApi.Lib 3.opencv配置,参见这里 视频采集 下面进入重点,实时视频采集。 先看看SDK里的demo函数,参见这里 代码如下: NesunCamDriver.h 添加了进程锁,由于考虑到项目保密性,下面开放部分源码。 .cpp源码开放出来: #include "StdAfx.h" #include "NesunCamDriver.h" #include <windows.h> IplImage * NesunCamDriver::m_pImg = NULL; long NesunCamDriver::nPort = -1; float NesunCamDriver::Scalefactor = 1.0f; MTCMutex NesunCamDriver::m_hMutex; HWND NesunCamDriver::m_hPlayWnd=NULL; NesunCamDriver::NesunCamDriver(void) : lUserID(0) , lRealPlayHandle(-1) { /* Create a mutex Lock when a object create */ //m_pImg = NULL; //hMutex = CreateMutex(NULL,FALSE,NULL); } NesunCamDriver::~NesunCamDriver(void) { ReleaseCamera(); } int NesunCamDriver::ReleaseCamera(void) { if(!

移动端底部input被弹出的键盘遮挡的解决办法

input输入框是通过position定位一直放在页面底部,当点击input进行输入的时候,部分机型(尤其是ios系统)底部input被弹出的键盘遮挡,如何解决这个问题呢? 在解决这个问题的时候,有试过下面这种方法: 在input的focus事件中,开启一个定时器,然后每隔300毫秒进行一次document.body.scrollTop=document.body.scrollHeight的调整,运行3次即可。 然而实际体验确差强人意,于是就找到了一下这个办法: Element.scrollIntoView() Element.scrollIntoView():方法让当前的元素滚动到浏览器窗口的可视区域内。 document.querySelector('#inputId').scrollIntoView(); //只要在input的点击事件,或者获取焦点的事件中,加入这个api就好了 123 这个api还可以设置对齐方法,选择将input放在屏幕的上方/下方,这个api还常用于以下效果: 类似的api还有:Element.scrollIntoViewIfNeeded(),这两个是解决同一个问题的,选择一个用就可以了。

Android通用LoadingView加载框架

手写一个通用加载中、显示数据、加载失败、空数据的LoadingView框架。 定义3个布局:加载中,加载失败,空数据 加载中: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:clickable="true"> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:indeterminate="true" /> </FrameLayout> 加载失败: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:clickable="true" android:orientation="vertical"> <ImageView android:id="@+id/error_retry" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:src="@drawable/loading_retry" /> </FrameLayout> 空数据: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:clickable="true" android:orientation="vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/loading_empty" /> </FrameLayout> 自定义一个LoadingView: package com.sample.loadingview.widget; import android.content.Context; import android.content.res.TypedArray; import android.support.annotation.AttrRes; import android.support.annotation.NonNull; import android.

C语言创建与读写txt文件

#include <stdio.h> #include <stdlib.h> #include <math.h> int main() { FILE *fp = fopen("loss.txt", "w"); if (fp == NULL){ printf("Failed to open file"); return 0; } double i, y; for (i = 0, y = 0; i < 100; i += 0.5){ fprintf(fp, "%f\t", i); y = sin(i); fprintf(fp, "%f\n", y); } fclose(fp); //FILE *fpread = fopen("loss.txt", "r"); //if (fpread == NULL) //{ // printf("Failed to open file "); // return 0; //} int a[10] = { 0 }; //int *a = new int[10]; //for (int i = 0; i < 10; i++) //{ // fscanf(fpread, "

小程序批量上传照片至服务器

因为小程序接口wx.uploadFile的限制,一次只能上传一张照片。因此需要想办法解决多个照片上传的问题。 其实原理很简单… 就是在循环that.data.list里的数据,循环调用内含上传接口的方法。 代码如下: uploadPicToJY: function() { var that=this var imgList = that.data.imgList; for (var i = 0; i < imgList.length;i++){ wx.uploadFile({ url: app.globalData.root + 'service/WeChatParent.asmx/UploadPic', //仅为示例,非真实的接口地址 filePath: imgList[i], name: 'image', header: { "Content-Type": "multipart/form-data" }, success: function (res) { var data = res.data } }) } } 后台: [WebMethod(Description = "上传图片")] public void UploadPic() { var resu = ""; HttpPostedFile file = HttpContext.Current.Request.Files[0]; byte[] buffer = new byte[file.ContentLength]; var fs = (System.

剑指offer面试题(11)——旋转数组的最小数字

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组 {3, 4, 5, 1, 2} 为 {1, 2, 3, 4, 5} 的一个旋转,该数组的最小值为 1 。 解题思路 最直观的做法是把旋转数组从前到后遍历一遍,其时间复杂度为 O(n)。很明显,这种解法效率较低。 主要代码如下: int FindMinElement(int* array,int length) { int minElement = array[0]; if (array == nullptr || length <= 0) throw new std::exception("Invalid parameters"); for (int i = 0; i < length; ++i) { if (array[i] <= minElement) minElement = array[i]; } return minElement; } 旋转后的数组实际为两个排序子数组的组合,在排序的数组中可以用二分查找的方法来查找最小数字,其时间复杂度为O(logn)。每次查找都把旋转数组平均分成两部分,通过比较当前旋转数组两端点和中间点的值,判断最小值在数组的哪一部分,从而达到缩小搜索范围的目的。具体过程如下图所示: 需要注意的是,当旋转数组的两端点的值都与中间点的值相等时,无法判断最小值在哪一部分,因此需要采用顺序查找方法,其查找过程如下图所示: 上述查找过程主要实现代码如下: int MinInOrder(int* array,const int& index1, const int& index2) { int minNumber = array[index1]; for (int i = index1 + 1; i <= index2; ++i) { if (array[i] < minNumber) minNumber = array[i]; } return minNumber; } int FindMinElement(int* array, const int& length) { //输入合法检查 if (array == nullptr || length <= 0) throw new std::exception("

Java使用SFTP和FTP两种连接方式实现对服务器的上传下载

转载地址:https://blog.csdn.net/a745233700/article/details/79322757 一、Java实现对SFTP服务器的文件的上传下载 1、添加maven依赖: <dependency> <groupId>com.jcraft </groupId> <artifactId>jsch </artifactId> <version>0.1.54 </version> </dependency> 2、SFTPUtil工具类: import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Properties; import java.util.Vector; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpException; /** * 类说明 sftp工具类 */ public class SFTPUtil { private transient Logger log = LoggerFactory.getLogger( this.getClass()); private ChannelSftp sftp; private Session session; /** SFTP 登录用户名*/ private String username; /** SFTP 登录密码*/ private String password; /** 私钥 */ private String privateKey; /** SFTP 服务器地址IP地址*/ private String host; /** SFTP 端口*/ private int port; /** * 构造基于密码认证的sftp对象 */ public SFTPUtil(String username, String password, String host, int port) { this.

视频云王海华:关于移动短视频技术选型的那些事

摘要: 在短视频时代,让自己的产品提供短视频能力,并拥有良好的用户拍摄和观看体验,让短视频真正能够帮助业务发展是每个产品都应该考虑的问题。如何让自己的应用能够快速拥有短视频的能力,让短视频在你的应用里能够拥有更好的用户体验呢?今天我们从完整的技术链路上来梳理一下搭建一个完整的短视频的服务我们需要考虑哪些技术相关的问题。 在短视频时代,让自己的产品提供短视频能力,并拥有良好的用户拍摄和观看体验,让短视频真正能够帮助业务发展是每个产品都应该考虑的问题。如何让自己的应用能够快速拥有短视频的能力,让短视频在你的应用里能够拥有更好的用户体验呢?今天我们从完整的技术链路上来梳理一下搭建一个完整的短视频的服务我们需要考虑哪些技术相关的问题。首先我们来看一张图: 上图展示了一个移动短视频的一个生命周期,在整个生命周期中包含了以下几个关键的步骤:移动端适配拍摄+编辑,视频文件的上传,视频文件处理(存储,转码,视频理解),视频分发(CDN加速),短视频的播放。 那么下面我们分开来讲讲每个阶段在短视频场景里需要考虑的一些问题。 一、如何选择一个短视频SDK 为什么讲如何选择一个SDK而不是开发一个SDK?因为从零开始开发一个短视频SDK对开发工程师音视频专业能力有较高的要求,而今天在市面上可以找到很多非常成熟的短视频SDK,所以不建议自研。但是面对众多的SDK我们该如何选择呢?我们可以从以下几个方面去评价一个SDK的优劣: 1. 功能的丰富度 现在市场上提供的短视频SDK上看像快手,抖音等主要功能基本已经对齐,各家都会提供一些各自特色的功能,比如阿里云提供实时动态帖子,照片视频混合导入等。这块大家可以根据自己的产品进行选择; 2. 性能表现 说到移动端的性能大家通常会从CPU占用,内存占用,功耗等方面来做出自己的评估,但是对于短视频SDK的特殊场景是用户快速完成一个短视频拍摄和编辑,我们需要充分利用手机的性能包括CPU,GPU等硬件资源来完成 最终视频的合成,所以往往在真正合成的时候CPU占用往往会比较高。 我们来衡量一个短视频SDK的性能通常重点关注两个问题:第一谁能拍摄出更大分辨率,更高帧率的视频,第二导入合成一个相同分辨率,相同时长,相同帧率的视频谁花的时间更短?这里就涉及到短视频的解码性能,渲染性能,编码性能和整体多媒体框架调度性能谁更优秀; 3. 视频质量 拍摄出一个清晰的,流畅的,文件大小又足够小的视频是作为一个SDK或者一个产品需要去追求的。 4. 整体稳定性 移动的环境异常复杂特别在安卓平台,SDK能在各个平台,各种手机上的稳定运行是稳定性的一个重要指标,一般都会从Crash率来评价一个SDK的稳定性。现在市场上很少有SDK公布自己的Crash率,用户可以从SDK的所对接的APP上做一个评估。 5. 扩展性 是否有足够丰富的API提供,能够完成一些个性化的功能开发。 6. 包大小 整个应用安装包的大小直接影响用户下载,更新,安装时间和用户手机存储空间,进而也影响了应用程序的推广成本,所以引入的第三方SDK的包大小也是需要非常关注的。 现在有些SDK为了一味追求包大小直接在短视频SDK中完全使用了硬编硬解,从而抛弃了ffmpeg等第三方包来减少包大小,我认为是不可取的,首先硬编硬解存在非常多的适配问题会引起用户直接无法使用短视频功能,另外在某些机型上硬编硬解的能力不一定比CPU的能力强,所以还是需要根据机型适配合理选择编解码器。 7. 价格 现在市场上一般对短视频SDK都会有自己的一些定价策略,主要有以下几种:跟云端绑定普通功能免费试用,高级功能收取一定的费用几十万不等。另外如果在云端有较大的消费可以拿到一定的折扣。 经过以上这几个维度的比较,我相信能够很快确定一个合适的短视频SDK的。 接下来我们看看在短视频的场景里面云端服务我们如何选择?在选择的时候我们需要重点关注哪些问题? 二、云端服务选择 1. 存储 容量和处理能力弹性扩展,安全可靠是作为一个存储服务必须要具备的能力,所以选择一个可靠的云存储服务是首选的。 阿里云OSS:海量、安全、低成本、高可靠的云存储服务,提供99.999999999%的数据可靠性,使用 RESTful API可以在互联网任何位置存储和访问,容量和处理能力弹性扩展,多种存储类型供选择全面优化 存储成本。 2. 媒体处理 从客户端产生的视频为了让视频更加清晰加上手机端的处理能力毕竟有限,往往这个我们称之为原片的视频文件相对比较大,当我们把文件上传到我们云端提供众多用户进行观看的的时候我们需要关注一下几个问题: 1.如何减低整体带宽流量成本;2.环境复杂的移动端产生的视频在播放的时候是否存在一些兼容性的问题?3.在复杂移动网络下如何提升用户的观看流畅度体验,降低卡顿率?4.如何降低终端用户流量成本?5....... 所有的这些问题使得我们都需要在云端对视频做一次统一的处理保证视频格式的统一从而提升播放的兼容性,同时需要在保证清晰度不下降的情况下尽量压缩文件大小。 小贴士:一般视频处理(转码)需要一定的耗时,根据视频时长从几秒钟到几分钟不等,而在短视频场景里面往往需要快速消费,在这种场景里面通常做法可以采用异步处理的方式来做,先让用户观看原片,等待转码完成后再把各种清晰度的视频下发给观众。 在阿里云点播放服务中只需要几个简单的配置就可以完成以上所有的能力,除了这些能力以外,点播服务是集强大的媒资管理能力,视频编辑能力,详细的数据统计能力,分发加速于一体的一站式音视频点播解决方案。 三、播放器 视频的最终的消费就是需要有一个优秀的播放器,选择一个播放器的时候除了关注CPU占用,内存占用,功耗,以及一些传统播放的能力以外在短视频场景里面会有自己比较特殊的几个需求,主要有以下几点: 像抖音这种沉浸是的播放体验中离不开播放器的快速启播的能力(秒开);短视频往往都会有较多的循环播放的需求,需要考虑首尾循环是否无缝和为了节省流量播放器有缓存的能力;播放行为数据是一个对视频产品非常重要的,播放器是否提供行为数据埋点,上报,云端分析,最终报表展示也是至关重要的; 小贴士:播放器有著名的开源的播放器ijkplayer,但是各种优化和功能的开发需要有专业开发资源。另外各大云厂家也都提供了各自播放器。建议是端和云能够配套使用,这样才能够发挥出各自的优势达到更好的播 放体验; 解决上了以上的几个技术问题以后,基本能够完成整个短视频产品的开发了。 四、视频AI 很多短视频场景都是UGC的业务场景,用户可以任意拍摄和上传自己的短视频到平台上。而在国内的大背景下视 频涉黄,涉政,涉恐,广告,重复视频的审核,为了做好视频管理和推荐的基础就是需要对视频内容进行多维度的 理解和打标,这些问题是不得不考虑的问题,在产品前期视频量较少的情况下可以有人工进行审核和视频运营人员 进行打标。随着产品的发展海量的短视频场景中通过纯人工完成这两项工作几乎是不可能的。所以视频AI是一个不得不考虑的一个问题。 原文链接

MVC、MVP、MVVM,我到底该怎么选?

本文由玉刚说写作平台提供写作赞助 原作者:AndroFarmer 版权声明:本文版权归微信公众号玉刚说所有,未经许可,不得以任何形式转载 前言 MVC、MVP、MVVM是我们工作和面试中都比较重要的一块,但很多时候我们却有点迷惑。比如看了好多篇文章都搞不懂MVC到底是个啥本来想写个MVP写着写着就变成MVC了,到底Databing和MVVM之间有啥见不得人的关系。本篇文章主要从发展的角度来介绍,如mvp,mvvm的出现都是为了解决前者的哪些问题。如果你有同样的疑问,本篇文章可能会给你带来一点收获。但是架构和设计模式相对来说不是那么容易捉摸透的东西,很多需要经过实践才能体会,另外由于本人水平有限,如果写的不对或者不严谨的地方,请不要打我。 MVC 可能由于MVP、MVVM的兴起,MVC在android中的应用变得越来越少了,但MVC是基础,理解好MVC才能更好的理解MVP,MVVM。因为后两种都是基于MVC发展而来的。 1、MVC眼花缭乱设计图 我们从网上搜索mvc相关资料时,如果你多看几篇文章的话可能会发现,好像他们介绍的设计图都不太一样,这里罗列了大部分的设计图 2、MVC设计图解释 到底上面列出的设计图哪个才是对的。其实都是对的。为什么这么说呢,这得从mvc的发展说起。 MVC框架模式最早由Trygve Reenskaug 于1978年在Smalltalk-80系统上首次提出。经过了这么多年的发展,当然会演变出不同的版本,但核心没变依旧还是三层模型Model-View-Control。 3、MVC三层之间的关系 箭头→代表的是一种事件流向,并不一定要持有对方,比如上图中model→view的事件流向,view可以通过注册监听器的形式得到model发来的事件。在设计中model view controller之间如果要通讯,尽量设计成不直接持有,这样方便复用。也符合mvc的设计初衷 在android中三者对应的关系如下: 视图层(View) 对应于xml布局文件和java代码动态view部分 控制层(Controller) MVC中Android的控制层是由Activity来承担的,Activity本来主要是作为初始化页面,展示数据的操作,但是因为XML视图功能太弱,所以Activity既要负责视图的显示又要加入控制逻辑,承担的功能过多。 模型层(Model) 针对业务模型,建立的数据结构和相关的类,它主要负责网络请求,数据库处理,I/O的操作。 由于android中有个god object的存在activity,再加上android中xml布局的功能性太弱,所以activity承担了绝大部分的工作。所以在android中mvc更像是这种形式: 因为activity扮演了controller和view的工作,所以controller和view不太好彻底解耦,但是在一定程度上我们还是可以解耦的。 Talk is cheap. Show me the code. 扯了这么多,我们来看点代码。 4、MVC sample 通过代码来看下,mvc在android中的实现 结构很简单,这里介绍下其中的关键代码 public interface BaseModel { void onDestroy(); } 复制代码 BaseModel顾名思义就是所有业务逻辑model的父类,这里的onDestroy()方法用于跟activity或者fragment生命周期同步,在destroy做一些销毁操作 public interface Callback1<T> { void onCallBack(T t); } public interface Callback2<T,P> { void onCallBack(T t,P p); } 复制代码 Callback是根据View或者Controller调用Model时回调的参数个数选择使用 public class SampleModel implements BaseModel{ public void getUserInfo(String uid,Callback1<UserInfo> callback) { UserInfo userInfo= new HttpUtil<UserInfo>().

操作系统总结之内存管理(除虚拟内存管理)

0 内存管理概述 包括内存管理和虚拟内存管理。 内存管理包括:内存管理概念、交换与覆盖、连续分配管理方式和非连续分配管理方式(分页管理方式、分段管理方式、段页式管理方式)。 虚拟内存管理包括:虚拟内存概念、请求分页管理方式、页面置换算法、页面分配策略、工作集和抖动。 内存管理的概念 操作系统对内存的划分和动态分配 内存管理的功能 内存空间的分配与回收:由操作系统完成主存储器空间的分配和管理,使程序员摆脱存储分配的麻烦,提高编程效率。地址转换:在多道程序环境下,程序中的逻辑地址与内存中的物理地址不可能一致,因此存储管理必须提供地址变换功能,把逻辑地址转换成相应的物理地址。内存空间的扩充:利用虚拟存储技术或自动覆盖技术,从逻辑上扩充内存。存储保护:保证各道作业在各自的存储空间内运行,.互不干扰。 1 存储器的层次结构 CPU 寄存器 寄存器主存 高速缓存 主存 磁盘缓存辅存 磁盘 可移动存储介质 寄存器,高速缓存,主存,磁盘缓存属于操作系统存储管理,掉电后其信息不再存在 辅存和可移动存储介质 属于设备管理(因此会涉及中断,设备驱动程序和物理设备的运行),存储的信息被长期保存 1.1 主存储器和寄存器 主存储器 用于保存进程运行时的程序和数据,也称为可执行存储器。cpu将所取得的指令放入指令寄存器中,将数据放入数据寄存器中。现在内存由VLSI 构成。寄存器 寄存器的访问速度最快,完全能与CPU协调工作,但价格却十分昂贵。比如:使用寄存器存放操作数,用作地址寄存器加快地址转换速度等等 。 1.2 高速缓存和磁盘缓存 高速缓存 用量远大于寄存器,而比内存小两到三个数量级,访问速度快于主存储器。存储一些经常访问的信息,减少访问主存储器的次数,可大幅度提高程序的执行速度。通常,进程的程序和数据存放在主存,每当使用时,被临时复制到高速缓存中,当CPU访问一组特定信息时,首先检查它是否在高速缓存中,如果已存在,则直接取出使用,否则,从主存中读取信息。有的计算机系统设置了两级或多级高速缓存,一级缓存速度最高,容量小,二级缓存容量稍大,速度稍慢。磁盘缓存 磁盘的IO速度远低于对主存的访问速度,因此将频繁使用的一部分磁盘数据和信息暂时存放在磁盘缓存中,可减少访问磁盘的次数,磁盘缓存本身并不是一种实际存在的存储介质,它依托于固定磁盘,提供对主存储器空间的扩充,即利用主存中的存储空间,来暂存从磁盘中读出或写入的信息,辅存中的数据必须复制到主存方能使用,反之,数据也必须先存在主存中,才能输出到辅存。 2 程序的装入和链接 为了使程序能够运行,必须先为之创建进程,而创建进程的第一件事,就是将程序和数据装入内存,如何将一个用户源程序变为一个可在内存中执行的程序,通常要经过如下几步,首先是编译(由编译程序将用户源代码编译成若干个目标模块),其次是链接(由链接程序将编译后形成的一组目标模块,以及它们所需要的库函数链接在一起,形成一个完整的装入模块),最后是装入(由装入程序将装入模块装入内存) 2.1 程序的装入方式 在装入一个模块到内存时,有绝对装入方式,可重定位装入方式,动态运行时装入方式。 1. 绝对装入方式 如果在编译时知道程序驻留在内存的什么位置,那么,编译程序将产生绝对地址的目标代码,绝对装入方式按照装入模块中的地址,将程序和数据装入内存,装入模块被装入内存后,由于程序中的逻辑地址与实际内存地址完全相同,故不需要对程序和数据的地址进行修改。 2. 可重定位装入方式 由于绝对装入方式只能将目标模块装入到内存中事先指定的位置,在多道程序环境下,编译程序不可能事先知道所编译的目标模块应放在内存的何处,因此,绝对装入方式只适用于单道程序环境,在多道程序环境下,所得到的目标模块的起始地址通常都是以0开始的,程序中的其他地址也都是相对于起始地址计算的,此时应采用可重定位装入方式,根据内存的当前情况,将装入模块装入到内存的适当位置。该方式会使装入模块中的所有逻辑地址与实际装入内存的物理地址不同,需要对数据地址和指令地址进行修改,通常把在装入时对目标程序中指令和数据的修改过程称为重定位,又因为地址变换通常是在装入时一次完成的,以后不再变化,故称为静态重定位。 3. 动态运行时装入方式 可重定位装入方式允许将装入模块装入到内存中任何允许的位置,故可用多道程序环境,但这种方式并不允许程序运行时在内存中移动位置,因为,程序在内存中的移动,意味着它的物理位置发生了变化,这就必须对程序和数据的地址进行修改后方能运行。然而,在运行过程中它在内存中的位置可能经常要改变,此时就应该采用动态运行时装入方式。动态运行时的装入程序在把装入程序装入内存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序真正要执行时才进行。因此,装入内存后的所有地址都仍是逻辑地址,为了使地址转换不影响指令的执行速度,需要重定位寄存器的支持。 提问:程序在装入内存后还需要进行移动?为什么?如果是对换,那么为什么不能等价于重新装入? 答:正在寻找。。。。。。 2.2 程序的链接 源程序经过编译后,可得到一组目标模块,再利用链接程序把这组目标模块链接,形成装入模块,根据链接时间的不同,可把链接分为三种: 1.静态链接:在程序运行之前,先将各目标模块及他们所需的库函数, 链接成一个完整的装配模块,以后不再拆开 2.装入时动态链接:将用户源程序编译后所得到的一组目标模块, 在装入内存时,采用边装入边链接的链接方式 3.运行时动态链接:对某些目标模块的链接,是在程序执行中需要该模块时,才对它进行链接 1. 静态链接 在将几个目标模块装配成一个装入模块时。须解决两个问题: (1)对相对地址进行修改 (2)变换外部调用符号 。 比如:三个目标模块A,B,C。合为一个时,B的起始地址变为L,C->(L+M),因为编译程序产生的所有目标模块中,使用的都是相对地址,其起始地址都为0,每个模块中的地址都是相对于起始地址计算的。而外部符号 B,C要变为起始地址L和L+M 2. 装入时动态链接 用户源程序经编译后所得是目标模块,是在装入内存时边装入边链接的,即在装入一个目标模块时,若发生一个外部模块调用事件,将引起装入程序去找出相应的外部目标模块,并将它装入内存,装入时动态链接有如下优点,便于修改和更新(各目标模块是分开的存放的,所以要修改或更新各目标模块非常容易),便于实现对目标模块的共享(很容易将一个目标模块链接到几个应用模块上,实现多个应用程序对该模块的共享)

C++中的友元和内联函数

友元函数 创建一个类,让他里面仅仅只有一个私有变量: void Test(const Test& a) { a._a = 1;//可以在友元函数内部直接访问类的私有变量 } class Test { friend void Test(const Test& a);//友元函数的声明;在哪个类里面声明,这个函数就是哪个函数的友元函数 private: int _a; }; int main() { Test a; return 0; } 想要通过一个类外的函数去访问类中的私有变量在一般情况下是不可行的,友元函数可以直接访问类的非公有成员,它的定义是在类外部的普通函数,不输入任何类,但是它需要在类的内部进行声明,声明时需要加上friend关键字。 ●友元函数可以访问类的非公有成员,但它不是类的成员。 ●友元函数不能用const进行修饰。 ●友元函数可以在类中的任何地方进行友元声明,不受类访问限定符的限制。 ●一个函数可以是多个类的友元函数。 ●友元函数的调用和普通函数的调用原理相同。 友元函数的声明 友元函数的声明仅仅指定了访问的权限,而非一个通常意义上的函数声明。如果我们希望类的用户能够调用某个友元函数,那么我们必须在友元声明之外再专门对函数进行一次声明。 友元类 class A { private: int _a; }; class B { friend class A;//声明A类为B类的友元类 public: void Test()//当A类为B类的友元类的,B类中的函数也可以访问A类中的任意成员 {} private: int _b; }; int main() { A a; B b; return 0; } 如果一个类指定了友元类,则友元类的成员函数可以访问此类包括非公有成员在内的所有成员。(友元类的所有成员函数都可以是另一个类的友元函数) 注意: ●友元关系是单向的,不具有交换性 ●友元关系不能继承 ●友元关系不能传递 友元类的优点:提高了程序的运行效率 友元类的缺点:破环了类的封装性和隐蔽性

thymeleaf+bootstrap,onclick实现传订单id到模态框中

下面是一个评价订单的功能代码 <a id="myModal" data-toggle="modal" data-target="#exampleModal" th:οnclick="'javascript:Values('+${item.id}+')'">评价服务</a> 模态框代码 <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">评价</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <form class="table" th:action="@{/order/evaluate}" method="post"> <input id="id" name="id" type="hidden" value=""/> <span>请输入评价内容:</span> <textarea class="form-control" aria-label="With textarea" name="evaluateContent"></textarea> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> <button type="submit" class="btn btn-primary">提交</button> </div> </form> </div> </div> </div> </div>js代码 <script type="

手机手动设置代理之后打不开页面

如果发现手机设置代理之后一切设置正常,就是没有打开页面,那出问题的地方很有可能是Windows自带的安全防火墙墙了它,只要打开控制面板把防火墙关了就可以了。