vs2013编译驱动错误-Inf2Cat,signability test failed

点进去看细节: 看打印是inf 文件的catalogfile 名字不对,找一找inf文件 在Driver Files下面。猜测应该是在属性里面配置,右键单击 直接看到属性里面的catalog File Name,猜测可能是工程名加后缀的,毕竟整个功臣给里面的自动生成的都是这个格式的 应用然后确定,再F5 编译 这回结果就全对了。

深度学习:乳腺x检测

乳腺影像学检测方法 在乳腺癌的诊疗过程中,主要有超声,钼靶,核磁共振(MRI),CT检查(月经后1-2周),病理和基因等医学手段用于辅助诊断和治疗。其中超声和钼靶主要用于乳腺癌的初筛,MRI用于治疗效果的评估,病理用于癌症的确诊以及治疗方案的评估。近年来,基因分析在肿瘤诊疗方面也得到了快速发展,主要用于遗传性乳腺癌的筛查以及个性化的精准医疗。目前我们团队完成了乳腺钼靶AI诊断产品的研发和落地,并且在核磁共振和病理方面,相关的研发的工作也已经展开。 1、影像:轴位片(头足位 CC) 斜位片(MLO)*左右=4张影像 同侧 例如:rcc 或者R-mlo用于定位 左右两侧 例如:R-CC L-CC 用于比较是否不对称,两侧同拍照模式进行对比 2、BI-RADS评价分类 0类为不定类别,需进一步的影像学检查1类为未见异常 Ⅰ2类为良性 Ⅱ3类为可能良性 Ⅲ4类为可疑恶性 Ⅳ5类为高度提示恶性 Ⅴ6类为活检证实恶性 Ⅵ 3、数据集: 3.1 DDSM (10263张,4025正例,标签分类,分割) Digital Database for Screening Mammography (DDSM) 是乳腺数据集中比较著名和数据量比较大的一个数据集,分为四个子文件夹:分别是benign_without_callbacks, benigns, cancers, normals 代表乳腺检查的不同类别,每个子文件夹中各有很多个case,每个case代表一个样例 其中LJPEG文件是乳腺图片的原始格式,目前正在转为png格式,每个样本有四张乳腺图片,如果是有病的样本,至少会有一张图片有分割标签;.mat文件是从原始的.overlay文件中获得的分割标签。 3.2 CBIS-DDSM 图像已解压缩并转换为DICOM格式。更新了ROI分段和边界框,还包括了训练数据的病理诊断 注释了钙化和肿块的ROI。 数据集包含753个钙化病例和891个肿块病例 3.3 Inbreast (410张,100正例,标签分类,少量带框标签) 3.4MIAS (322张,分类标签) 4、乳腺检测任务 4.1分类+检测 弱监督学习( 定位通常通 CAM or MIL ) 7分类 等级分类==》2分类 0-2 为良性 4-6 为恶性 3不参与考虑 2分类 钙化和肿块 4.2 分类+分割 5、方法实现

【Linux学习】Linux free 命令学习

一、学习这个命令的背景 因为最近Gitlab服务器占用内存很多,也在下面的这篇博客里面写了怎么减少Gitlab占用的内存问题。 +【Git学习】解决GitLab内存消耗大的问题 但是一开始并没有很清楚的明白free命令的每一个数据到底代表的什么意思,导致一直以为优化没有效果。后面认真学习了下free命令,先看看 操作系统版本是 Ubuntu 14.04 linux的内核版本号是 3.13.0-24-generic root@ubuntu116:~# uname -r 3.13.0-24-generic 您在 /var/mail/root 中有新邮件 root@ubuntu116:~# uname -a Linux ubuntu116 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux 您在 /var/mail/root 中有新邮件 root@ubuntu116:~# cat /proc/version Linux version 3.13.0-24-generic (buildd@panlong) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 root@ubuntu116:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.

配置安全组

安全组是一种虚拟防火墙,用来控制ECS的出站和入站流量。 在同一个VPC内,位于相同安全组的ECS实例私网互通。默认情况下,VPC内的不同交换机下的ECS实例可以通过系统路由相互访问。你可以通过配置安全组规则,使其互相隔离。详情请参考 VPC内设置私网隔离。 默认安全组 当你创建专有网络类型的ECS实例时,可以使用系统提供的 默认安全组规则,也可以选择VPC中已有的其它安全组。 安全组规则配置 具体的安全组规则配置方法,请参考 添加安全组规则。 安全组应用案例,请参考 应用案例。

【Codeforces Round #522 C - Playing Piano】爆搜+剪枝

C. Playing Piano 题意 给你一个a数组,让你按照规则构造b数组 规则如下 如果 a i &lt; a i + 1 a_i&lt;a_{i+1} ai​<ai+1​那么 b i &lt; b i + 1 b_i&lt;b_{i+1} bi​<bi+1​ 如果 a i &gt; a i + 1 a_i&gt;a_{i+1} ai​>ai+1​那么 b i &gt; b i + 1 b_i&gt;b_{i+1} bi​>bi+1​ 如果 a i = a i + 1 a_i=a_{i+1} ai​=ai+1​那么 b i ! = b i + 1 b_i!=b_{i+1} bi​!=bi+1​ 给出b数组或者输出-1表示b数组不存在。 做法 考虑一下会发现只有两种情况会出现-1 第一种:连续上升/下降的个数>=6个 第二种:连续五个上升/下降,连续五个下降/上升

xml转json的两种方法

1.第一种方法 使用JSON-JAVA提供的方法,之前一直使用json-lib提供的方法转json,后来发现了这个开源项目,觉得用起来很不错,并且可以修改XML.java中的parse方法满足自己的转换需要。 (1)首先去git下载所需的java文件,并导入项目 Git:https://github.com/stleary/JSON-java (2)使用XML.java中提供的XML.toJSONObject(xml)方法即可完成xml到json的转换,同时也可以对JSON进行格式化 /* 第一种方法,使用JSON-JAVA提供的方法 */ //将xml转为json JSONObject xmlJSONObj = XML.toJSONObject(xml); //设置缩进 String jsonPrettyPrintString = xmlJSONObj.toString(4); //输出格式化后的json System.out.println(jsonPrettyPrintString); 2.第二种方法 使用json-lib的XMLSerializer对象 (1)创建XMLSerializer对象 (2)使用XMLSerializer的read(xml)方法即可 /* 第二种方法,使用json-lib提供的方法 */ //创建 XMLSerializer对象 XMLSerializer xmlSerializer = new XMLSerializer(); //将xml转为json(注:如果是元素的属性,会在json里的key前加一个@标识) String result = xmlSerializer.read(xml).toString(); //输出json内容 System.out.println(result); 3.测试 public class Test { public static void main(String[] args) { String xml = "<class id=" + "'1'" + "><student><name>aaaaaa</name><age>21</age></student><student><name>bbbbbb</name><age>22</age></student></class>"; /* 第一种方法,使用JSON-JAVA提供的方法 */ //将xml转为json JSONObject xmlJSONObj = XML.toJSONObject(xml); //设置缩进 String jsonPrettyPrintString = xmlJSONObj.

Netty4实现HTTP请求、响应

前言: 我们所编写的项目多以BS为主,用户通过浏览器访问我们的服务器 发送的请求以HTTP请求为主,本例就以Netty4来实现一个接收HTTP请求的服务器,并根据用户请求返回响应 1.Netty中HTTP请求和响应类 请求(FullHttpRequest) /** * Combine the {@link HttpRequest} and {@link FullHttpMessage}, so the request is a <i>complete</i> HTTP * request. */ public interface FullHttpRequest extends HttpRequest, FullHttpMessage { 可以看到,它结合了HttpRequest、FullHttpMessag,作为一个完整的HTTP请求体。 默认实现为DefaultFullHttpRequest 响应(FullHttpResponse) /** * Combination of a {@link HttpResponse} and {@link FullHttpMessage}. * So it represent a <i>complete</i> http response. */ public interface FullHttpResponse extends HttpResponse, FullHttpMessage { 同样,它结合了HttpResponse、FullHttpMessage 默认实现为DefaultFullHttpResponse * 2.Netty中客户端、服务端的编解码器 作为服务端而言: 主要工作就是接收客户端请求,将客户端的请求内容解码;发送响应给客户端,并将发送内容编码 所以,服务端需要两个编解码器 * HttpRequestDecoder(将请求内容解码)

在Windows 中配置Oracle ODBC驱动(不需要安装客户端)

用于测试的操作系统:Win7 64X Oracle ODBC驱动版本:11.02.00.04 Oracle ODBC下载地址:https://download.csdn.net/download/qq_24886681/10789627 可以下載最新版的ODBC驅動進行配置(下載Basic Package+ODBC Package , ADMIN文件夾打包的可以自己在網上找找) https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 下載積分被系統定義的太高了,有需要的可以留郵箱給我我發你們郵箱 注意、注意、注意:如果要在MS SQL 中建立Link需要安裝Oracle 客戶端(尚未發現不使用客戶端就能直接在MS SQL調用訪問接口的方法) 安装配置步骤: (1)解压instantclient_12.rar文件到任意位置(我的示例:G:\oracle odbc\instantclient_12\instantclient_12_1) (2)管理员权限打开cmd,cd 到 G:\oracle odbc\instantclient_12\instantclient_12_1 执行odbc_install.exe 如图所示:(提示 Oracle ODBC Driver is installed successfully 安装成功!) 安装成功后ODBC数据源管理器会出现 Oracle 的驱动 (3)配置环境变量,打开系统属性选择环境变量(系统变量添加TNS_ADMIN) 具体值: --注:该变量主要是读取ADMIN文件夹下的tnsnames.ora文件 TNS_ADMIN=G:\oracle odbc\instantclient_12\instantclient_12_1\network\ADMIN (4)修改tnsnames.ora,如下图红色方框标记的改成你自己要远程链接的服务器IP地址 及SID,点击保存 (1)=数据源驱动要连接的数据库IP地址 (2)=数据库的SID (3)=数据源驱动稍后选择的TNS Service Name (5)创建ODBC数据驱动(该驱动安装完应该是从C:\Windows\SysWOW64\odbcad32.exe) 打开数据源驱动-》选择系统DSN-》点击添加-》选择Oracle驱动-》点击完成 (6)配置数据源驱动 配置Data Source Name(稍后在数据库中创建连接服务器要用,命名按照你数据源用途来命名最好) 、 TNS Service Name(tnsnames.ora的节点名) 、User ID(数据库帐号) 配置完相关属性之后 点击“Test Connection”测试连接是否成功 注:当出现 ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务时, 请首先确保tnsnames.ora配置信息是正确的,

快速解决ADF5356不能锁定问题

链接:https://pan.baidu.com/s/1hZw0LlGMyd9LXZtdZ2Shlw 提取码:b8vi 最近使用ADF5356 | 小数N分频锁相环 (PLL)实现信号源,FPGA控话制SPI,始终不能锁定,初始化配置899MHZ没问题,但是更改N,F值不能锁定,按照手册更改各种参数和配置顺序,硬是不能锁定,咨询ADI售后也没解决问题,怀疑是新品问题,一个简单问题折腾了几天,功夫不负有心人,终于最后一个小小的改动,实现了锁定,信号源完成

Linux安装jdk11.0.3

提示:非root用户请在每句语句前加sudo(可能需要输入密码) 从官网上下载jdk 下载好后使用命令解压 tar -zxvf jdk-version_os.tar.gzcd /etc/localmkdir java kidir java/jdk11cd java/jdk11将解压后的jdk11.0.3下的所有文件移动到/etc/local/java/jdk11目录下 mv allPath/jdk11.0.3/* ./编辑属性文件 vim /etc/profile ,然后按insert 文末添加内容 JAVA_HOME=/usr/local/java/jdk11 JRE_HOME=$JAVA_HOME/lib PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME JRE_HOME PATH 编辑好后 按ESC,间接着 :wq,保存退出OK 测试 java javac

微信支付-免充值立减与折扣(下篇)

一 前言 读本文前请确保商户号已开通免充值立减与折扣。否则请看 微信支付-免充值立减与折扣(上篇)。 本文主要讲述如何创建优惠券,统一下单和支付通知怎样支持使用优惠券。 二 准备 2.1 必要前提 你要有微信公众号支付/小程序支付/H5支付的开发经验(本文以公众号支付为例),否则先看我的上一篇文章 移动支付--微信公众号支付开发; 2.2 必读文档 1)支付接口单品优惠功能开发者文档; 三 过程 3.1 创建优惠券 3.1.1 哪里创建 步骤:微信商户平台 - 营销中心 - 代金券/立减与折扣 3.1.2 创建一张 立减与折扣 - 全场立减优惠券 1、 设置优惠券规则。 2、设置优惠券规则。 3、高级设置截图 。 4、确认创建。 5、 创建成功,需要激活后才能使用。 3.1.3 创建一张 立减与折扣 - 创建单品立减优惠券 1、设置优惠券规则 2、设置单品优惠规则。 3、设置优惠券规则。 4、创建优惠券。 5、 创建成功,需要激活后才能使用。 3.2 统一下单接口修改 根据文档 统一下单API(支持单品优惠) ,统一下单接口做了以下修改,附修改代码: //元转分 Double moneyd = Double.parseDouble(money) * 100; Integer moneyi = moneyd.intValue(); String amount = moneyi.toString(); parameters.

python(基础--函数)

函数 普通函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。 函数能提高应用的模块性,和代码的重复利用率。 规则: 以 def 关键词开头,后接函数标识符名称和圆括号 ()。 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。(参数可以没有) 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。 函数名所有都小写 函数内容以冒号起始,并且缩进。 return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。 注意:若定义的函数名在程序前面定义的函数名相同则将程序前面的函数名覆盖 def 函数名(参数列表): 函数体 函数调用 你可以通过另一个函数调用执行,也可以直接从 Python 命令提示符执行。 参数传递 注意:类型属于对象,变量是没有类型的 a=[1,2,3] a=“Runoob” 解析: [1,2,3] 是 List 类型,“Runoob” 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。 固定参数: 形参:定义函数时,括号里的参数,没有具体值 补充:1.形参可以有默认值,调用时,该参数可以不赋值,如果赋值就会覆盖掉默认值 2.如果形参有默认值,那么该形参后面的参数也必须有默认值 实参:调用函数时,括号里的参数,有具体值 位置参数:函数调用时实参的顺序是和形参一一对应的,那么就是位置参数 默认参数:有默认值的参数(默认参数必须放在最后面否则报错SyntaxError: non-default argument follows default argument) 关键字参数:实参赋值时,如果标明参数名字=值,那么该参数就成为了关键字参数,不需要按照顺序赋值 非固定参数: 如果定义参数时,参数个数不固定,可以定义非固定参数,一般写*args 注意:函数参数赋值时,如果非固定参数后还有参数,那么该参数的赋值必须用关键字参数赋值 1.加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。我们也可以不向函数传递未命名的变量,如果在函数调用时没有指定参数,它就是一个空元组。 def printinfo( arg1, *vartuple ): “打印任何传入的参数” print ("

在malloc函数中为什么常用sizeof来设定内存分配的大小?

在malloc函数中为什么常用sizeof来设定内存分配的大小? 例子:为40个整数变量分配内存并赋值,然后系统在收回这些内存。 #include<stdlib.h> #include<stdio.h> void main() { int *p; p = (int *)malloc(40*sizeof(int));//用sizeof(int)计算int类型数据的字节数 if(!p) { printf("内存已用完"); exit(0); } printf("OK"); free(p); } 程序中用了sizeof以保证此程序可以移植到其他系统上去。 注意: (1)malloc(8)表示:开辟一个长度为8个字节的内存空间。 (2)sizeof()功能是返回一个变量或者类型的大小,以字节为单位,对 sizeof() 的处理都是在编译阶段进行。

大数据学习笔记之spark及spark streaming----快速通用计算引擎

导语 spark 已经成为广告、报表以及推荐系统等大数据计算场景中首选系统,因效率高,易用以及通用性越来越得到大家的青睐,我自己最近半年在接触spark以及spark streaming之后,对spark技术的使用有一些自己的经验积累以及心得体会,在此分享给大家。 本文依次从spark生态,原理,基本概念,spark streaming原理及实践,还有spark调优以及环境搭建等方面进行介绍,希望对大家有所帮助。 spark 生态及运行原理 Spark 特点 运行速度快 => Spark拥有DAG执行引擎,支持在内存中对数据进行迭代计算。官方提供的数据表明,如果数据由磁盘读取,速度是Hadoop MapReduce的10倍以上,如果数据从内存中读取,速度可以高达100多倍。 适用场景广泛 => 大数据分析统计,实时数据处理,图计算及机器学习 易用性 => 编写简单,支持80种以上的高级算子,支持多种语言,数据源丰富,可部署在多种集群中 容错性高。Spark引进了弹性分布式数据集RDD (Resilient Distributed Dataset) 的抽象,它是分布在一组节点中的只读对象集合,这些集合是弹性的,如果数据集一部分丢失,则可以根据“血统”(即充许基于数据衍生过程)对它们进行重建。另外在RDD计算时可以通过CheckPoint来实现容错,而CheckPoint有两种方式:CheckPoint Data,和Logging The Updates,用户可以控制采用哪种方式来实现容错。 Spark的适用场景 目前大数据处理场景有以下几个类型: 复杂的批量处理(Batch Data Processing),偏重点在于处理海量数据的能力,至于处理速度可忍受,通常的时间可能是在数十分钟到数小时; 基于历史数据的交互式查询(Interactive Query),通常的时间在数十秒到数十分钟之间 基于实时数据流的数据处理(Streaming Data Processing),通常在数百毫秒到数秒之间 Spark成功案例 目前大数据在互联网公司主要应用在广告、报表、推荐系统等业务上。在广告业务方面需要大数据做应用分析、效果分析、定向优化等,在推荐系统方面则需要大数据优化相关排名、个性化推荐以及热点点击分析等。这些应用场景的普遍特点是计算量大、效率要求高。 腾讯 / yahoo / 淘宝 / 优酷土豆 spark运行架构 spark基础运行架构如下所示: spark结合yarn集群背后的运行流程如下所示: spark 运行流程: Spark架构采用了分布式计算中的Master-Slave模型。Master是对应集群中的含有Master进程的节点,Slave是集群中含有Worker进程的节点。 Master作为整个集群的控制器,负责整个集群的正常运行; Worker相当于计算节点,接收主节点命令与进行状态汇报; Executor负责任务的执行; Client作为用户的客户端负责提交应用; Driver负责控制一个应用的执行。 Spark集群部署后,需要在主节点和从节点分别启动Master进程和Worker进程,对整个集群进行控制。在一个Spark应用的执行过程中,Driver和Worker是两个重要角色。Driver 程序是应用逻辑执行的起点,负责作业的调度,即Task任务的分发,而多个Worker用来管理计算节点和创建Executor并行处理任务。在执行阶段,Driver会将Task和Task所依赖的file和jar序列化后传递给对应的Worker机器,同时Executor对相应数据分区的任务进行处理。 Excecutor /Task 每个程序自有,不同程序互相隔离,task多线程并行 集群对Spark透明,Spark只要能获取相关节点和进程 Driver 与Executor保持通信,协作处理 三种集群模式: 1.Standalone 独立集群

spring cloud stream RabbitMQ 特性介绍

1. 前言 1.1 概述 “Spring Cloud Stream is a framework for building message-driven microservice applications.”这是来自官方文档对spring cloud sream的介绍,大致可以理解为Spring Cloud Stream 是一个构建消息驱动微服务的框架。 本文档是基于spring-cloud-stream(消息代理)对消息中间件rabbitMQ的支持。 2.使用指南 2.1 前期准备 RabbitMQ的搭建,具体参考http://www.rabbitmq.com/install-windows.html 应用程序通过pom.xml引用核心jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rabbit</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> 2.2 Spring Cloud Stream 相关概念 Application Model 从上图我们知道spring cloud stream 通过input channels和output channels跟Binder交互,特定Binder在与对应的外部broker节点交互。 Binder Binder 是 Spring Cloud Stream 的一个抽象概念,是应用与消息中间件之间的粘合剂。目前 Spring Cloud Stream 实现了 Kafka 和 Rabbit MQ 的binder。

图像处理之特征提取-ORP特征匹配

1、算法介绍 ORB(Oriented FAST and Rotated BRIEF)是一种快速特征点提取和描述的算法。ORB算法分为两部分,分别是特征点提取和特征点描述。 特征提取是由FAST(Features from Accelerated Segment Test)算法发展来的 特征点描述是根据BRIEF(Binary Robust IndependentElementary Features)特征描述算法改进的。 ORB特征是将FAST特征点的检测方法与BRIEF特征描述子结合起来,并在它们原来的基础上做了改进与优化。据说,ORB算法的速度是sift的100倍,是surf的10倍。 https://blog.csdn.net/kevin_cc98/article/details/75123316 https://blog.csdn.net/qq_40213457/article/details/80848952 代码: import cv2 from matplotlib import pyplot as plt img1 = cv2.imread('6.jpg', cv2.IMREAD_GRAYSCALE) img2 = cv2.imread('7.jpg', cv2.IMREAD_GRAYSCALE) orb = cv2.ORB_create() kp1, des1 = orb.detectAndCompute(img1, None) kp2, des2 = orb.detectAndCompute(img2, None) bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(des1, des2) matches = sorted(matches, key=lambda x: x.distance) img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:80], img2, flags=2)

c语言实现多项式加减法(两种方法)

多项式的每一项用一个结构体存储 在这里主要介绍两种方法实现加减法 (有什么建议想法 评论哦) 第一种方法是将f2多项式中的每一项分别和f1中的每一项比对 如果f1中有和f2当前一项指数相同的项 将系数相加 如果没有 将这一项插入到f1的最前面 继续判断f2的下一项 void addPolyn(Test *f1,Test *f2) { //f1 f2为两个多项式链表 含头结点 head = f1;p = f1->next; q = f2->next; while (q!=NULL) { p = f1->next; //每次都将指针指向A的第一项 int flag = 0; //B多项式每后移一项都赋flag为0 while (p!=NULL){ if (p->expn==q->expn) { flag = 1; //做为后面是插入还是系数相加的判断条件 s = p; //多项式A里面要是有与当前多项是B中的一个指数相同的话 用s保存下来 } p = p->next; } if (flag == 1) { //如果A中存在与B中当前一项系数相同的项 s->coef = s->coef + q->coef; //将相同系数的项指数相加 } else { //如果不存在 r = (Test *)malloc(length); //将当前项复制到一块新的结构体中 r->coef = q->coef; r->expn = q->expn; r->next = head->next; //将B当前项插入A中 head->next = r; } q = q->next; //进行B的下一项的判断 } ListSort(f1);//输入随机 有序无序都可以 } 第二种方法是先将两个多项式合并 然后排序 将指数相同的项的系数相加至它的前一项 然后跳过该节点 (本来想将无序链表直接实现删除多余项 但是出了点bug 暂时不好解决^-^)

MySQL实战 -- 一条SQL更新语句是如何执行的?

今天主要看一下MySQL 的基础架构,主要参考:前阿里技术专家丁奇的课程,感兴趣可以通过下面方式微信扫码购买: 前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块。相信你还记得,一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。 那么,一条更新语句的执行流程又是怎样的呢? 之前你可能经常听 DBA 同事说,MySQL 可以恢复到半个月内任意一秒的状态,惊叹的同时,你是不是心中也会不免会好奇,这是怎样做到的呢? 我们还是从一个表的一条更新语句说起,下面是这个表的创建语句,这个表有一个主键 ID 和一个整型字段 c: mysql> create table T(ID int primary key, c int); 如果要将 ID=2 这一行的值加 1,SQL 语句就会这么写: mysql> update T set c=c+1 where ID=2; 前面我有跟你介绍过 SQL 语句基本的执行链路,这里我再把那张图拿过来,你也可以先简单看看这个图回顾下。首先,可以确定的说,查询语句的那一套流程,更新语句也是同样会走一遍。 MySQL 的逻辑架构图 你执行语句前要先连接数据库,这是连接器的工作。 前面我们说过,在一个表上有更新的时候,跟这个表有关的查询缓存会失效,所以这条语句就会把表 T 上所有缓存结果都清空。这也就是我们一般不建议使用查询缓存的原因。 接下来,分析器会通过词法和语法解析知道这是一条更新语句。优化器决定要使用 ID 这个索引。然后,执行器负责具体执行,找到这一行,然后更新。 与查询流程不一样的是,更新流程还涉及两个重要的日志模块,它们正是我们今天要讨论的主角:redo log(重做日志)和 binlog(归档日志)。如果接触 MySQL,那这两个词肯定是绕不过的,我后面的内容里也会不断地和你强调。不过话说回来,redo log 和 binlog 在设计上有很多有意思的地方,这些设计思路也可以用到你自己的程序里。 重要的日志模块:redo log 不知道你还记不记得《孔乙己》这篇文章,酒店掌柜有一个粉板,专门用来记录客人的赊账记录。如果赊账的人不多,那么他可以把顾客名和账目写在板上。但如果赊账的人多了,粉板总会有记不下的时候,这个时候掌柜一定还有一个专门记录赊账的账本。 如果有人要赊账或者还账的话,掌柜一般有两种做法: (1)一种做法是直接把账本翻出来,把这次赊的账加上去或者扣除掉; (2)另一种做法是先在粉板上记下这次的账,等打烊以后再把账本翻出来核算。 在生意红火柜台很忙时,掌柜一定会选择后者,因为前者操作实在是太麻烦了。首先,你得找到这个人的赊账总额那条记录。你想想,密密麻麻几十页,掌柜要找到那个名字,可能还得带上老花镜慢慢找,找到之后再拿出算盘计算,最后再将结果写回到账本上。 这整个过程想想都麻烦。相比之下,还是先在粉板上记一下方便。你想想,如果掌柜没有粉板的帮助,每次记账都得翻账本,效率是不是低得让人难以忍受? 同样,在 MySQL 里也有这个问题,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。为了解决这个问题,MySQL 的设计者就用了类似酒店掌柜粉板的思路来提升更新效率。 而粉板和账本配合的整个过程,其实就是 MySQL 里经常说到的 WAL 技术,WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘,也就是先写粉板,等不忙的时候再写账本。

QT中菜单输入快捷键和中文

QT菜单栏快捷键设置: Type Here中输入:例如: 文件(&F) 注意:(&F) 这四个字符都是英文状态下输入的!!! QT高版本中会出现: 菜单栏中一级菜单标题可以输入中文,但是二级菜单标题却无法输入中文的问题? 解决方案:先创建一个 英文标题 的二级菜单 方法一:之后在右下角 属性-值 编辑框中找到QAction下面的text属性,text后面的那个就是你之前输入的英文标题,双击它来写入你想要的中文标题。 方法二:之后在下方Action Editor的文本栏中输入你想要的中文标题。(若没有找到Action Editor,则点击菜单栏上的 控件(W) - 视图(V) - Action Editor)。

e.getMessage()和e.toString() 和e.printStackTrace()对比

一. java中e.getMessage()和e.toString() 以及e.printStackTrace()比较 e.getMessage() 只获取异常信息的字符串(不含异常类型) e.toString() 获取异常类型和异常详细信息 e.printStackTrace() 打印出异常类型和异常详细信息,并且显示异常在后台代码中出现的位置。 案例: public class ExceptionTest { public static void main(String[] args) { try { System.out.println(1/0); } catch (Exception e) { System.out.println("e.getMessage():"+e.getMessage()); System.out.println("————————————————————"); System.out.println("e.toString():"+e.toString()); System.out.println("————————————————————"); e.printStackTrace(); } } } 空值台打印结果: 除以零 ———————————————————— java.lang.ArithmeticException: 除以零 ———————————————————— java.lang.ArithmeticException: 除以零 at com.eric.test.ExceptionTest.main(ExceptionTest.java:7) 二. PrintStackTraceUtil 有些时候,我们在后台catch捕获异常后,希望能将异常具体的报错信息和位置存入数据库中,便于后期跟踪并解决问题,此时我们可以将e.printStackTrace()输出的信息转换成字符串,再将字符串保存到数据库中,以下是将e.printStackTrace()输出信息转换成String字符串的工具类 public class PrintStackTraceUtil { /** * 获取e.printStackTrace() 的具体信息,赋值给String 变量,并返回 * * @param e Exception * * @return e.printStackTrace() 中 的信息 */ public static String getStackTraceInfo(Exception e) { StringWriter sw = null; PrintWriter pw = null; try { sw = new StringWriter(); pw = new PrintWriter(sw); e.

数据库迁移框架Flyway介绍

官方文档 https://flywaydb.org/getstarted/firststeps/api[https://flywaydb.org/getstarted/firststeps/api] 入门示例 Java代码 package foobar; import org.flywaydb.core.Flyway; public class App { public static void main(String[] args) { Flyway flyway = new Flyway(); // 指定数据源 flyway.setDataSource("jdbc:mysql://localhost/test", "root", "root"); // 开始数据迁移 flyway.migrate(); } } 在classpath下添加SQL文件 db/migration/V1__Create_person_table.sql create table PERSON ( ID int not null, NAME varchar(100) not null ); 运行程序,在test数据库会自动创建PERSON表。 后续新增表和字段,只需在db/migration目录下新增SQL文件,格式为V${version}__${name}.sql,version值依次增加,比如V2__name.sql,V3__name.sql。 原理介绍 Flyway的数据库迁移的实现原理是,从classpath或文件系统中找到符合规则的数据库迁移脚本,比如db/migration目录下命名规则为V${version}__${name}.sql的文件,将脚本按照version进行排序,依次执行。执行过的脚本会作为一条记录,存储在schema_version表中。当下次执行迁移时,判断脚本已经执行,则跳过。 MigrationResolver接口负责查找数据库迁移脚本,方法为resolveMigrations(),数据库迁移脚本用ResolvedMigration对象表示。MigrationResolver包含多种实现类,比如SqlMigrationResolver会从classpath下查找sql文件。查询通过Scanner类实现,Location类指定查询路径,sql文件的命名规则需要符合V${version}__${name}.sql,规则中的前缀V、后缀.sql、分隔符__均在FlywayConfiguration接口中定义。另一种实现类JdbcMigrationResolver会从classpath下查找实现JdbcMigration接口的类,类的命名规则需要符合V${version}__${name}。需要扩展自己的实现类,可以继承BaseMigrationResolver。 MetaDataTable接口负责查找已执行的数据库迁移脚本,方法为findAppliedMigrations(),已执行的数据库迁移脚本用AppliedMigration对象表示。MetaDataTable只有一种实现类MetaDataTableImpl,从数据库schema_version表查询所有记录。 ResolvedMigration集合包含了已经执行的AppliedMigration集合,在执行ResolvedMigration前,需要对比AppliedMigration,找到已执行和未执行的ResolvedMigration,对比通过MigrationInfoServiceImpl.refresh()实现。已执行的ResolvedMigration需要校验文件有没有发生变化,有变更则提示错误。未执行的ResolvedMigration依次执行,执行结果记录在schema_version表中。 Flyway的主要方法: public class Flyway { /**数据库迁移*/ public int migrate(); /**校验已执行的迁移操作的变更情况*/ public void validate(); /**清理数据库*/ public void clean(); /**设置数据库的基准版本*/ public void baseline(); /**删除执行错误的迁移记录*/ public void repair(); /**准备执行环境,并执行Command操作,以上方法都调用了execute()来执行操作*/ <T> T execute(Command<T> command); } 接下来我们分析Flyway.

两种方法打印水仙花数

一个三位数,它的个位的立方加上十位的立方再加上百位的立方等于这个数本身的话,此数叫作水仙花数.如:某三位数abc,如果满足a^3+b^3+c^3=abc,则abc是水仙花数。下面我提供两种方法打印水仙花数。 1.下面这个代码是比较好理解的,直接从水仙花的定义,结构a^3+b^3+c^3=abc入手,分别定义个位、十位、百位构造水仙花数。 #include<stdio.h> #include<stdlib.h> #include<math.h> int main() { int i, j, k; int a;//j,j,k分别表示水仙花数的百位,十位,个位;a表示水仙花数 for (i = 0; i <= 9; i++) { for (j = 0; j <= 9; j++) { for (k = 0; k <= 9; k++) { a= k + j * 10 + i * 100; if (a==i*i*i+j*j*j+k*k*k&& a>=100) printf("%d\n", a); } } } system("pause"); return 0; } 2.下面的这个代码是由三位数分别计算他的个位、十位、百位,在来判断他是否为水仙花数,也是比较好理解的 #include <stdio.h> #include <stdlib.h> int Isshuixianhua(int num)//num为需要判断是否为水仙花数的整数 { int x1 = num % 10;//除以10的余数=>个位 int x2 = (num / 10) % 10;//=>十位 int x3 = (num/ 100)%10;//=>百位 if (x1*x1*x1 + x2*x2*x2 + x3*x3*x3 == num) return num; else return 0; } int main() { int X=100; for (X = 100; X < 1000; X++) { if (Isshuixianhua(X) !

SVG中stroke-dasharray及stroke-dashoffset属性

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴! stroke-dasharray属性用来设置描边的点划线的图案范式。就是设置实线和虚线的宽度 比如: stroke-dasharray: 50 20; 效果就是: 50和20分别对应了实线和虚线的长度 stroke-dashoffset则指定了dash模式到路径开始的距离,就是实线虚线绘制的起点距路径开始的距离 比如: stroke-dashoffset: 30; 效果: 由于向左移动30像素,这样左边的实线就跟虚线一样长了。 我们可以设置stroke-dashoffset与stroke-dasharray相同的值实现“画线”的效果: 代码: <style>path{ stroke-dasharray: 1000; stroke-dashoffset: 1000; animation: draw 5s ease 3;}@keyframes draw{ 0%{ stroke-dashoffset: 1000; } 100%{ stroke-dashoffset: 0; }}</style><path d="M153 334C153 334 151 334 151 334C151 339 153 344 156 344C164 344 171 339 171 334C171 322 164 314 156 314C142 314 131 322 131 334C131 350 142 364 156 364C175 364 191 350 191 334C191 311 175 294 156 294C131 294 111 311 111 334C111 361 131 384 156 384C186 384 211 361 211 334C211 300 186 274 156 274"

KNN也能进行人脸识别(Python实现加权欧氏距离KNN算法)

代码地址: https://github.com/youaresherlock/IntelligentInformationProcessing 前沿: 本实践是纯属小白练手入门小项目,希望未来可以手动自己用神经网络来识别人脸。共勉,加油! 话不多说, 我们用加权欧氏距离KNN算法来实现人脸识别(Python实现) 题目内容: 针对标准人脸样本库,选择训练和测试样本,对基本的knn分类算法设计智能算法进行改进,能够对测试样本识别出身份。 题目要求: 1) 选择合适的编码方法; 2) 构造目标函数,设计算法进行求解; 3) 记录目标函数进化曲线,记录分配结果 4) 分析参数设置对算法结果的影响 5) 统计识别正确率 人脸数据库的选择: ORL人脸库 ORL人脸库(Olivetti Research Laboratory人脸数据库),诞生于英国剑桥Olivetti实验室。 开源下载地址: https://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html ORL人脸数据库由该实验室从1992年4月到1994年4月期间拍摄的一系列人脸图像组成,共有40个不同年龄、不同性别和不同种族的对象。每个人10幅图像共计400幅灰度图像组成,图像尺寸是92×112,图像背景为黑色。其中人脸部分表情和细节均有变化,例如笑与不笑、眼睛睁着或闭着,戴或不戴眼镜等,人脸姿态也有变化,其深度旋转和平面旋转可达20度,人脸尺寸也有最多10%的变化。该库是目前使用最广泛的标准人脸数据库,特别是刚从事人脸识别研究的学生和初学者,研究ORL人脸库是个很好的开始。 使用加权KNN算法来分类人脸: 目标函数: 通过结合KNN本身的分类算法以及对前k个距离加权,来达到分类的目的 wk-nnc算法是对经典knn算法的改进,这种方法是对k个近邻的样本按照他们距离待分类样本的远近给一个权值w w(i) = (h(k) - h(i)) / (h(k) - h(1)) w(i)是第i个近邻的权值,其中1<i<k,h(i)是待测样本距离第i个近邻的距离 看代码: 图像特征提取三大法宝:HOG特征,LBP特征,Haar特征,Hog_descriptor这个类不是我写的,本来还想弄特征提取,结果分类结果很差,等待以后系统学习吧。 import os import cv2 import shutil import math import random import numpy as np from PIL import Image import matplotlib.pyplot as plt import matplotlib.image as mpimg class Hog_descriptor(): def __init__(self, img, cell_size=16, bin_size=8): self.

Medusa(美杜莎)和Hydra(九头蛇)快速入门手册:01

今天主要是初步介绍一些Hydra和Medusa的分析和内容,旨在方便快速入门,这是第一部分Medusa,后面附带一些字典,之所以是写一起,我是觉得这两个都是不错的工具,不应该分开的,在这种思想下就汇总成一个标题,便于检索 Medusa快速入门 JoMo-Kun / jmk@foofus.net 目录 0x00Medusa是什么? ·0×01为什么创造Medusa? ·0×02如何使用Medusa? ·0×03哪里可以下载? ·0×04可以联系谁? ·0×05嘿嘿嘿? 0×00 Medusa是什么? Medusa旨在成为一个迅速,大规模并行,模块化,爆破登录。目标支持大部分允许远程登录的服务。以下是Medusa项目一些主要功能: ·基于线程的并行测试。可以同时对多个主机,用户或密码执行强力测试。 ·灵活的用户输入目标信息(主机/用户/密码)可以通过多种方式指定。例如,每个项目可以是单个条目或包含多个条目的文件。此外,组合文件格式允许用户改进其目标列表。 ·模块化设计。每个服务模块作为独立的.mod文件存在。这意味着,核心应用程序不需要进行任何修改,以便扩展支持的强制服务列表。 0×01为什么创造Medusa? 为什么要创造Medusa?这与THC-Hydra不一样吗?以下是此应用程序的一些原因: ·应用稳定。可能我是个跛脚汉,但是九头蛇也经常摔倒。我不再相信Hydra实际上的功能是否和自己声称的那样比起修复Hydra,我决定创建自己新的应用程序,虽然这可能会以新的和令人兴奋的方式崩溃。 ·代码结构。一段时间后,我向Hydra添加了几个功能(并行主机扫描,SMBNT模块)。将并行主机代码复制到Hydra真的是的痛苦。这主要是由于我的编码上的无力,但也可能是由于Hydra不是从底层设计来支持这一点。而Medusa从一开始就设计为支持主机,用户和密码的并行测试。 ·速度。Hydra通过为每个主机和正在测试的服务的实例分派新流程来完成其并行测试。当一次测试许多主机/用户时,会产生大量的开销,因为每个分叉进程的用户/密码列表必须重复。Medusa是基于pthread的,不会不必要地重复信息。 ·教育。我不是一个有经验的C程序员,也不认为自己是多线程编程的专家。写这个应用程序是对我的训练。希望其结果对别人有用。 下面是Medusa和Hydra的详细比较: 区特征Medusa2.2Hydra7.1Ncrack 0.4ALPHA*LicenseGPL-2GPL-3GPL-2核心并行方式Pthreadfork() 服务设计模块化内建 速度 通用包装模块 √ AFP √√ CVS √√ FTPFTP√√√ Explicit显式FTPS(RFC 4217中定义的AUTH TLS模式)√√√ Implicit隐式FTPS(FTP over SSL(990 / tcp)√√√HTTP基本认证√√√ NTLM认证(Windows集成)√√ 摘要认证MD5,MD5-sessMD5 HTTP代理 √ ICQ √ IMAPLOGIN支持√√ AUTH-PLAIN支持√√ AUTH-NTLM支持√√ SSL支持IMAPS,STARTTLSIMAPS,STARTTLS LDAP √ Microsoft SQL端口自检√ MS-SQL√√ MySQL的Pre4.1的认证√√ Pre4.1的散列传递√ 4.1+认证√√ NCP(NetWare) √(ncpfs)√(ncpfs) NNTP √(原AUTHINFO)√(原AUTHINFO) Oracle数据库√(通过Wrapper脚本) Listener监听 SID √ 远程控制软件支持的加密级别没有没有 支持的认证模式本地PCA,ADS,NT,Windows原生PCA PCNFS √ POP3AUTH-USER支持√√√ AUTH-LOGIN支持√√ AUTH-PLAIN支持√√ AUTH-NTLM支持√√ SSL支持POP3S,STARTTLSPOP3SPOP3S,STARTTLSPostgreSQL的 √√ RDP(终端服务器) √√√ 哈希支持√ REXEC √√ RLOGIN.

Android 动态禁止/允许Viewpager左(右)滑动

最近在做一个仿抖音首页效果。大致结构为, MainActivity里Viewpager带3个fragment,中间的fragment又add了4个Tab(首页,关注,消息,我) 1 玩过抖音的孩子应该有点印象。在首页tab的时候,viewpager左右两个fragment还能滑出来,在关注tab,消息tab,我tab中,viewpager左右就滑不出来了——禁止了Viewpager左右滑动。 2 在首页tab中,还有推荐tab和城市tab,推荐tab正常左右滑动viewpager,而城市tab无法滑出右侧tab——禁止Viewpager右滑 说到底就是需要一个可以动态设置当前是否可以左(右)滑的Viewpager,网上看了下,emm…几乎是写viewpager禁止滑动的,好吧…过人还得自己写。 处理手势 禁止和允许,无非就是要不要处理这个touch事件。 允许——正常情况下,onTouchEvent返回的super.onTouchEvent(event); 禁止——return true private float lastX; private static final int LEFT_TO_RIGHT=1;//方向=从左到右 private static final int RIGHT_TO_LEFT=2;//方向=从右到左 //手指是否已经抬起 (如果不加入这个参数判断,在手指抬起的那一刻touch事件return了true,页面会卡在手指离开那时候的偏移位置) private boolean isUp=true; @Override public boolean onTouchEvent(MotionEvent event) { int direction=0; switch (event.getAction()){ case MotionEvent.ACTION_DOWN: isUp=false; //获取起始坐标值 lastX = event.getX(); break; case MotionEvent.ACTION_MOVE: if(event.getX()-lastX<0){//从右到左滑(左滑) direction=RIGHT_TO_LEFT; }else {//从左到右滑(右滑) direction=LEFT_TO_RIGHT; } break; case MotionEvent.ACTION_UP: isUp=true; break; } if(isUp){ //手指抬起后,不再接管viewpager的事件,让它自由地滑动 return super.onTouchEvent(event); }else if(direction==RIGHT_TO_LEFT&&isCanGoRight){ //允许滑动则应该调用父类的方法 return super.

Paperreading之三Simple Baselines for Human Pose Estimation

本次paper是coco2018关键点检测项目的亚军方案,方法非常的简洁明了,但是效果很惊艳,达到了state of the art,paper的标题也是写了simple baseline。整篇paper包含一个sota的姿态估计和姿态跟踪,本篇博客只涉及到paper里面的姿态估计部分。 前言 人体姿态估计是MSCOCO数据集(http://cocodataset.org/)上面的一项比赛,人体关键点检测,目前主流的做法都是深度学习来做。本文的出发点: 作者认为目前的姿态估计方法都太过于复杂,并且有显著的差异,比如hourglass,open pose,cpn等等,比较这些工作的差异性,更多体现在系统层面而不是信息层面。 作者在本文提出了一个既精确(sota水平),又简单(网络结构非常简单,见下文)的姿态估计方法,作为一个baseline,希望能激发一些新的ideas和简化评估方式。 2. 网络结构部分 网络结构一句话就可以表达清楚,就是一个普通的backbone(用resnet50就很好)加一些转置卷积层(作为一个head network)。作者认为这可能是得到heatmaps的最简单方式,并且包含了从深到浅的特征。 先看图: 上图c是不是非常简单,论文的整个网络就是这样。三个网络最大的区别就是在head network(头部网络)是如何得到高分辨率的feature map的,前两个方法都是上采样得到heatmap,但是simple baseline的方法是使用deconv ,deconv相当于同时做了卷积和上采样。 看起来似乎是得到高分辨率的feature maps是很重要的,但是你是怎么获取的并不是那么的关键,不同的方法获取的都会有不错的效果。 看一下forward函数 就一个resnet50去掉全连接层,加3个deconv layers和一个1*1的卷积就完事了。Deconv layers全部都是一样的kernel=4,channels=256,最后加一个1*1的卷积,输出得到关键点的heatmaps,求一个最大响应值就可以得到最后坐标点了。 Loss的设计:就是普通L2 loss,只在最后的输出算loss,并没有中继监督。 3.Ablation experiments 消融实验对比: 作者从heatmaps的尺寸,deconv的卷积核尺寸,backbone结构,输入图像尺寸等4个方面分别作了对比: 结论是:heatmaps尺寸最好是64*48,三层deconv,kernel的size最好是4,backbone是越大越好,图像尺寸越大越好,但是后两者会极大增加计算量和显存。要做好精度和速度的平衡。 4. 源码和结果对比 源码是Pytorch版本(https://github.com/Microsoft/human-pose-estimation.pytorch),微软亚洲研究院官方出品,写的很好很通用,值得一读。 下面是各种效果对比图,训练几乎没有任何trick,网络里面也没有任何其他的骚操作,比如各种ohem,ohkm等等,也没有中继监督,相同条件下(主要是输入尺寸和bakcbone)效果都是领先水平。在backbone是resnet152和输入是384*288的条件下,各项指标都是排名第一,都是单模型对比的。 5.结论 论文给出的simple baseline是真的很simple,效果真的好,但是其实没有很特别的创新地方,只是把deconv用在了姿态估计的网络里面。 就像论文里面的第二章节一个标题Pose Estimation Using A Deconvolution Head Network。整个网络就是一个普通backbone+一个使用deconv的head network。 参考文献 [1]Simple Baselines for Human Pose Estimation and Tracking(https://arxiv.org/abs/1804.06208) [2]https://github.com/Microsoft/human-pose-estimation.pytorch

Visual Studio 2017 修改 文件 编码为 UTF-8

VS 2017隐藏了高级保存功能,导致没办法直接去设置代码编码 UTF-8 那么我们直接把高级保存功能调用出来即可: 单击“工具”|“自定义”命令,弹出“自定义”对话框。 单击“命令”标签,进入“命令”选项卡。 在“菜单栏”下拉列表中,选择“文件”选项。 单击“添加命令”按钮,弹出“添加命令”对话框。 在“类别”列表中,选择“文件”选项;在“命令”列表中,选择“高级保存选项”选项。 单击“确定”按钮,关闭“添加命令”对话框。 选中“控件”列表中的“高级保存选项”选项,单击“上移”或者“下移”按钮,调整该命令的位置。 单击“关闭”按钮,完成“高级保存选项”命令的添加操作

整理:密码输入框点击眼睛可以查看密码

HTML: <div class="form-text-login nob"> <label class="font-two iconfont icon-suo"></label> <input style="border: none" maxlength="16" type="password" name="password" id="lPassword" class="form-text " placeholder="请输入密码"> <i class="r loginI iconfont icon-biyanjing" id="togglePassword"></i> </div> JQ: $("#togglePassword").click(function () { var hClass= $("#togglePassword").hasClass("icon-yanjing"); if(hClass==true){ $("#togglePassword").removeClass("icon-yanjing"); $("#togglePassword").addClass("icon-biyanjing"); $("#lPassword").attr("type", "password"); }else if(hClass==false){ $("#togglePassword").addClass("icon-yanjing"); $("#togglePassword").removeClass("icon-biyanjing"); $("#lPassword").attr("type", "text"); } 效果图:

四种方法计算字符串的长度

在这里我提供四种方法计算字符串的长度: 1.使用递归函数。 2.数数,从第一个字符开始数数,没遇到一个字符,长度加一,直到遇到"\0",停止数数。 3.使用strlen函数,使用此函数时,需包含头文件# include <string.h> 4.使用sizeof,对于字符串,一定要减去1,因为字符数组的末尾有一个"\0",size=sizeof(str)/sizeof(str[0]) 完整代码入下: #include <stdio.h> #include <stdlib.h> #include <string.h> int strlen_1(char str[]) { if (str[0]=='\0') { return 0; } return strlen_1(str + 1) + 1; } int main() { char str[] = "abcde"; //第一种方法,使用递归 int ret ; ret = strlen_1(str); printf("%d\n", ret); //第二种方法,数数 int strlen_2=0; while (str [strlen_2]!= '\0') strlen_2++; printf("%d\n", strlen_2); //第三种方法,调用strlen函数 int strlen_3 =strlen(str); printf("%d\n", strlen_3); //第四种方法,使用sizeof int strlen_4 = sizeof(str) / sizeof(str[0]) - 1; printf("

机器学习学习笔记一:线性回归(一)

线性回归作为监督学习中经典的回归模型之一,是初学者入门非常好的开始。宏观上考虑理解性的概念,我想我们在初中可能就接触过,y=ax,x为自变量,y为因变量,a为系数也是斜率。如果我们知道了a系数,那么给我一个x,我就能得到一个y,由此可以很好地为未知的x值预测相应的y值。这很符合我们正常逻辑,不难理解。那统计学中的线性回归是如何解释的呢? 对于统计模型线性回归,我想从以下六个方面来展开,并分两篇文章进行详细解读: 线性回归模型定义 线性回归的损失函数 线性回归参数估计 线性回归预测 线性回归拟合优度 线性回归假设检验 线性回归诊断 ▌线性回归模型定义 线性回归按变量数量的多少可以分为:一元线性回归(简单线性回归)和多元线性回归。 一元线性回归,也就是有一个自变量,其模型可以表示如下: 公式中参数解释如下: x:自变量 y:因变量 β 0:截距 β 1:变量回归系数 ϵ:误差项的随机变量1 这些参数中,(β 0+β 1x)反映了由于x的变化而引起的y的线性变化;ϵ反映了除了x和y之间的线性关系之外的随机因素对y的影响,是不能由x和y之间的线性关系所解释的变异性。可以这么来理解ϵ:我们对y的预测是不可能达到与真实值完全一样的,这个真实值只有上帝知道,因此必然会产生误差,我们就用ϵ来表示这个无法预测的误差。 同样的,多元线性回归模型的表示如下: 我们通过引入了ϵ可以让模型达到完美状态,也就是理论的回归模型。但是我们要如何定义这个无法预测的误差项呢?为此,伟人们提出了一些假设条件: 在统计学中,高斯-马尔可夫定理陈述的是:在误差零均值,同方差,且互不相关的线性回归模型中,回归系数的最佳无偏线性估计(BLUE)就是最小方差估计。 总结一下,有如下几个主要的假设条件: (1)误差项ϵ是一个期望为0的随机变量,即E(ϵ)=0 (2)对于自变量的所有值,ϵ的方差σ^2 都相同 (3)误差项ϵ是一个服从正态分布的随机变量,且相互独立,即ϵ~N(0,σ^2) ϵ正态性意味着对于给定的自变量,因变量y也是一个服从正态分布的随机变量。根据回归模型的假设,有如下多元回归方程: ▌线性回归的损失函数 从样本数据考虑,如果想让我们预测值尽量准确,那么我们就必须让真实值与预测值的差值最小,即让误差平方和ϵ最小,用公式来表达即: 用平方而没用误差绝对值是因为:平方对于后续求导比较方便。 虽然我们得到了损失函数,但是如果从统计理论的角度出发来推导损失函数,我认为更有说服力,也能更好地理解线性回归模型,以及为什么开始要提出那些假设条件。 根据上面假设条件:ϵ 服从均值为0,方差为σ的正态分布,且独立,因此随机变量ϵ 的概率密度函数(正态分布的概率密度函数)为: 我们把前面的多元线性回归模型简单地变换一下,如下: 然后将得到的ϵ公式带入上面概率密度函数: 有了概率密度函数,我们自然会想到用最大似然估计推导损失函数: 然后我们将似然函数取对数,这样可以将概率密度的乘法转换为加法: 再然后我们对似然函数取最大值,即最大化似然函数: 这样我们就从统计理论的角度得到了我们要找的损失函数,与我们最小化误差平方和得到的结果是一样的,也从侧面证实了前面提出假设的正确性。因此,多元线性回归模型的损失函数为: 公式里的1/2对损失函数没有影响,只是为了能抵消求导后的乘数2。 ▌线性回归参数估计 损失函数只是一种策略,有了策略我们还要用适合的算法进行求解。在线性回归模型中,求解损失函数就是求与自变量相对应的各个回归系数和截距。有了这些参数,我们才能实现模型的预测(输入x,给出y)。 对于误差平方和损失函数的求解方法有很多,典型的如最小二乘法,梯度下降等。下面我们分别用这两种方法来进行求解。 最小二乘法 最小二乘法可以将误差方程转化为有确定解的代数方程组(其方程式数目正好等于未知数的个数),从而可求解出这些未知参数。这个有确定解的代数方程组称为最小二乘法估计的正规方程。 我们将代数方程组用矩阵来代替可以简化推导过程,以及代码实现。 这里会涉及到矩阵求导的用法,详细介绍请看下面wiki的参考链接: https://en.wikipedia.org/wiki/Matrix_calculus#Scalar-by-vector_identities 我们令上面得到的公式等于0,即可得到最终的求解: Python中对于矩阵的各种操作可以通过Numpy库的一些方法来实现,非常方便。但在这个代码实现中需要注意:X矩阵不能为奇异矩阵,否则是无法求解矩阵的逆的。下面是手撸最小二乘法的代码实现部分。 def standRegres(xArr,yArr): """ 函数说明:计算回归系数w Parameters: xArr - x数据集 yArr - y数据集 Returns: ws - 回归系数 "

图像矩(Hu矩)简介

(1)零阶矩 根据矩的定义,二维图像的灰度用f(x,y)表示,零阶矩m00表示为: 表示的是图像灰度的总和。 (2)一阶矩 图像的一阶矩m10和m01表示用来确定图像的灰度中心, 根据中心矩的定义很容易计算出,u10=0,u01=0 可以根据该公式编写matlab程序。 (3)二阶矩 二阶矩有三个,m11 m02 m20,也成为惯性矩。它们可以确定物体的几个特性: 1.二阶中心矩用来确定目标物体的主轴,长轴和短轴分别对应最大和最小的二阶中心矩。可以计算主轴方向角。 2.图像椭圆:由一阶、二阶矩可以确定一个与原图像惯性等价的图像椭圆。所谓图像椭圆是一个与原图像的二阶矩及原图像的灰度总和均相等的均匀椭圆。使得主轴与图像的主轴方向重合,一边分析图像性质。 (4)三阶矩及以上 对于三阶或三阶以上矩,使用图像在轴或轴上的投影比使用图像本身的描述更方便。 三阶矩:投影扭曲,描述了图像投影的扭曲程度。扭曲是一个经典统计量,用来衡量关于均值对称分布的偏差程度。 四阶矩:投影峰度,峰度是一个用来测量分布峰度的经典统计量。可以计算峰度系数。当峰度系数为0时,表示高斯分布;当峰度系数小于0时,表示平坦的少峰分布;当峰度系数大于0时,表示狭窄的多峰分布。 (5)Hu矩 图像的hu矩是一种具有平移、旋转和尺度不变性的图像特征。 普通矩的计算: (对上面的普通矩阵进行总结) f(x,y)的p+q阶原点矩可以表示为: 而数字图像是一个二维的离散信号,对上述公式进行离散化之后: 其中C与R分别表示图像的列与行。 各阶矩的物理意义: 普通矩: 0阶矩(m00):目标区域的质量 1阶矩(m01,m10):目标区域的质心 2阶矩(m02,m11,m20):目标区域的旋转半径 3阶矩(m03,m12,m21,m30):目标区域的方位和斜度,反应目标的扭曲 但是目标区域往往伴随着空间变换(平移,尺度,旋转),所以需要在普通矩的基础上构造出具备不变性的矩组—hu矩。 中心矩:构造平移不变性 由零阶原点矩和一阶原点矩,我们可以求得目标区域的质心坐标: 由求得的质心坐标,我们可以构造出中心矩: 由于我们选择了以目标区域的质心为中心构建中心矩,那么矩的计算时永远是目标区域中的点相对于目标区域的质心,而与目标区域的位置无关,及具备了平移不变性。 归一化中心矩:构造尺度不变性 为抵消尺度变化对中心矩的影响,利用零阶中心矩u00对各阶中心距进行归一化处理,得到归一化中心矩: 由上文可知,零阶矩表示目标区域的质量(面积),那么如果目标区域的尺度发生变化(缩小2倍),显然其零阶中心矩也会相应变小,使得矩具备尺度不变性。 hu矩:构造旋转不变性 利用二阶和三阶规格中心矩可以导出下面7个不变矩组(Φ1 Φ7),它们在图像平移、旋转和比例变化时保持不变。 参考内容:https://blog.csdn.net/tingxie9116/article/details/52582912 https://blog.csdn.net/chaipp0607/article/details/70256892

Solr 7.5配置、数据库连接、Java(学习篇(1)配置)

需求:基础Java环境JDK 1.8(solr7.5支持jdk 1.8及以上) Solr 7.5文件 ikanalyzer-solr6.5分词器文件 Sublime Test编辑器 (本人已把需要用到的所有工具、文件、jar包上传至百度网盘,有需要者可下载使用, 链接:https://pan.baidu.com/s/1G_L-h0PN2GAaPcreKuuhlg 提取码:qnwe ) 1、配置solr 输入cmd, 启动solr服务器,输入solr start –p 8983(solr服务器默认是8983端口,也可以自定义启动端口) 注:控制界面打开之后不要关闭, 在浏览器中输入:http://localhost:8983/solr/#/ 出现如下界面表示启动成功: 新建一个solr服务 输入solr create –c testsolr (testsolr是自己定义的名字) 出现箭头指的信息表示创建成功 刷新页面,在Core Selector中找到自己创建的core服务

PyCharm连接虚拟机oracle数据库

1、修改主机环境变量 我的电脑(此电脑)、高级系统设置、环境变量 进入环境变量,选择变量Path进行编辑 新建两个路径 : D:\海量数据培训\instantclient-basic-windows.x64-18.3.0.0.0dbru\instantclient_18_3 D:\海量数据培训\instantclient-basic-windows.x64-18.3.0.0.0dbru\instantclient_18_3\oci.dll 2、进入PyCharm设置连接(环境变量设置以后需重启PyCharm) import cx_Oracle cx_Oracle.clientversion() user_name = ‘scott’ #oracle中用户名 password = ‘tiger’#对应用户的登录密码 connect_str = ‘192.168.80.10:1521/VDEDU’ # 服务器地址和服务名称(IP,端口和数据库名称) connection = cx_Oracle.connect(user_name, password, connect_str) #SQL语句,可以定制,实现灵活查询 sql = ‘select * from emp’ #选择数据库中表名称 # 使用pandas 的read_sql函数,可以直接将数据存放在dataframe中 import pandas as pd # 导入pandas库 results = pd.read_sql(sql, connection) #引用oracle中的表在PyCharm中重定义命名便于使用 connection.close() # 关闭数据库连接

数据库概论学习笔记——关系数据理论

属性间的联系 1.一对一联系 2.一对多联系 3.多对多联系 数据依赖 是一个关系内部属性与属性之间的一种约束关系 是现实世界属性间相互联系的抽象 是数据内在的性质 是语义的体现 1.函数依赖 2.多值依赖 例:描述一个学生关系,可以有学号、姓名、系名等属性。 一个学号只对应一个学生,一个学生只在一个系中学习 “学号”值确定后,学生的姓名及所在系的值就被唯一确定。 现给出一个关系模式找出其问题: U ={Sno, Sdept, Mname, Cno, Grade} F={Sno→Sdept, Sdept→ Mname, (Sno, Cno)→ Grade} (1)数据冗余 (2)更新异常 (3)插入异常 (4)删除异常 把这个单一的模式分成三个关系模式: S(Sno,Sdept,Sno → Sdept); SC(Sno,Cno,Grade,(Sno,Cno) → Grade); DEPT(Sdept,Mname,Sdept → Mname); 这三个模式都不会发生插入异常、删除异常的问题,数据的冗余也得到了控制。 平凡函数依赖与非平凡函数依赖 X→Y,但Y⊈X则称X→Y是非平凡的函数依赖。 X→Y,但Y⊆X 则称X→Y是平凡的函数依赖。 例:在关系SC(Sno, Cno, Grade)中, 非平凡函数依赖: (Sno, Cno) → Grade 平凡函数依赖: (Sno, Cno) → Sno (Sno, Cno) → Cno 完全函数依赖与部分函数依赖 在关系SC(Sno, Cno, Grade)中,有: 由于:Sno ↛Grade,Cno ↛ Grade, 因此:(Sno, Cno) → Grade (Sno,Cno)→Sdept是部分函数依赖 因为Sno →Sdept成立,且Sno是(Sno,Cno)的真子集

使用C++11实现线程池的两种方法

概述:什么是线程池? 因为程序边运行边创建线程是比较耗时的,所以我们通过池化的思想:在程序开始运行前创建多个线程,这样,程序在运行时,只需要从线程池中拿来用就可以了.大大提高了程序运行效率. 如何实现: 一般线程池都会有以下几个部分构成: 1. 线程池管理器(ThreadPoolManager):用于创建并管理线程池 2. 工作线程(WorkThread): 线程池中线程 3. 任务队列:用于存放没有处理的任务。提供一种缓冲机制。 4. 用于添加任务的接口 总的来讲,就是先创建几个线程,然后这些线程等待任务队列,不为空拿出任务执行即可(任务可以是对象,也可以是某个函数). 第一种实现: #ifndef _THREADPOOL_H #define _THREADPOOL_H #include <vector> #include <queue> #include <thread> #include <iostream> #include <stdexcept> #include <condition_variable> #include <memory> //unique_ptr const int MAX_THREADS = 1000; //最大线程数目 template <typename T> class threadPool { public: /*默认开一个线程*/ threadPool(int number = 1); ~threadPool(); /*往请求队列<task_queue>中添加任务<T *>*/ bool append(T *request); private: /*工作线程需要运行的函数,不断的从任务队列中取出并执行*/ static void *worker(void *arg); void run(); private: std::vector<std::thread> work_threads; /*工作线程*/ std::queue<T *> tasks_queue; /*任务队列*/ std::mutex queue_mutex; std::condition_variable condition; /*必须与unique_lock配合使用*/ bool stop; }; template <typename T> threadPool<T>::threadPool(int number) : stop(false) { if (number <= 0 || number > MAX_THREADS) throw std::exception(); for (int i = 0; i < number; i++) { std::cout << "

利用Python的requests模块实现翻译程序

1:安装requests模块 pip install requests 2:打开百度翻译进行抓包,刚刚操作了一波发现pc版的正面不好刚,有sign不知道是什么玩意,,emmmm,刚了半天不知道,所有切换到手机版,奇迹出现了,,,嘿嘿嘿.... 3:抓取接口 Request URL: https://fanyi.baidu.com/basetrans 4:python的代码 import requests import json url = "https://fanyi.baidu.com/basetrans" headers_s = { "User-Agent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Mobile Safari/537.36" } data_s = { "query": "你好", "from": "zh", "to": "en" } r = requests.post(url, data=data_s, headers=headers_s) # print(r.content.decode()) res = json.loads(r.content.decode()) print(res['trans'][0]['dst']) 解析成json需要导入json模块,最后效果如下:

SpringBoot main方法详解

SpringBoot main方法详解 @SpringBootApplication public class UdeamApplication { public static void main(String[] args) { SpringApplication.run(UdeamApplication.class, args); } } @SpringBootApplication 开启springboot配置注解 ,项目启动入口,用来启动spring容器 , 启动tomcat , 其他包必须与此类在同级目录或者子包下 

SpringBoot 默认生成的pom配置文件详解

SpringBoot 默认生成的pom配置文件详解 创建springboot 默认选择web生成的配置文件 pom文件内容 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.udeam.springboot</groupId> <artifactId>udeam</artifactId> <version>0.0.1</version> <packaging>jar</packaging> <name>udeam</name> <description></description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <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> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 继承springboot父级项目 提供相关的Maven 默认依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> </parent> 使用之后,常用的Jar包依赖 可以省去 version (版本)配置会从父级项目中继承父级maven 依赖的版本 如果不想使用默认的版本依赖,可以指定版本并且会覆盖父级的依赖项 <spring.

Android ConstraintLayout layout_constraintDimensionRatio w h 备忘

注:以下结论由测试推测得到,仅仅是结果表现上合理,并非一定就是ConstraintLayout内部实现机制,不敢误导他人,仅自己记录备忘 ConstraintLayout layout_constraintDimensionRatio 可以设置一个前缀 w或h, 根据官方说法 The ratio can be expressed either as: a float value, representing a ratio between width and heighta ratio in the form "width:height" You can also use ratio if both dimensions are set to MATCH_CONSTRAINT (0dp). In this case the system sets the largest dimensions the satisfies all constraints and maintains the aspect ratio specified. To constrain one specific side based on the dimensions of another, you can pre append W,"

数据结构算法常见面试考题

(1) 红黑树的了解(平衡树,二叉搜索树),使用场景 把数据结构上几种树集中的讨论一下: 1.AVLtree 定义:最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。 节点的平衡因子是它的左子树的高度减去它的右子树的高度(有时相反)。带有平衡因子1、0或 -1的节点被认为是平衡的。带有平衡因子 -2或2的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。 一般我们所看见的都是排序平衡二叉树。 AVLtree使用场景:AVL树适合用于插入删除次数比较少,但查找多的情况。插入删除导致很多的旋转,旋转是非常耗时的。AVL 在linux内核的vm area中使用。 2.二叉搜索树 二叉搜索树也是一种树,适用与一般二叉树的全部操作,但二叉搜索树能够实现数据的快速查找。 二叉搜索树满足的条件: 1.非空左子树的所有键值小于其根节点的键值 2.非空右子树的所有键值大于其根节点的键值 3.左右子树都是二叉搜索树 二叉搜索树的应用场景:如果是没有退化称为链表的二叉树,查找效率就是lgn,效率不错,但是一旦退换称为链表了,要么使用平衡二叉树,或者之后的RB树,因为链表就是线性的查找效率。 3.红黑树的定义 红黑树是一种二叉查找树,但在每个结点上增加了一个存储位表示结点的颜色,可以是RED或者BLACK。通过对任何一条从根到叶子的路径上各个着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的。 当二叉查找树的高度较低时,这些操作执行的比较快,但是当树的高度较高时,这些操作的性能可能不比用链表好。红黑树(red-black tree)是一种平衡的二叉查找树,它能保证在最坏情况下,基本的动态操作集合运行时间为O(lgn)。 红黑树必须要满足的五条性质: 性质一:节点是红色或者是黑色; 在树里面的节点不是红色的就是黑色的,没有其他颜色,要不怎么叫红黑树呢,是吧。 性质二:根节点是黑色; 根节点总是黑色的。它不能为红。 性质三:每个叶节点(NIL或空节点)是黑色; 性质四:每个红色节点的两个子节点都是黑色的(也就是说不存在两个连续的红色节点); 就是连续的两个节点不能是连续的红色,连续的两个节点的意思就是父节点与子节点不能是连续的红色。 性质五:从任一节点到其每个叶节点的所有路径都包含相同数目的黑色节点。从根节点到每一个NIL节点的路径中,都包含了相同数量的黑色节点。 红黑树的应用场景:红黑树是一种不是非常严格的平衡二叉树,没有AVLtree那么严格的平衡要求,所以它的平均查找,增添删除效率都还不错。广泛用在C++的STL中。如map和set都是用红黑树实现的。 4.B树定义 B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个),不属于二叉搜索树的范畴,因为它不止两路,存在多路。 B树满足的条件: (1)树种的每个节点最多拥有m个子节点且m>=2,空树除外(注:m阶代表一个树节点最多有多少个查找路径,m阶=m路,当m=2则是2叉树,m=3则是3叉); (2)除根节点外每个节点的关键字数量大于等于ceil(m/2)-1个小于等于m-1个,非根节点关键字数必须>=2;(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2) (3)所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指针地址都为null对应下图最后一层节点的空格子 (4)如果一个非叶节点有N个子节点,则该节点的关键字数等于N-1; (5)所有节点关键字是按递增次序排列,并遵循左小右大原则; B树的应用场景:构造一个多阶的B类树,然后在尽量多的在结点上存储相关的信息,保证层数尽量的少,以便后面我们可以更快的找到信息,磁盘的I/O操作也少一些,而且B类树是平衡树,每个结点到叶子结点的高度都是相同,这也保证了每个查询是稳定的。 5.B+树 B+树是B树的一个升级版,B+树是B树的变种树,有n棵子树的节点中含有n个关键字,每个关键字不保存数据,只用来索引,数据都保存在叶子节点。是为文件系统而生的。 相对于B树来说B+树更充分的利用了节点的空间,让查询速度更加稳定,其速度完全接近于二分法查找。为什么说B+树查找的效率要比B树更高、更稳定;我们先看看两者的区别 (1)B+跟B树不同,B+树的非叶子节点不保存关键字记录的指针,这样使得B+树每个节点所能保存的关键字大大增加; (2)B+树叶子节点保存了父节点的所有关键字和关键字记录的指针,每个叶子节点的关键字从小到大链接; (3)B+树的根节点关键字数量和其子节点个数相等; (4)B+的非叶子节点只进行数据索引,不会存实际的关键字记录的指针,所有数据地址必须要到叶子节点才能获取到,所以每次数据查询的次数都一样; 特点: 在B树的基础上每个节点存储的关键字数更多,树的层级更少所以查询数据更快,所有指关键字指针都存在叶子节点,所以每次查找的次数都相同所以查询速度更稳定; 应用场景: 用在磁盘文件组织 数据索引和数据库索引。 6.Trie树(字典树) trie,又称前缀树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。 在图示中,键标注在节点中,值标注在节点之下。每一个完整的英文单词对应一个特定的整数。Trie 可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的。 键不需要被显式地保存在节点中。图示中标注出完整的单词,只是为了演示 trie 的原理。 trie树的优点:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。缺点:Trie树是一种比较简单的数据结构.理解起来比较简单,正所谓简单的东西也得付出代价.故Trie树也有它的缺点,Trie树的内存消耗非常大. 其基本性质可以归纳为: 根节点不包含字符,除根节点外每一个节点都只包含一个字符。从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。每个节点的所有子节点包含的字符都不相同。 典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。字典树与字典很相似,当你要查一个单词是不是在字典树中,首先看单词的第一个字母是不是在字典的第一层,如果不在,说明字典树里没有该单词,如果在就在该字母的孩子节点里找是不是有单词的第二个字母,没有说明没有该单词,有的话用同样的方法继续查找.字典树不仅可以用来储存字母,也可以储存数字等其它数据。 (2) 红黑树在STL上的应用 STL中set、multiset、map、multimap底层是红黑树实现的,而unordered_map、unordered_set 底层是哈希表实现的。

MySQL 获取当前时间戳

MySQL 获取当前时间戳 1. 秒级别时间戳 自19700101 00:00:00以来按秒算,SQL如下: mysql> select unix_timestamp(now()); +-----------------------+ | unix_timestamp(now()) | +-----------------------+ | 1541604376 | +-----------------------+ 1 row in set (0.00 sec) 2. 当前时间戳 mysql> select current_timestamp(); +---------------------+ | current_timestamp() | +---------------------+ | 2019-01-04 20:37:19 | +---------------------+ 1 row in set (0.00 sec)

C语言头插法与尾插法创建单链表

C语言头插法与尾插法创建单链表 用带头结点的链表为例 尾插法: 参考之前文章C语言单链表的入门学习,将新建结点加到单链表的表尾。新建一个尾指针tail,使其指向当前链表的表尾(称为先进先出链表或“队列”,即最先建立的结点为链头,最后建立的结点为链尾)。 tail->next = p; tail = p; 头插法: 从一个空表开始,不断读入数据,生成新的结点,将新结点插入到头结点之后,直至读入结束标志为止(称为后进先出链表或“栈”,即最后建立的结点为链头,最先建立的结点为链尾)。 p->next = head->next; head->next = p; 尾插法具体函数实现 node * createHeadList(void) { int n; node * head, *tail, *p; //创建头结点 p = (node *)malloc(sizeof(node)); p->next = NULL; head = p; tail = p; while(scanf("%d",&n) == 1) { p = (node *)malloc(sizeof(node)); p->num = n; p->next =NULL; tail->next = p; tail = p; } return head; } 头插法具体函数实现 node * createHeadList2(void) { int n; node * head, *p; p = (node *)malloc(sizeof(node)); p->next = NULL; head = p; while(scanf("

一文彻底解决python2的乱码问题

1. 前言 在使用python处理字符串和文件时,如果包含有中文,总是会遇到各种问题,虽然每次都通过查询资料解决了,但是并不是很明白,今天决定系统研究一下。在这里把研究的结果分享出来,也希望大家进行指导。 2. 编码与解码 首先,明确一点,计算机中存储的信息都是二进制的。 编码/解码本质上是一种映射(对应关系),比如‘a’用ascii编码则是65,计算机中存储的就是00110101,但是显示的时候不能显示00110101,还是要显示’a’,但计算机怎么知道00110101是’a’呢,这就需要解码,当选择用ascii解码时,当计算机读到00110101时就到对应的ascii表里一查发现是’a’,就显示为’a’ **编码:**真实字符与二进制串的对应关系,真实字符→二进制串 **解码:**二进制串与真实字符的对应关系,二进制串→真实字符 3. 字符集 说起字符的编码与解码,那就不得不提字符集了 如图所示,我们所知的英文编码都是采用ansi编码,随着中国的崛起,国家也开始信息化,但是计算机不认识中国汉字,怎么办呢,我们制定自己统一的字符集,这就是GB2312,后来更新的字符集,GBK,GB18030,BIG5 ,都是在原来的基础之上增加一些新的元素的识别,比如一些生僻字,繁体字认识。 这样一来不是中文一套,英文一套,那后来的一些其它的国家文字不就都不能互相通用了,那干脆一锅端,将这些英文,中文,各国的语言文字大一统,Unicode就出现了,不仅兼容了这些文字,与方便了各国的信息交流. unicode编码系统是为表达任意语言而设计的,为了防止存储上的冗余(比如,对应ascii码的部分),其采用了变长编码,但变长编码给解码带来了困难,无法判断是几个字节表示一个字符。 在Unicode编码方式下,又存在 utf-8,utf-16,utf-32的编码方式。UTF-8是针对unicode变长编码设计的一种前缀码,根据前缀可判断是几个字节表示一个字符。 4. python中的编码与解码 通过上面的一些例子,我们可以大致对于编码和解码有一个大概的印象,那接下来我们看看python2.7.x对于编码是怎么处理的,还是先上一个图 basestring下面有两个对象,unicode,str 那这两者的关系是怎么样的? unicode encode> str #unicode经过encode变成str str decode> unicode #str经过decode变成unicode 在python中,编码解码其实是不同编码系统间的转换,默认情况下,转换目标是Unicode,即编解码的中间对象是unicode对象。 熟悉Java的同学可能知道,Java编解码的中间对象是byte[]数组,即一个字符串如果要从一种编码方式转换成另一种编码方式,需要先按照原来的编码方式(如utf8)解码成byte[]数组,然后再使用新的编码方式(如gbk)编码成新的字符串。在python中没有byte[]类型,unicode的作用相当于Java中byte[],即编码unicode→str,解码str→unicode,其中str指的是字节流,而str.decode是将字节流str按给定的解码方式解码,并转换成utf-8形式,u.encode是将unicode类按给定的编码方式转换成字节流str。我理解的是python使用unicode编码作为中间编码,来完成不同编码的转换,一种编码想要转换成另一种编码,需要先转换到unicode编码,再从unicode编码转换到其他编码。 注意:unicode编码并不等同于utf-8编码。 注意调用encode方法的是unicode对象,生成的是字节流;调用decode方法的是str对象(字节流),生成的是unicode对象。若str对象调用encode会默认先按系统默认编码方式decode成unicode对象再encode,忽视了中间默认的decode的编码方式往往导致报错。 同样的,若unicode对象调用decode会默认先按系统默认编码方式encode成str对象再encode,忽视了中间默认的encode的的编码方式往往导致报错。 5. 文件开头的coding:utf-8 在python2中,在.py的源代码文件中,如果使用还有中文的字符串或者含有中文注释,会报错: 如 两种形式都会报错,报错信息如下: SyntaxError: Non-ASCII character '\xe4' in file E:/PycharmProjects/Demo_local/encode/demo_encode.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details 这是应为python系统默认使用ascii编码来编码.py文件,由于ascii不能编码中文,所以会报语法错误。 在文档的开头添加coding:utf-8,告诉python系统使用utf-8编码来编码源代码文件,这样就不会再报错了。 在python3就不需要这么做,因为python3默认使用utf-8编码.py文件,可以编码中文。 6. sys.defaultencoding(‘utf-8’) 毫无疑问这行代码是设置系统的默认编码方式,与之对应的还有一个sys.getdefaultencoding()可以获得系统的编码方式,这个系统是指python系统,不是指计算机系统。python2系统默认的编码方式是ascii。什么时候应该使用这个函数呢,下面来看一个例子。 可以看到在文件头加上coding:utf-8后不再报上面的,SyntaxError: Non-ASCII character '\xe4' in file .

C语言带头结点的单链表

带头结点的单链表 之前的文章创建的单链表都是不带头结点的单链表。有时,我们为了更加方便地对链表进行操作,会在单链表的第一个结点前附设一个结点,称为头结点。 头指针与头结点的异同 头指针: 头指针是指链表中指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。头指针具有标识作用,所以常用头指针冠以链表的名字。 头结点: 头结点是为了操作的统一和方便而设立的,放在第一元素的结点之前,其数据域一般无意义(也可存放链表的长度)。有了头结点,对在第一元素结点前插入结点和删除第一结点,其操作与其它结点的操作就统一了。头结点不一定是链表的必须要素。 下面根据之前文章创建一个带头结点的单链表 node * createHeadList(void) { int n; node * head, *tail, *p; //创建头结点 p = (node *)malloc(sizeof(node)); p->next = NULL; head = p; tail = p; while(scanf("%d",&n) == 1) { p = (node *)malloc(sizeof(node)); p->num = n; p->next =NULL; tail->next = p; tail = p; } return head; } 该链表的遍历函数则变为 void headDisplay(node *head) { node *p; p = head; while(p->next != NULL) { printf("