目录
1.概念
2.与单链表对比
2.1相比单链表的优势
2.2相比单链表的缺点
3.DLL的插入操作
4.链表头部插入一个节点(5个步骤)
5.指定节点的后面插入新节点(7个步骤)
6.链表的尾部插入新节点(7个步骤)
7.指定节点的前面插入新节点(7个步骤)
8.实现所有插入操作的完整程序
1.概念 双向链表(doubly linked list - DLL)的操作,与单链表很大程度上有相似之处。在开始本篇文章前,可以先回顾下单链表的类似操作。
参考本博客中单链表系列中的这两篇文章:”单链表(1) - 介绍“, ”单链表(3) - 插入节点“。
一个双向链表包含一个额外的指针,称之为前向指针(prev pointer),与单链表中的后向指针(next pointer)一起来标识一个节点。
下面是使用C++代码来表示一个DLL的例子:
//双向链表中的节点元素 struct Node { int data; Node *next; // 指向下一个节点 Node *prev; // 指向前一个节点 }; 2.与单链表对比 与单链表相比,双向链表有下面的这些优点和缺点。
2.1相比单链表的优势 1) DLL支持正向和逆向的遍历方式。
2) DLL中的删除操作更有效,如果提供了要删除节点的指针。
这是因为,在单链表中如果要删除一个节点,则必须要知道前一个节点。有时为了得到这前一个节点,需要遍历整个链表,而在双向链表中,使用前向指针就可以很方便的得到前一个节点。
2.2相比单链表的缺点 1) DLL的每个节点,需要额外空间来保存前向指针。
其实可以使用一个指针来实现双向链表。
具体可以参考本博客的"高级数据结构"系列中的下面这两篇文章:"高级链表 - 异或链表(1)" 以及 "高级链表 - 异或链表(2)"。
2) 所有的操作,都需要维护前向指针。例如,插入操作时,需要同时更改前向和后向指针。
3.DLL的插入操作 可以使用4种方式添加一个节点:
1) 在DLL的头部
2) 在一个指定节点的后面
public static bool WriteToSerialPort(byte[]byteArr) { SerialPort Com = newSerialPort(); try { Com.ReadTimeout = 5000; Com.WriteTimeout = 5000; Com.PortName = "Com1"; Com.BaudRate = 9600; Com.StopBits = StopBits.One; Com.Parity = Parity.None; Com.Open(); Com.Write(byteArr, 0,byteArr.Length); return true; } catch(Exception ex) { return false; } finally { Com.Close(); } } 本例使用的是方法Write(Byte[]buffer, Int32 offset, Int32 count)。该方法使用缓冲区的数据将指定数量的字节写入串行端口。buffer为缓冲区,offset表示从此处开始将字节复制到端口,count表示要写入的字节数。
1.bat重命名文件
ren 111.txt 222.doc
解释:将111.txt 命名为222.doc
2.循环重命名一个文件夹下的所有结尾为xls的文件,前加上A
for /f %%i in ('dir /b *.txt') do (ren %%i A%%i)
3. 在原文件名前面加当前系统日期格式yyyyMMdd
@echo off
for /f "tokens=1,2,3 delims=- " %%a in ('date /t') do set day=%%a%%b%%c
for /f %%i in ('dir /b *.txt') do (ren %%i �y%%%i)
解释:tokens=1,2,3 delims=- 以‘-’为分隔符,将当前日期截取为三部分,分别付给a,b,c,
设置day变量为截取到的三部分的结合,set day=%%a%%b%%c,即day=格式为yyyyMMdd的当天日期
循环修改同一目录下的文件名,*.txt的都会被修改; i为原文件名
4.现有一堆照片,命名格式为0001.jpg,0002.jpg,0003.jpg,…,00020.jpg,……
要求在所有文件名前加上A_
@echo off
rem 启用"延缓环境变量扩充"
setlocal EnableDelayedExpansion
set a=1
rem 循环当前目录下所有图片的文件名,支持带空格的名称
for /f "delims=" %%i in ('dir /b *.
log4j是一个优秀的开源日志记录项目,我们不仅可以对输出的日志的格式自定义,还可以自己定义日志输出的目的地,比如:屏幕,文本文件,数据库,甚至能通过socket输出。本节主要讲述如何将日志信息输入到数据库(可以插入任何数据库,在此主要以MSSQL为例进行详解)。
用log4j将日志写入数据库主要用到是log4j包下的JDBCAppender类,它提供了将日志信息异步写入数据的功能,我们可以直接使用这个类将我们的日志信息写入数据库;也可以扩展JDBCAppender类,就是将JDBCAppender类作为基类。下面将通过一个实例来讲解log4j是如何将日志信息写入数据库的。
我们的需求:我们在软件开发的过程中需要将调试信息、操作信息等记录下来,以便后面的审计,这些日志信息包括用户ID、用户姓名、操作类、路径、方法、操作时间、日志信息。
设计思想:我们采用JDBCAppender类直接将日志信息插入数据库,所有只需要在配置文件配置此类就可以;要获得用户信息需要用过滤器来实现;(假如不需要用户的信息,就不需要设计过滤器,其实大部分情况下都是需要这些用户信息,尤其是在web应用开发中)在日志信息中获得用户信息,就的通过过滤器的request或session对象,从session中拿到用户信息怎样传到log4j呢,log4j为我们提供了MDC(MDC是log4j种非常有用类,它们用于存储应用程序的上下文信息(context infomation),从而便于在log中使用这些上下文信息。MDC内部使用了类似map的机制来存储信息,上下文信息也是每个线程独立地储存,所不同的是信息都是以它们的key值存储在”map”中。相对应的方法,
MDC.put(key, value); MDC.remove(key); MDC.get(key); 在配置PatternLayout的时候使用:%x{key}来输出对应的value)。有了MDC,我们可以在过滤器中先获得用户信息,再用MDC.Put(“key”)方法,log在执行sql语句时通过%x{key}来输出对应的value。
实现步骤:
1、在你的项目中要确保有log4j和commons-logging这两个jar文件;
2、设置要你要插入日志信息的表结构
[javascript] view plain copy if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[WDZLOG]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[WDZLOG] GO CREATE TABLE [dbo].[WDZLOG] ( [WDZLOGID] [int] IDENTITY (1, 1) NOT NULL , [LogName] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,//用户ID [UserName] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,//用户姓名 [Class] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,//类名 [Mothod] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL //,方法名 [CreateTime] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,//产生时间 [LogLevel] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,//日志级别 [MSG] [varchar] (555) COLLATE Chinese_PRC_CI_AS NULL //日志信息 ) ON [PRIMARY] GO 3、配置文件(摘自我们的项目)后面将对此配置文件进行详细讲解,它也log4j的核心部分。
Unknown lifecycle phase “”. You must specify a valid lifecycle phase or a goal in the format : or :[:]:. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-site, site, post-site, site-deploy, pre-clean, clean, post-clean. -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
写在篇头:
在不同的编译器下结果不同,本例测试的环境为 devcpp5.3.0.1 。 ——————————————————————————————————————————————————————————————————————
先看一段代码,猜猜会是什么输出:
[cpp] view plain copy print ? x=1; printf("%d %d\n",x,x++); x=1; printf("%d %d\n",x++,x); x=1; printf("%d %d %d\n",x,x++,x); x=1; printf("%d %d %d %d\n",x,++x,x++,x); 如是~: [html] view plain copy print ? 2 1 1 2 2 1 2 3 3 1 3 看到这里,你会发现,有时看起来是从左往右算,有时候是从右往左算,有时候还是从乱序算。。是不是有些郁闷呢。
其实,在处理printf时,压栈顺序为从右往左,也就是说从右往左的计算(“计算”不等于“输出”)。
在计算时,遇到x++会记录此时的x的值作为最后的输出结果。遇到x和++x的时候则不会将此时的计算结果作为最终的输出,只会修改x的值,在最终输出的时候都输出x的值(所以++x和x的结果总是一样的)。
为什么会是这个样子呢?参见某高手解释吧:
对于a++的结果,是有ebp寻址函数栈空间来记录中间结果的,在最后给printf压栈的时候,再从栈中把中间结果取出来;而对于++a的结果,则直接压寄存器变量,寄存器经过了所有的自增操作。 (来源:http://www.zzzj.com/html/20090609/71613.html)
[小试身手]
[cpp] view plain copy print ? a=1; printf("%d %d %d %d %d %d\n",a++, ++a, a++, ++a, a++, ++a ); 答案:[ 6 7 4 7 2 7 ]
经过多方查找,原来是因为我使用了nginx反响代理的原因。nginx在做反向代理时,默认的可以上传的附件大小是1M,可以通过设置nginx.conf中的client_max_body_size进行更改:
1 client_max_body_size 35m; 在生产环境中仅设置上面的参数时好时坏,不知道啥原因,又增加了下面的设置后没出现过问题,记录一下: 1 client_body_temp_path /home/www/nginx_temp; 转载于:https://www.cnblogs.com/fanelephant/p/4546839.html
Part1: 由于在我们的程序中,不允许一些耗时的任务在主线程中出现,主要是为了防止阻塞主线程而导致的 Anr(Application not Responding),一些耗时任务主要包括:
网络访问,缓慢的磁盘操作,比较耗时的算法
当我们的主线程在一定时间里对某一事件的处理超过一定时间后会主线程会崩溃报ANR,
通常的解决方案:采用子线程技术来将耗时任务与主线程进行脱离
1、handler机制
只需要将UI更新参数在子线程中使用sendMessage发送到定义好的Handler里的handleMessage里既可以在主线程中更新UI(Handler实现了从子线程到主线程之间的跳转)
2、runOnUiThread方法
使用这个方法,既可以使得当前主线程获取cpu资源,从而进行UI的更新(至于如何从子线程中返回数据,方法很多,比如使用接口来回调获取参数)
3、使用我们熟悉的AsyncTask类
AsyncTask使用详解和源码分析
Part2:网络访问 大家都熟知的右HttpClient和HttpUrlConnection两种方式,当然还有像Volley和OkHttp以及AsyncHttpClient
针对前两种最原始基础的方式,是不具备异步处理能力的,也就是需要我们配合part1里的异步处理框架来使用,否则就只能接受ANR这赤裸裸的尴尬
Volley则是具备了异步访问的能力而且访问结束的回调方法是处于主线程中的,这样就可以直接脱离异步访问框架来单独使用了(还能够替代Universal-Image-Loader异步加载图片喔)Volley使用详解
AsyncHttpClient则是对HttpClient的一种异步封装,它对于Volley的一个缺陷就是回调方法依然处于子线程中,我们依然需要使用part1里的异步框架来解决问题
SharedPreferences是一个轻量级的存储类,采用xml文件存放数据。它是通过其Editor接口中的一些方法来操作SharedPreference的。
做登陆页面记住密码首先要先做好页面布局,我采用了两个页面,一个是登陆页面,还有一个是主页面。
这个页面中,主要有两个textview控件来做用户名和密码的输入框,一个Button控件是登陆按钮,一个checkbox控件做记住密码的复选框。
部分代码如下:
<TextView
android:id="@+id/tvUsername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="@string/tvName"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/etUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tvUsername"
android:layout_below="@+id/tvUsername"
android:background="@android:drawable/edit_text"
android:ems="10" />
<TextView
android:id="@+id/tvPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/etUsername"
android:layout_below="@+id/etUsername"
android:text="@string/tvPassword"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tvPassword"
android:layout_below="@+id/tvPassword"
android:layout_marginTop="16dp"
android:background="@android:drawable/edit_text"
android:ems="10"
android:inputType="textPassword" />
<Button
android:id="@+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/etPassword"
android:layout_below="@+id/etPassword"
android:layout_marginTop="20dp"
android:background="#FF72CAE1"
android:onClick="save"
android:text="@string/btnLogin" />
<CheckBox
android:id="@+id/cbSetPass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btnLogin"
android:layout_alignBottom="@+id/btnLogin"
android:layout_alignLeft="@+id/etPassword"
android:text="@string/cb_setPass" />
页面布局做好之后就是在LoginActivity类中写保存用户名和密码的代码。
在保存前要先创建文件:
// 创建文件
sharedPreferences=getSharedPreferences("user", MODE_PRIVATE);
保存用户名和密码的方法:
在使用 Flask 的过程中,页面向后台发起 Ajax 请求,后台处理完成后向页面返回 JSON 数据时,会报出一个 TypeError: 'dict' object is not callable 的错误。该错误是因为直接将 {key:value} 形式的字典数据向页面传输导致的,在这里我们必须将这样的字典数据转换为 JSON字符串,才能正常向页面返回。使用 json.dumps({key:value}) 来进行数据转换。使用 json 前需要 import json。
有以下hql:
String hql = "select new com.ks.admin.report.dto.ReportMonthWithDrawalDto(" + "count(*)," + "sum(ct.tradeTotal)," + "sum(case when ct.tradeTotal >= 0 then 1 else 0 end)," + "sum(case when ct.tradeTotal >= 0 then ct.tradeTotal else 0 end)" + ") " + "from CustTrade ct " + "where ct.tradeType = 'DR' " + "and ct.tradeTime between ? and ? " + "and ct.tradeDesc like '%提现%'"; count(*)返回的是Long类型,Sum(Double类型)返回Double类型, sum(case when ct.tradeTotal >= ? then ct.1 else 0 end) 返回Long类型。 sum(case when ct.
WLCSP即晶圆级芯片封装方式,英文全称是Wafer-Level Chip Scale Packaging Technology,不同于传统的芯片封装方式(先切割再封测,而封装后至少增加原芯片20%的体积),此种最新技术是先在整片晶圆上进行封装和测试,然后才切割成一个个的IC颗粒,因此封装后的体积即等同IC裸晶的原尺寸。它号称是封装技术的未来主流,已投入研发的厂商包括FCT、Aptos、卡西欧、EPIC、富士通、三菱电子等。
它在结束前端晶圆制作流程的晶圆上直接完成所有的操作。在封装过程中再将芯片从晶圆上分离,从而使WLCSP可以实现与芯片尺寸相同的最小的封装体积,这几乎是最终的封装缩微技术。
晶圆级芯片规模封装技术,融合薄膜无源器件技术及大面积规格制造技术能力,不仅提供节省成本的解决办法,而且提供与现存表面贴装组装过程相符合的形状因素。芯片规模封装技术既提供性能改进路线图,又降低了集成无源器件的尺寸。
自1998年可行性的WLCSP技术宣布以来,近年市场上已经出现了各种不同类型的WLCSP。这种技术已经使用在移动电子设备中,比如用于移动电话的电源供给芯片,并且延伸到逻辑产品的应用中。
WLCSP是倒装芯片互连技术的一个变种。借助WLCSP技术,裸片的有源面被倒置,并使用焊球连接到PCB。这些焊球的尺寸通常足够大(在0.5mm间距、预回流焊时有300μm),可省去倒装芯片互连所需的底部填充工艺。如图1所示,
图1:WLCSP封装。
封装结构
WLCSP可以被分成两种结构类型:直接凸块和重分布层(RDL)
直接凸块
直接凸块WLCSP包含一个可选的有机层(聚酰亚胺),这个层用作有源裸片表面上的应力缓冲器。聚酰亚胺覆盖了除连接焊盘四周开窗区域之外的整个裸片面积。在这个开窗区域之上溅射或电镀凸块下金属层(UBM)。UBM是不同金属层的堆叠,包括扩散层、势垒层、润湿层和抗氧化层。焊球落在UBM之上(因此叫落球),然后通过回流焊形成焊料凸块。直接凸块WLCSP的结构如图2所示。
图2:直接凸块WLCSP。
重分布层(RDL)
图3是一种重分布层(RDL)WLCSP。这种技术可以将为邦定线(邦定焊盘安排在四周)而设计的裸片转换成WLCSP。与直接凸块不同的是,这种WLCSP使用两层聚酰亚胺层。第一层聚酰亚胺层沉积在裸片上,并保持邦定焊盘处于开窗状态。RDL层通过溅射或电镀将外围阵列转换为区域阵列。随后的结构类似直接凸块——包括第二个聚酰亚胺层、UBM和落球。
图3:重分布层(RDL)WLCSP
WLCSP的优点:
WLCSP的封装方式,不仅明显地缩小内存模块尺寸,而符合行动装置对于机体空间的高密度需求;另一方面在效能的表现上,更提升了数据传输的速度与稳定性。无需底部填充工艺,可以使用标准的SMT组装设备。
1原芯片尺寸最小封装方式:
WLCSP晶圆级芯片封装方式的最大特点便是有效地缩减封装体积,封装外形更加轻薄。故可搭配于行动装置上而符合可携式产品轻薄短小的特性需求。
2数据传输路径短、稳定性高:
采用WLCSP封装时,由于电路布线的线路短且厚(标示A至B的黄线),故可有效增加数据传输的频寛减少电流耗损,也提升数据传输的稳定性。由于轻质裸片在焊接过程中具有自我校准特性,因此组装良率较高。
3散热特性佳
由于WLCSP少了传统密封的塑料或陶瓷包装,故IC芯片运算时的热能便能有效地发散,而不致增加主机体的温度,而此特点对于行动装置的散热问题助益极大。能减小电感、提高电气性能。
WLCSP不仅是实现高密度、高性能封装和SiP的重要技术,同时也将在器件嵌入PCB技术中起关键作用。尽管引线键合技术非常灵活和成熟,但是WLCSP技术的多层电路、精细线路图形、以及能与引线键合结合的特点,表明它将具有更广泛的应用和新的机遇。
WLCSP的缺点:WLCSP成本来源于晶圆片或封装加工过程。而需要大面积生产的话就需要增加劳动量。就会相应的增加生产的成本。
WLCSP技术的未来
WLCSP在2000年应用在电子手表中之后,已经应用在手机、存储卡、汽车导航仪、数码设备中。未来几年中,在手机这样的高性能移动市场中,会更多采用WLCSP技术的芯片。
将WLCSP技术和芯片嵌入PCB工艺结合,可以确保PCB组装质量的稳定,这是因为WLCSP不仅易于进行PCB板贴装,而且具有“已知优良芯片(KGD,Known Good Die)”的特性。
WLCSP技术为实现生产轻薄和小巧电子设备带来了更多的可能性。WLCSP已经应用在电路板组装上,近来它也成为SiP的重要组成部分,结合WLCSP和常规引线键合技术的MCP也已经进入量产。
看着WLCSP这几年的发展,我们完全可以相信不久之后WLCSP将不断的发展,扩展到更多的领域。
DRAM(Dynamic Random Access Memory),即动态随机存取存储器,是一种 最常见的半导体存储器,主要的作用原理是利用电容内存储电荷的多寡来代表一个二进制比特(bit)是1还是0。据IHS调查显示,2013年世界DRAM的销售值比上年窜升了32.5%,达到350亿美元,2014年还将快速增长19.4%,达418亿美元,2015年稍差,但也能微增2%,达到425亿美元。在广泛的DRAM领域内,所有业者都竭尽全力争取属于自己的市场,希望跟上此一领域对产量需求的快速变化。通过近年的整合,世界DRAM市场趋于稳定,形成 三星、SK Hynix和Micron三足鼎立之势,现世界排名前10的DRAM公司,我国宝岛台湾的企业更是占据半壁江山,下面由OFweek电子工程网小编为大家一一揭晓。
Top1、三星电子
三星电子是韩国最大的电子工业公司,同时也是三星集团旗下最大的子公司。集电子、机械、化工、金融及贸易服务为一体的集团。三星集团是韩国的特大型集团之一,也是世界着名的跨国公司。
三星集团始于贸易公司,进而以电子产品,特别是电子高科技领域的新产品研制开发能力而闻明世界。1994年,三星电子开发出世界第一个256M DRAW(动态存储器是决定计算机存储量的关键部件)。1995年开发出世界第一个22英寸TET-LCD。1996年成功地开发出世界第一个1GB DRAW(动态储存器)。1997年成功地开发出苏第一个30英寸TET-LCD。
根据DRAMeXchange表示,2014年第二季全球DRAM产值达108亿美元,较上季成长9%。由于产品比重调配得宜,三大DRAM厂获利能力皆进一步上升,其中仍以三星表现最佳,营业获利达39%,三星品牌记忆体市占率各为39%,逼近四成全球市场占有率,
在DRAM制程方面,三星25nm良率第二季已经来到85%左右,产出增加与第二季合约价持续上涨,营收季成长20%。由于制程领先成本持续下降,第二季营业利益来到39%,为叁大DRAM厂中最高。值得注意的是,三星Line17工厂正在兴建当中,预计明年第二季初导入量产规模,将会对DRAM价格产生一定程度的影响。
Top2、海力士
Hynix 海力士芯片生产商,源于韩国品牌英文缩写"HY"海力士为塬来的现代内存,2001年更名为海力士。海力士半导体是世界第三大DRAM制造商,也在整个半导体公司中占第九位。
海力士半导体在1983年以现代电子产业有限公司成立,在1996年正式在韩国上市,1999年收购LG半导体,2001年将公司名称改为(株)海力士半导体,从现代集团分离出来。2004年10月将系统IC业务出售给花旗集团,成为专业的存储器制造商。2012年2月,韩国第叁大财阀SK集团宣布收购海力士21.05%的股份从而入主这家内存大厂。
海力士在韩国有4条8英寸晶圆生产线和一条12英寸生产线,在美国俄勒冈州有一条8英寸生产线。2004年及2005年全球DRAM市场占有率处于第二位,中国市场占有率处于第一位. 在世界各地有销售法人和办事处,共有员工15000人.海力士(Hynix)半导体作为无形的基础设施,通过半导体,竭尽全力为客户创造舒适的生活环境。海力士半导体致力生产以DRAM和NAND Flash为主的半导体产品。
海力士半导体以超卓的技术和持续不断的研究投资为基础,每年都在开辟已步入纳米级超微细技术领域的半导体技术的崭新领域。另外,海力士半导体不仅标榜行业最高水平的投资效率,2006年更创下半导体行业世界第七位,步入纯利润2万亿韩元的集团等,正在展现意义非凡的增长势力。海力士半导体不仅作为给国家经济注入新鲜血液的发展动力,完成其使命,同时不断追求与社会共同发展的相生经营。海力士半导体为发展成为令顾客和股东满意的先导企业,将尽心尽责,全力以赴。
在DRAMeXchange进行的2014年第二季全球DRAM产值调查中,SK海力士以营业获利38%紧追叁星,品牌记忆体市占率为27%。在DRAM制程方面,其无锡厂于第一季完全恢复商转,但良率仍有改善的空间,加上刚转进25nm新制程,初期必有产能的耗损,营收仅小幅成长6%,但随着后续25nm投片持续提升,下半年会有较大幅度的营收成长。
Top3、镁光
Micron(美国镁光)半导体是全球第叁大内存芯片厂,是全球着名的半导体存储器方案供应商,是美国500强企业之一。
Micron是其中先进的半导体解答领先世界的提供者之一。Micron微量和闪光组分用于现代最先进的计算,Micron的网络和通信产品,包括计算机、工作站、服务器、手机、无线电设备、数字照相机和GAMING系统。
镁光科技有限公司(Micron Technology, Inc.)是高级半导体解决方案的全球领先供应商之一。Micron通过全球化的运营,镁光公司制造并向市场推出DRAM、NAND闪存、CMOS图像传感器、其它半导体组件以及存储器模块,用于前沿计算、消费品、网络和移动便携产品。美光公司普通股代码为MU,在纽约证券交易所交易(NYSE)。
镁光(Micron)身为世界第二大内存颗粒制造商,产品在国内极少现身。这是因为镁光很少将自己的优质颗粒卖给其他内存品牌,其极品颗粒供自家DIY品牌Crucial使用及品牌机OEM市场,在IBM、HP、Dell等国际知名品牌都可以看到其内存颗粒的产品,可知其稳定性及超频性好。
要问现在的内存超频颗粒哪种最火,答案毫无疑问是镁光的小D9颗粒,优越的超频性能和相对低廉的售价让镁光小D9颗粒的内存成为市场中的抢手货。
目前常见到的小D9颗粒编号一般为D9GCT、D9GMH、D9GKX等,内存厂商Crucial、Corsair、Mushkin、Patriot、OCZ、Geil等多家超频内存提供商均有使用,前段时间创造内存超频世界纪录的也正是这款颗粒。
2014年第二季全球DRAM产值调查中美光集团中则以华亚科营业获利达54.6%最为亮眼,美光集团由于新加坡Tech厂第二季产能全数转进NAND相关产品,投片减少情况下让美光DRAM营收小幅下滑2%,营业利益为25.5%。美光现阶段以30nm制程为主,但25nm制程正积极转进中,预计第四季可以导入20nm制程试产行列,量产时间点落在明年上半年,有机会拉近与韩系厂商的技术门槛。
Top4、南亚
南亚科技股份有限公司成立于1995年3月4日,致力于DRAM(动态随机存取内存)之研发、设计、制造与销售,并在美国、欧洲、日本、大陆设立营销点,其最大股东为台塑集团之南亚塑料股份有限公司。
南亚科技跻身成为世界一流DRAM内存及相关产品制造服务供货商,以两位数的全球市场占有率为目标。
南亚科技除巩固其在标准型内存市场市占率外,更积极经营利基型(非标准型)内存市场,包括服务器用内存、消费型内存及行动式内存(Mobile RAM)叁大核心产品线的研发、生产及销售。在服务器用内存及消费型内存领域已有优异成绩表现,且行动式内存领域正逐渐茁壮。预期这些高附加价值产品在2011年占总营业额比重可提高至叁成以上,可为南科销售量带来逐月成长,且期许2012年能挑战营收过半的策略目标。非标准型内存利润较高且市场稳定,属高附加价值的产品,南科致力强化该内存战线,期能进一步提升台湾DRAM产业在国际的竞争力。
在制程进度上,南亚科技的42纳米制程技术已于2010年第四季开始量产,计划于2011年中全数可转换至42纳米(不包含部份为利基型内存产品线所保留的产能),以2Gb DDR3芯片生产为主,将于下半年导入4Gb DDR3的产品。3X纳米制程技术规划将于今(2011)年第二季导入投片。南亚科技致力拥有自主技术及经营自有品牌,并持续强化高附加价值利基型(非标准型)内存战线,期能进一步提升台湾DRAM产业在国际的竞争力。
为提升技术力与竞争力,南亚科技于2008年4月与美国美光公司(Micron)签订10年共同研发合约,共同致力于先进制程技术,开发更高附加价值产品。南亚科技与美国美光公司(Micron)签订50纳米以下制程技术共同开发合约,自2008年12月起共同分享华亚科技的产出。华亚科技已于2010年第四季完成50纳米技术转换,并达产能满载每月13万片之投片。华亚科技计划于2011年第一季开始42纳米量产,且于2011年年中完成绝大多数的产能转换。此策略联盟,与美光共同研发,同时在台湾培养本土的研发人才,使技术在台生根,以达到永续经营的目标。
Top5、力晶
台湾力晶半导体股份有限公司为提升在国际市场的竞争力及达到量产的经济规模,公司设立之初,力晶即与日本叁菱电机建立技术、生产与销售的策略联盟关系。另一方面,力晶亦为日商瑞萨科技(Renesas Technology Corp.)的主要代工伙伴,发展系统晶片(System LSI)产品。九十五年力晶和尔必达签订共同开发50奈米DRAM制程技术备忘录,掌握关键科技自主能力;同年,力晶也与瑞萨达成协议,取得AG-AND Flash技术授权,成为我国第一家具备高容量快闪记忆体产销实力的半导体厂商。
目前与日本的DRAM大厂Elpida缔结策略联盟,双方携手合作共同研发力晶半导体晶圆厂最尖端DRAM技术。代工方面,力晶亦为叁菱与日立LSI部门合并后的新公司瑞萨科技(Renesas Technology Corp.)的主要代工伙伴,迈向系统晶片(System LSI)产品领域。
力晶现有12吋晶圆厂叁座(P1,P2及P3厂)。是目前台湾12吋厂产能最大的存储器芯片制造公司。
力晶位于新竹科学园区的首座八吋晶圆厂(8A厂)自八十五年开始运转,投入生产DRAM,并于今年分割独立为鉅晶电子(股)公司,专注于利基型DRAM、驱动IC等晶圆代工之业务;目前力晶拥有叁座总月产能达十叁万片的十二吋晶圆厂(P1/P2/P3厂),为全国最大的记忆体制造公司。九十五年十二月,力晶更与尔必达于台湾中部科学园区后里基地合资设立瑞晶电子公司,计画斥资新台币4,500亿元建置全球最大十二吋晶圆DRAM厂区。另外,力晶也于今年动土兴建第四座与第五座十二吋晶圆厂(P4/P5厂)。
Top6、晶豪
晶豪科技股份有限公司 ( Elite Semiconductor Memory Technology Inc., ESMT) 为一专业 IC 设计公司,于 1998 年 6 月由赵瑚博士成立 , 总部设立于台湾之新竹科学工业园区。公司主要业务包含 IC 产品之研究、开发、制造、销售及相关技术服务。根据市调公司IHS的相关统计,晶豪科技2014年第一季度营收5800万美元,暂排世界10大DRAM公司第六位。
介绍 在本文中,我们通过探索线性变换与所得数据协方差之间的关系提供协方差矩阵一个直观的几何解释。大部分教科书基于协方差矩阵的概念解释数据的形状。相反,我们采取一个反向的方法,根据数据的形状来解释协方差矩阵的概念。
在《为什么样本方差除以N-1?》的文章中,我们会讨论方差的概念,并提供了众所周知的估算样本方差公式的推导和证明。这篇文章中使用的图1表明标准差(方差的平方根)提供了数据在特征空间上传播多少的量度。 我们发现,样本方差的无偏估计可由下式获得: 然而,方差只能用于解释平行于特征空间轴方向的数据传播。考虑图2所示的二维特征空间: 对于这个数据,我们可以计算出在x方向上的方差和y方向上的方差。然而,数据的水平传播和垂直传播不能解释明显的对角线关系。图2清楚地显示,平均而言,如果一个数据点的x值增加,则y值也将增加,这产生了正相关。这种相关性可以通过扩展方差概念到所谓的数据“协方差”捕捉到: 对于2D数据,我们得到,这些值可以用矩阵来表示,该矩阵叫做协方差矩阵: 如果x与y是正相关的,那么y和x也是正相关的。换句话说,。因此,协方差矩阵始终是一个对称矩阵,其对角线上是方差,非对角线上是协方差。二维正态分布数据由它的均值和2x2协方差矩阵就可以完全解释。同样,一个3x3协方差矩阵用于捕捉三维数据的传播,一个NxN协方差矩阵捕获N维数据的传播。
图3展示了数据的整体形状如何定义协方差矩阵: 协方差矩阵的特征值分解 在下一节,我们将讨论协方差矩阵如何被解释为白色数据转换成我们观察到数据的线性操作。然而,在深入技术细节之前,对特征向量和特征值如何唯一地确定协方差矩阵(数据形状)有一个直观的认识是非常重要的。
正如我们在图3看到的,协方差矩阵定义了我们数据的传播(方差)和方向(协方差)。因此,如果我们想用一个向量和它的大小来表示协方差矩阵,我们应该简单地尝试找到指向数据最大传播方向上的向量,其大小等于这个方向上的传播(方差)。
如果我们定义这个向量为,那么我们数据D到这个向量上的映射为,映射数据的方差是。由于我们正在寻找指向最大方差方向的向量,所以我们应该选择它的成分,使得映射数据的协方差矩阵尽可能的大。最大化的形式为的任何函数,其中是归一化单位向量,可以用一个所谓的瑞利商表示。通过设置等于矩阵的最大特征特征向量可以获得这样瑞利商的最大值。
换句话说,协方差矩阵的最大特征向量总是指向数据最大方差的方向,并且该向量的幅度等于相应的特征值。第二大特征向量总是正交于最大特征向量,并指向第二大数据的传播方向。
现在,让我们来看看一些例子。在文章《特征值和特征向量》中http://blog.csdn.net/u010182633/article/details/45921929,我们看到一个线性变换矩阵T完全由它的特征向量和特征值定义。应用到协方差矩阵,这意味着: 如果我们数据的协方差矩阵是对角矩阵,使得协方差是零,那么这意味着方差必须等于特征值λ。如图4所示,特征向量用绿色和品红色表示,特征值显然等于协方差矩阵的方差分量。 然而,如果协方差矩阵不是对角的,使得协方差不为零,那么情况稍微更复杂一些。特征值仍代表数据最大传播方向的方差大小,协方差矩阵的方差分量仍然表示x轴和y轴方向上的方差大小。但是,因为数据不是轴对齐的,所以这些值不再与图5所示的相同。 通过比较图5与图4,可以清楚地看到特征值表示沿特征向量方向数据的方差,而协方差矩阵的方差分量表示沿轴的传播。如果没有协方差,则这两个值是相等的。
协方差矩阵作为线性变换 现在,让我们忘了协方差矩阵。图3的实例可以简单地认为是图6的一个线性变换实例: 图6所示的数据是D,则图3所示的每个实例可以通过线性变换D得到:
其中T是变换矩阵,包括一个旋转矩阵R和缩放矩阵S: 这些矩阵定义如下: 其中是旋转角度。
分别是x方向和y方向的比例因子。
在下面的段落中,我们将讨论协方差矩阵与线性变换矩阵T= RS之间的关系。
让我们先从未缩放(缩放相当于1)和未旋转的数据开始。在统计中,这往往为“白数据’,因为它的样本是从标准正态分布引出的,因此对应于白(不相关)噪声: 这个“白色”数据的协方差矩阵等于单位矩阵,使得方差和标准差等于1,协方差等于零: 现在让我们用因子4在x方向缩放数据: 数据D’现在如下: D’的协方差现在是: D’的协方差与线性变换矩阵T有关系,D=TD,其中: 然而,虽然数据在x和y方向上缩放时等式(12)成立,但是应用旋转是否依然成立呢?为了调查一般情况下线性变换矩阵T和协方差矩阵之间的关系,我们试图分解协方差矩阵为旋转和缩放矩阵的乘积。
正如我们前面所看到的,我们可以用特征向量和特征值表示协方差矩阵: 等式(13)保存矩阵Σ的每个特征向量和特征值。在2D情况下,我们得到两个特征值和两个特征值。由公式(13)定义的两个等式可以有效地用矩阵符号来表示: 其中V是矩阵,它的列是Σ的特征向量,L是对角矩阵,其非零元素对应特征值。
这意味着我们可以将协方差矩阵表示为特征向量和特征值的函数: 方程(15)就是所谓协方差矩阵特征值分解,并可以使用奇异值分解算法来获得。而特征向量表示数据最大方差的方向,特征值表示那些方向方差的幅度。换言之,V表示旋转矩阵,而表示一个缩放矩阵。协方差矩阵可以进一步分解为: 在等式(6)中,我们定义了一个线性变换T= RS。由于S是对角缩放矩阵,所以S=ST。此外,由于R为正交矩阵,R-1=RT。因此,协方差矩阵可以写为: 换言之,如果我们应用由T=RS定义的线性变换到图7所示的原始白数据,我们得到了旋转和缩放的数据D’及协方差矩阵。这示于图10: 图10的彩色箭头表示特征向量。最大特征向量,即与最大特征值对应的特征向量,总是指向数据最大方差的方向,并由此确定其方位。次特征向量总是正交于最大特征向量,因为旋转矩阵的正交性。
总结 在本文中,我们表明观察到数据的协方差矩阵与白色不相关数据的线性变换有直接的关系。此线性变换完全由数据的特征向量和特征值确定。而特征向量表示旋转矩阵,特征值对应于每个维度上缩放因子的平方。
公司的项目,通过json传回来的是这么个东西:
NewsId":"94f52614-8764-46d7-a5fe-d0da1fe878ed","NewsTitle":"大型公选课《可持续发展与未来》系列二之现代经济(绿色经济)开始网上选课报名","NewsContent":"<span style="font-size:12pt;font-family:宋体;color:black;line-height:150%;"><span>近日,伴随着我校郑时龄院士、童小华教授分别在四平、嘉定举行的精彩演讲,本学期我校着力打造的大型公共选修课程《可持续发展与未来》之系列一已经圆满结束。该课程也是我校</span>“<span>可持续发展辅修专业</span>”<span>的核心必修课程之一。</span></span> <p style="text-indent:21pt;">
</p>.........
</span> 各种查询之后发现无法解析的根本原因就是里面有双引号" " "和反斜杠" \ ".
还不能直接对json进行转义,否则会将json本身自带的双引号都给转义了,所以不能暴力转义
上网找的方法:
//将坏的json数据里面的双引号,改为中文的双引号(啥都行,只要不是双引号就行)
public String jsonStringConvert(String s){
char[] temp = s.toCharArray(); int n = temp.length;
for(int i =0;i<n;i++){
if(temp[i]==':'&&temp[i+1]=='"'){
for(int j =i+2;j<n;j++){
if(temp[j]=='"'){
if(temp[j+1]!=',' && temp[j+1]!='}'){
temp[j]='”';
}else if(temp[j+1]==',' || temp[j+1]=='}'){
break ;
}
}
} }
} return new String(temp);
}</span> 此方法能将json本身的双引号以外的双引号转义为中文的双引号(其他什么都行)。这样就能够转义为正确的json字符串。
bingo
备忘:
在此方法之前,还要将html代码去空格,否则json也不能够解析,去空格方法:
public String replaceBlank(String str) {
String dest = "";
if (str !
1.HashMap和HashTable有何不同?
(1)HashMap允许key和value为null,而HashTable不允许。
(2)HashTable是同步的,而HashMap不是。所以HashMap适合单线程环境,HashTable适合多线程环境。
(3)在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的。
(4)HashMap提供对key的Set进行遍历,因此它是fail-fast的,但HashTable提供对key的Enumeration进行遍历,它不支持fail-fast。
(5)HashTable被认为是个遗留的类,如果你寻求在迭代的时候修改Map,你应该使用CocurrentHashMap。
2.如何决定选用HashMap还是TreeMap?
对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。
3.ArrayList和Vector有何异同点?
ArrayList和Vector在很多时候都很类似。
(1)两者都是基于索引的,内部由一个数组支持。
(2)两者维护插入的顺序,我们可以根据插入顺序来获取元素。
(3)ArrayList和Vector的迭代器实现都是fail-fast的。
(4)ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。
以下是ArrayList和Vector的不同点。
(1)Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
(2)ArrayList比Vector快,它因为有同步,不会过载。
(3)ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。
4.Array和ArrayList有何区别?什么时候更适合用Array?
Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
Array是指定大小的,而ArrayList大小是固定的。
Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。尽管ArrayList明显是更好的选择,但也有些时候Array比较好用。
(1)如果列表的大小已经指定,大部分情况下是存储和遍历它们。
(2)对于遍历基本数据类型,尽管Collections使用自动装箱来减轻编码任务,在指定大小的基本类型的列表上工作也会变得很慢。
(3)如果你要使用多维数组,使用[][]比List<List<>>更容易。
5.ArrayList和LinkedList有何区别?
ArrayList和LinkedList两者都实现了List接口,但是它们之间有些不同。
(1)ArrayList是由Array所支持的基于一个索引的数据结构,所以它提供对元素的随机访问,复杂度为O(1),但LinkedList存储一系列的节点数据,每个节点都与前一个和下一个节点相连接。所以,尽管有使用索引获取元素的方法,内部实现是从起始点开始遍历,遍历到索引的节点然后返回元素,时间复杂度为O(n),比ArrayList要慢。
(2)与ArrayList相比,在LinkedList中插入、添加和删除一个元素会更快,因为在一个元素被插入到中间的时候,不会涉及改变数组的大小,或更新索引。
(3)LinkedList比ArrayList消耗更多的内存,因为LinkedList中的每个节点存储了前后节点的引用。
6.哪些集合类提供对元素的随机访问?
ArrayList、HashMap、TreeMap和HashTable类提供对元素的随机访问。
27.EnumSet是什么?
java.util.EnumSet是使用枚举类型的集合实现。当集合创建时,枚举集合中的所有元素必须来自单个指定的枚举类型,可以是显示的或隐示的。EnumSet是不同步的,不允许值为null的元素。它也提供了一些有用的方法,比如copyOf(Collection c)、of(E first,E…rest)和complementOf(EnumSet s)。
8.哪些集合类是线程安全的?
Vector、HashTable、Properties和Stack是同步类,所以它们是线程安全的,可以在多线程环境下使用。Java1.5并发API包括一些集合类,允许迭代时修改,因为它们都工作在集合的克隆上,所以它们在多线程环境中是安全的。
9.并发集合类是什么?
Java1.5并发包(java.util.concurrent)包含线程安全集合类,允许在迭代时修改集合。迭代器被设计为fail-fast的,会抛出ConcurrentModificationException。一部分类为:CopyOnWriteArrayList、 ConcurrentHashMap、CopyOnWriteArraySet。
10.BlockingQueue是什么?
Java.util.concurrent.BlockingQueue是一个队列,在进行检索或移除一个元素的时候,它会等待队列变为非空;当在添加一个元素时,它会等待队列中的可用空间。BlockingQueue接口是Java集合框架的一部分,主要用于实现生产者-消费者模式。我们不需要担心等待生产者有可用的空间,或消费者有可用的对象,因为它都在BlockingQueue的实现类中被处理了。Java提供了集中BlockingQueue的实现,比如ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue,、SynchronousQueue等。
<div id="tabs-otherCompany" >
<iframe class="layout-frame" frameborder="0" src="oc_initialization.action"></iframe>
</div>
var div = document.getElementById("tabs-otherCompany");
var iframe = div.getElementsByTagName("iframe")[0];
var win;
win = iframe.contentWindow;
win.fn();
window.frames[i].fn()//fn为frame中定义的方法,i表明页面中第i+1个frame
也可以用window.framename.fn()//不同的是framename是frame的name 属性的值
如:
<iframe name="fun"></iframe> window.fun.fn();
介绍 在这篇文章中,我们将讨论所谓的“维数的诅咒”,并解释为什么在设计分类器时它是很重要的。以下各节我会提供这个概念直观的解释,并用一个由于维数灾难导致的过拟合例子图解说明。
考虑这样一个例子,我们有一组图像,其中每个表示猫或狗。我们想创建一个分类器,它能够自动识别狗和猫。要做到这一点,我们首先需要考虑每个对象类的描述,该描述可以用数字来表示。这样的数学算法,即分类器,可以用这些数字来识别对象。例如,我们可以认为猫和狗有不同的颜色。区分这两个类的一种可能描述可以由三个数字组成:平均红色,平均绿色和平均蓝色。例如,一个简单的线性分类器可以线性地结合这些特征来决定的类标签: 但是,这三个描述颜色的数字(即特征)显然不足以获得完美的分类。因此,我们可以添加描述图像纹理的特征,例如计算X和Y方向上的平均边缘或梯度强度。我们现在有5个特征来区分狗和猫。
为了得到更为准确的分类,我们可以根据颜色或纹理直方图,统计矩等添加更多的特征。我们可以通过仔细定义几百种特征就得到完美的分类吗?这个问题的答案听起来有点违反直觉:不能!实际上,在某点后,通过加入新的特征来增加问题的维数实际上会降低我们分类的性能。通过图1展示,这通常被称为“维数的诅咒’。 在接下来的章节中,我们会评论为什么上面是真实,以及如何避免维数的诅咒。
维数的诅咒和过拟合 在前面介绍的猫狗例子中,假设有无限个猫和狗生活在我们这个星球上。然而,由于我们的时间和处理能力是有限的,我们只能得到10张图片。那么分类的最终目标就是基于这10个训练实例来训练分类器,使得在我们不提供任何信息的前提下,它能正确地区分任何狗和猫。现在让我们使用一个简单的线性分类器,并试图获得一个完美的分类。我们可以用一个特征开始,例如图像中的平均“红”色: 图2表明,如果只有一个特征那么无法获得完美的分类结果。因此,我们可能会决定增加特征,如图像中的平均“绿”色: 最后,我们决定增加第三个特征,例如图像中的平均’蓝’色,得到一个三维特征空间 在三维特征空间中,我们现在可以发现一个平面,它完全分离狗和猫。这意味着这三个特征的线性组合可以获得10个训练图像的完美分类结果: 上面的插图表明通过增加特征的数目直到得到完美的分类结果似乎是训练一个分类器的最佳方式,而在介绍中图1所示的,我们认为这种情况并非如此。但是,注意当我们增加问题维数的时候,训练样本的密度是如何呈指数下降的。
在一维情况下(图2),10个训练实例涵盖了完整的1D特征空间,其宽度为5个单元间隔。因此,在一维情况下,样本密度为10/5=2样本/间隔。在2D情况下(图3),我们仍然有10个训练实例,现在它用5×5= 25个单位正方形面积涵盖了2D的特征空间。因此,在二维情况下,样本密度为10/25= 0.4样本/间隔。最后,在3D的情况下,10个样本覆盖了5×5×5=125个单位立方体特征空间体积。因此,在3D的情况下,样本密度为10/125= 0.08样本/间隔。
如果我们不断增加特征,特征空间的维数也在增长,并变得越来越稀疏。由于这种稀疏性,找到一个可分离的超平面会变得非常容易,因为当特征的数目变得无限大时,训练样本位于最好超平面反面的可能性变得无限小。但是,如果我们将高维的分类结果映射到低维空间,与此方法相关联的严重问题就凸显出来: 图6展示了3D分类结果投影到二维特征空间的情况。在三维空间中数据是线性可分的,但在一个较低维的特征空间中情况并非如此。事实上,加入第三个维度来获得完美的分类结果,仅仅相当于在低维特征空间中使用复杂的非线性分类器。结果,分类器学习具体实例的外观和我们训练数据集的特例。正因为如此,所产生的分类将无法处理真实世界为看到的无数猫狗数据,他们往往不遵守这些特例。
这个概念被称过拟合,是维数诅咒的直接结果。图7示出了只用2个特征而不是3个来训练分类器得到的结果: 虽然图7所示的决策边界线性分类器似乎比图5中非线性分类要糟,但这个分类器对未看见的数据能产生更好的结果,因为它没有学习我们训练数据中的例外。换句话说,通过使用较少的特征,避免了维数诅咒,以至于分类器没有过度拟合训练数据。
图8用不同的方式图解上面的内容。比方说,我们只用一个特征(其取值范围为0到1)来训练分类器。训练这个特征对每个猫和狗是唯一的。如果我们希望我们的训练数据覆盖范围内的20%,则所需的训练数据量是猫,狗的完整量的20%。现在,如果我们添加另一个特征,从而产生二维特征空间,事情发生了变化;为了覆盖二维特征空间的20%,我们需要在每个维度(0.45^2=0.2)上获得猫狗完整量的45%。在3D情况下,这会变得更糟:为了覆盖三维特征范围的20%,在每个维度上(0.58^ 3= 0.2)就需要获得完整量的58%。 换句话说,如果可用训练数据量是固定的,那么如果我们不断增加维数过拟合就会发生。另一方面,如果我们继续增加维数,训练数据量需要成指数增长以保持相同的覆盖范围从而避免过拟合。
在上面的例子中,我们表明维数的诅咒引出了训练数据的稀疏。特征使用的越多,数据就会变得更稀疏,以至于分类器参数(即它的决策边界)的精确估计变得更加困难。另一个维数诅咒的影响是,这个稀疏在搜索空间上不是均匀分布的。事实上,围绕原点(该超立方体的中心)的数据比搜索空间角落的数据更稀疏。理解如下:
试想一下,一个单位正方形表示2D特征空间。特征空间的均值是这个单位正方形的中心,离中心单位长度的所有点是一个内接圆。不属于单位圆内的训练样本更接近搜索空间的角落。这些样品比较难分类,因为它们的特征值有很大不同(例如,单位正方形的互相对立的样本)。因此,如果大部分样本属于图9所示的单位圆内,那么分类是比较容易的: 现在一个有趣的问题是当我们增加特征空间的维数时,圆(超球面)的体积如何变化。维数d上单位超立方体的体积是1^ d=1。维数d上的半径为0.5的内接超球体积可以计算为: 图10显示了当维数增加时,这种超球体积如何变化 这表明,当维数趋于无限时超球面的体积趋于零,而周围超立方体的体积保持恒定。这令人惊讶和相当反直觉的观察部分解释了分类中和维度诅咒相关的问题:在高维空间中,大部分训练数据驻留超立方体(定义特征空间)角落。如前面所述,特征空间角落的实例比超球重心周围的实例更难分类。这示于图11,其中显示了一个二维单位正方形,一个三维单位立方体和8D超立方体(有2^8=256个角落)的可视化: 对于一个8维超立方体,约98%的数据集中在它256个角落。结果是,当特征空间的维数趋向无穷大时,从采样点到质心之间的最小和最大欧几里得距离的差别率趋于零,设置最小距离也都趋于零: 因此,距离测量开始失去其衡量高维空间相异的有效性。由于分类取决于这些距离测量(如欧氏距离,马氏距离,曼哈顿距离),所以分类在低维空间(即较少的特种来描述所关心的对象)更加容易。同样地,高斯似然变得在高维空间变得扁平,使得最小和最大似然之间的差距以及最小似然本身趋向于零。
如何避免维数诅咒? 图1表明,当问题的维数变得比较大时,分类器的性能降低。接下来的问题是“太大“指的是多大,如何避免过拟合。遗憾的是没有固定的规则来确定分类中应该有多少特征。事实上,这取决于可用训练数据的数量,决策边界的复杂性以及所使用分类器的类型。
如果可以获得训练样本的理论无限量,那么维数的诅咒将被终结,我们可以简单地用无限数量的特征来获得完美的分类。训练数据越少,使用的特征越少。如果N个训练样本足够覆盖一维特征空间,那么还需要N^2个样本来覆盖具有相同密度的二维特征空间,三维特征空间需要N^3个样本。换句话说,所需训练实例的数目与所用的维数呈指数增长。
此外,倾向于非常精确的非线性决策边界(例如神经网络,KNN分类器,决策树)的分类器泛化不是很好,很容易发生过拟合。因此,当实用这些分类器时,维数应该保持的比较低。如果一个分类器泛化比较容易(例如朴素贝叶斯,线性分类器),那么所用特征的数量可以更高,因为该分类器本身的表现力不够。图6表明,在高维空间中使用简单的分类器模型对应于低维空间中使用复杂的分类器模型。
因此,过拟合既在高度维空间中估计相对少的参数时发生,也在低维空间中估计很多参数时发生。作为一个例子,考虑一个高斯密度函数,它的均值和协方差矩阵需要参数化。比方说,我们在三维空间进行操作,这样的话协方差矩阵是一个3×3的对称矩阵,它由6个独特的元素组成(3个方差在对角线上,3个协方差)。连同分布的三维平均,这意味着我们需要估计基于训练数据的9个参数,以获得代表我们数据似然的高斯密度。在一维情况下,只有2个参数需要估计(均值和方差),而在二维的情况下需要5个参数(2D均值,两个方差和一个协方差)。我们再次看到,要估计的参数数量增长量是维数的数目平方。
在早期的文章中,我们发现如果要估计的参数数量增加(并且如果估计的偏置和训练数据的数量保持恒定)那么参数估计的方差随之增大。这意味着如果维数增加,我们参数估计的质量会由于方差的增加而下降。分类器方差的增加对应于过拟合。
另一个有趣的问题是应该使用那些特征。给定一组N个特征;我们该如何选择M个最优特征子集使得M
结论 在这篇文章中,我们讨论了特征选择,特征提取和交叉验证的重要性,以避免由于维数诅咒产生过拟合。用一个简单的例子,我们评价了分类器训练中维数诅咒的一个重要影响,即过度拟合。
查看当前系统语言
登陆linux系统打开操作终端之后,输入 echo $LANG可以查看当前使用的系统语言。如
查看安装的语言包
查看是否有中文语言包可以在终端输入 locale命令,如有zh cn 表示已经安装了中文语言
如果没有中文语言呢
可以通过网上下载安装中文语言包yum groupinstall chinese-support(不能联网的通过其他电脑下载,上传上去吧)
如何修改系统语言为中文
1 临时更换语言
如果只是临时更换linux系统的语言环境,可以通过输入设置 LANG=语言名称, 如中文是 Zn_CN.UTF-8(注意我这里本来就是中文的,我临时设置为英文
修改系统默认语言
以上方法是通过修改设置系统默认的语言配置
如Vi /etc/sysconfig/i18n (注意改好之后重启一下系统)
其他注意事项
如果按照以上方法设置修改设置中文语言还是不行的话,注意您的链接终端选择的编码。
如xshell为例,把终端的编码选择中文,或者UTF8即可
7 设置好之后,再次查看之前的乱码文件就能看到显示为中文了
转载于:https://www.cnblogs.com/mooreliu/p/4849917.html
问题描述:
启动内核,运行到Freeing init memory: 120K卡死,具体如下:
......
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
yaffs: auto selecting yaffs2
VFS: Mounted root (yaffs filesystem).
Freeing init memory: 120K
---------------------------------------------------------------------------------------------------
解决方法:
原因是守护进程init没有运行起来,或者运行错误。使用与编译kernel相同的交叉编译器来编译busybox,然后重新制作文件系统,内核完美启动如下:
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
yaffs: auto selecting yaffs2
VFS: Mounted root (yaffs filesystem).
Freeing init memory: 120K
vim中多行注释和多行删除命令,这些命令也是经常用到的一些小技巧,可以大大提高工作效率。 1.多行注释: 1. 首先按esc进入命令行模式下,按下Ctrl + v,进入列(也叫区块)模式; 2. 在行首使用上下键选择需要注释的多行; 3. 按下键盘(大写)“I”键,进入插入模式; 4. 然后输入注释符(“//”、“#”等); 5. 最后按下“Esc”键。 注:在按下esc键后,会稍等一会才会出现注释,不要着急~~时间很短的 2.删除多行注释: 1. 首先按esc进入命令行模式下,按下Ctrl + v, 进入列模式; 2. 选定要取消注释的多行; 3. 按下“x”或者“d”. 注意:如果是“//”注释,那需要执行两次该操作,如果是“#”注释,一次即可 ===================== 3.多行删除 1.首先在命令模式下,输入“:set nu”显示行号; 2.通过行号确定你要删除的行; 3.命令输入“:32,65d”,回车键,32-65行就被删除了,很快捷吧 如果无意中删除错了,可以使用‘u’键恢复(命令模式下) 材料出处: http://www.python tab.com/html/2012/linuxkaiyuan_1222/47.html 转载于:https://www.cnblogs.com/babysay123/p/4511425.html
问题:新浪云上传zip文件时报错(该文件不是utf-8编码)?
原因分析:我们自己的系统windows中文操作系统一般为gb312编码格式,新浪云的linux操作系统一般为utf-8编码,这样就会造成中文乱码。
解决方案:将文件在windows下解压之后用ssh工具上传到linux环境,用linux操作系统命令convmv进行转码。 1. 如果提示找不到命令convmv请先安装convmv http://www.j3e.de/linux/convmv/convmv-1.14.tar.gz 2. 命令格式
convmv -f GB2312 -t UTF-8 -r --notest 文件夹名 打包命令格式: cd 文件夹路径 zip –r 包名.zip .(注意不要落了最后的’.’,它表示当前目录的所以文件)
今天在做用json异步提交按关键字查询数据的时候总是出现 No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered异常,一开始总是以为是List集合转换成json数据的时候转换不成功,经过百度查询资料已经结合hibernate的文档,终于解决了问题。
异常
java.lang.IllegalArgumentException: com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.ArrayList[0]->org.iep.model.hibernate.Menu["parent_menu"]->org.iep.model.hibernate.Menu_$$_jvst62a_2["handler"]) 原来的Menu.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2015-5-10 22:16:21 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="org.iep.model.hibernate.Menu" table="t_base_menu"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="assigned" /> </id> <property name="
select 字段1,字段2,字段3 into tempname form table where table.id=1;
oralce : insert into MID_DRUG_DETAIL( 字段1,字段2,字段3 )select a,b,c from table ; --把table表中的a,b,c对应插入到MID_DRUG_DETAIL表中
这个会给tempname 表中自动生成 字段1,字段2,字段3 三个字段以及值。
oracle 备份表 create table日期 as select * from table需要备份的表;会自动创建备份表表 如果只要表结构只需要加where 1=2
--创建新表
create table ss
as
select * from emp;
--插入表数据
insert into ss select * from ss;
sqlserve 备份表 select * into table备份 from table需要备份的表;会自动创建备份表表 如果只要表结构只需要加where 1=2
修改表字段值,根据nid
update tablename set 字段1=tb.ssm from ( select 字段 as ssm from table2 ) tb
问题 在Java中,一般使用JUnit作为单元测试框架,测试的对象一般是Service和DAO,也可能是RemoteService和Controller。所有这些测试对象基本都是Spring托管的,不会直接new出来。而每个TestCase类却是由JUnit创建的。如何在每个TestCase实例中注入这些依赖呢?
预期效果 我们希望能够达到这样的效果:
package me.arganzheng.study; import static org.junit.Assert.*; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; /** * @author arganzheng */ public class FooServiceTest{ @Autowired private FooService fooService; @Test public void testSaveFoo() { Foo foo = new Foo(); // ... long id = fooService.saveFoo(foo); assertTrue(id > 0); } } 解决思路 其实在我前面的文章:Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象,已经详细的讨论过这个问题了。Quartz是一个框架,Junit同样是个框架,Spring对于接入外部框架,采用了非常一致的做法。对于依赖注入,不外乎就是这个步骤:
首先,找到外部框架创建实例的地方(类或者接口),比如Quartz的jobFactory,默认为org.quartz.simpl.SimpleJobFactory,也可以配置为org.quartz.simpl.PropertySettingJobFactory。这两个类都是实现了org.quartz.spi.JobFactory接口。对于JUnit4.5+,则是org.junit.runners.BlockJUnit4ClassRunner类中的createTest方法。
/** * Returns a new fixture for running a test. Default implementation executes * the test class's no-argument constructor (validation should have ensured * one exists).
由于项目需要,最近在研究protobuf消息协议,关于protobuf协议,基础使用教程这里我就不想多说;度娘,谷哥都能找到大把,就不做太多解释。而关于protobuf动态自动反射消息的使用,这里可以参考陈硕的实现:http://blog.csdn.net/solstice/article/details/6300108
这里主要介绍一种在项目上使用的protobuf自己定义描述消息,FileDescriptorSet的使用,搜了好多文章大家只是一笔带过,至于怎么使用并没有给出详细说明。
项目场景:
由于开发时在通信接口协议层面中的.proto文件,可能会在后续扩展时更改,而按常规的使用方法,proto文件一旦更改后,整个程序又需要重新编译。那有没一种方法能在将proto文件像配置文件一样使用,与整个程序剥离开来。当接口层更新直接更新配置文件而应用程序不用再次编译更新? 答案当然是有的,就是使用protobuf的FileDescriptorSet来实现。
实现
首先,定义一个自己定义描述消息的config.proto文件,也就是动态自定义的关键,实例实现如下:
message SelfDescribingMessage { // Set of .proto files which define the type. required FileDescriptorSet proto_files = 1; // Name of the message type. Must be defined by one of the files in // proto_files. required string type_name = 2; // The message data. required bytes message_data = 3; } required FileDescriptorSet proto_files = 1; 这个是一定不能少的,也是实现的关键,至于SelfDescribingMessage里面其它的数据成员,可以根据自己的需求来加。
第二,实现自己通信协议接口的messages.proto文件,这个文件就是所有可扩展通信数据消息体,这里简单的写几个示例:
message ApplySettings { optional string language = 1; optional string label = 2; optional bool use_passphrase = 3; optional bytes homescreen = 4; } message Success { optional string message = 1; } message Failure { optional FailureType code = 1; optional string message = 2; } message XXX { XXXX //这里是以后可能扩展的消息 } 第三,用户protoc工具,将通信协议接口messages.
分几个方面分别的论述一下人脸识别的技术和产业发展的相关状况。 第一,人脸识别技术的价值在哪里。我们把人脸作为一个生物学特征,作为一个商业化运用,只是备选的一个方案之一。生物学当中,唯一的判断的标准,其实识别从精准度的角度和不可替代的角度来讲,最精准的是虹膜,但是虹膜的识别采集成本非常高,识别的效率相对不是很高,需要等待的时间。所以这两个条件约束了整个的产业化运用只能局限在相对小众的,对识别要求极高的军工、国防等安全性非常高的远的投入,不适合大范围的推广。 第二,指纹。我们知道指纹的唯一性比较强,指纹同时采集成本是比较低的,比对成本也不高。但是为什么指纹没有成为一个特别大的可供支付、刷脸可替代的方案呢?实际上主要的原因是因为指纹的可复制性,是一个静态图像之间的比对,现在我们可以看到淘宝也好,各种各样的大量的指纹贴,指纹膜,可复制的特征,不适合支付。所以指纹现在也大致上被pass了。 第 三和第四分别是人脸识别和声音识别技术。这两个在现在横向来相比,采集成本和比对的效率,以及生命特征的唯一性来讲,性价比比较高。所以现阶段来看,人脸识别浮出水面,是有它的道理的,这是它的价值。商业特征的应用场景到底在哪里。 人脸识别的应用场景是非常宽泛的,现在主要两块, 一个是金融行业,一个是安保行业 。金融行业,已经从马云的蚂蚁金服演示中看到了场景,通过 刷脸进行支付 ,显然刷脸可以付钱了,为什么不可以签收快递呢,下一步淘宝应该会把淘宝签收快递的功能打通。我相信有一天,我们会收到无人机送来的快递,无人机在你的面前拍一张照片,进行对比,就知道这个用户就是需要的用户,完成整个的支付过程。实际上这种场景,是经过多方面的讨论和认证的。基于这样的场景,是跟第三方的支付认证相关的,包括我们看到的腾讯的银行,第一张远程开卡,就是通过人脸识别的技术,把人证合一进行认证,这样远程开户,远程开卡的功能,在我们的券商,在我们的网络银行上面,应该有广泛的应用。 对于安保行业来说,刷脸开门,现阶段,人脸识别的应用应该说达到了一个可具备商业化的水平,我们举个例子,在去年的时候,香港有一个导演叫许鞍华,他在南京地铁中丢了一个他的皮包,这个案件的破获,只花了5个小时。视频监控里面获取了一张照片截图,截到了嫌疑人的照片,是极其模糊的,侧脸的照片,如果肉眼比对,发现不了什么。但是有一家非上市公司,在这里不能提供他的公司名称,他们通过一个图像还原技术,把那个照片还原出可能嫌疑人的样子,清晰照,用这个照片到图库当中比对,锁定嫌疑人的身份,把嫌疑人抓获,只需要了5个小时的时间。现在安防领域的监控,我们可以看到各个省市以及地级市,都在上大量的视频监控,人脸识别的大平台。在整个安防的投入当中,上一代的安防只是静态的记录下来数据,但是下一代的安防,是对实时数据的采集、辨认,就是一个核心的技术,这个技术,人脸识别在其中发挥的作用是很大的。 我 们再拓展一下,未来的商业用途,到底有没有第二代人脸识别技术的潜在的应用的场景呢。我们说在未来,应该说原来整个确定身份的身份证,但是证和人的比对需要人工来完成。如果我们直接界定,达到了这样的一个标准,实际上每个人所对应的唯一的ID就是脸部的生物特征。这个识别了以后,所有的地方都可以用刷脸的方式,所有的地方都可以用刷脸去开门,用刷脸去做各种各样的事情。你刷脸的数据,包括你去坐火车、坐飞机、去哪儿吃饭、购物、收快递等等,这些数据都会掌握到人脸识别中,刷脸的数据将取代现在线上的点击量. 现在信用卡、银行卡消费的数据,其实有助于知道用户消费习惯和消费数据,做大数据的营销和征信,但是刷脸时代来临之后,这个的价值更大了。有很多张卡,但是只有一张脸,这是唯一的。刷脸数据是2.0时代当中,我们重点看到的。 为什么在这个时间段,人脸识别的技术会大范围的爆发出来,大范围的应用起来,成熟度到底怎么样呢?我们首先要界定一下人脸识别技术要达到产品化的应用,是两阶段的过程。 第一阶段,需要获取大量的样本数据,这些数据是用于训练的,训练的是学习算法,这个是深度学习算法,把这些数据和相互人之间的关系提取出来,进行一个特别的比对。耦合度高,超过一定的水平之后,我们会认定这两个人是一个人,但是这个模型是需要投入大量的成本,这个成本包括优化的成本,包括数据训练的成本,包括运算的成本 ,我们当时人脸识别的一个业内的公司,这家公司的创始人,曾经说,人脸识别的技术意味着什么呢?太上老君的炼丹炉,有了这个炉之后,大数据是炉子炼的原料,解决计算能力资源的稀缺。因此这些合在一起,形成了现在人脸识别大爆发的时代,就是我们说的技术上的突破。 但是在产业上面的应用来看,目前我们可以看到,美国和以色列的人脸识别,特别是动态识别的水平是国际领先的。全网的实时监控当中,FBI在去年推出了他们的下一代的电子识别系统,总的投入是超过10亿美金的。在美国将来无论是在什么地方犯了事,监控锁定犯罪嫌疑人,进行全网追捕。 国内是什么水平呢?顶尖的学术水平,就代表着国内产业发展的阶段。目前主要是三种力量,一个是 清华大学的苏光大教授 ,他是中国的人脸识别之父。第二个是 中科院的自动化所的李教授 ,他早年在微软的亚洲研究院当中获得了非常高的成就,后来到了中科院的自动化所,专攻人脸识别。在奥运会当中,以及后来很多的人脸识别的应用当中,提供了比较好的技术。 第三支就是 香港中文大学的汤晓鸥教授 的团队,每年会进行学术界的比赛,他是高记录的保持者。目前的识别率是超过了人类的脸部识别的总体水平,汤教授帮助讯飞在语音识别领域之后,在人脸识别的领域当中,建立了自己的行业地位。所以国内基本上目前是这样的发展阶段,我们去推导下面的阶段,我们怎么去甄别人脸识别的技术,到底哪一家靠谱,哪一家不靠谱,我们可以提出一些关键的甄别的关键点。这些点在哪里呢? 第一,我们要区分的,动态和静态配合式的识别还是非配合式的识别。配合式的就是像蚂蚁金服那样的,需要数据的比对方进行配合,可以很好的去采集正脸的二维的数据。另外,就是非配合式的,非配合式的没有办法对排除方的配合,是需要随机采集的图片进行比对,这个识别的效果会差一些,但是识别的时效性会很高。 这两种模式当中,我们关注三点。
第一点,你的人脸建模当中到底提取了多少个特征点进行比对,这个跟我们人脸上面的一些特征是关键节点,每个人的差异很大,而你选取的特征点的数据越多,比对的准确率就会越高。我们也采访了一些专家,他们目前能够做到的特征点的比对,应该是在700个点以上。目前大部分做刷脸的门禁这样系统产品的公司,特征点的选取大概是在50个左右。所以我们去做调研和交流,可以问一下整个公司人脸识别建模当中特征点的数量。
第二点,人脸识别数据库的数据样本和大小,这是一个非常重要的指标。样本及大小,是我们可供的数据集,这些必须要对人脸,比如说一个人有500张照片,拍的都是他的脸,不同的角度和位置、光线,把这些数据进行合理的清洗,供机器去训练包括比对和识别之后,可以告诉你是识别对了还是识别错了,这样的样本数非常重要,有助于训练,提高模型的准确率。因此可标签的数据样本集的大小,这个大小目前至少是百万以上的级别,才会使得现在识别率能够提升到世界领先的水平,这个也是可以甄别的关键点之一。 第三点,是不是你的商业模式能够对你的整个的数据的获取,我们说人脸数据的比对,形成一个 正循环的模式 。实际上数据来源,人脸的样本来源,是来源于两个非常重要的渠道,美图秀秀和美颜照相机,这是一个商业的互换,这个数据,因为考虑到做一个脱敏的处理,剩下的只有几百个关键的特征点的数据,其他的都被略去,用脱敏的技术之后,形成了从获取数据到训练模型,再到优化模型,持续的反馈结果,获取新的数据,这样的一个正循环的过程。有了这个以后,你的模型的数据就会获取的很好了,这是商业模式上非常重要的一个指标。 如果有了这三个指标之后,应当说同时具备了这三个,可能是在人脸识别领域当中有非常大的领先优势,或者是未来发展潜力的东西。同时我们在直观的性能方面去分析,直观的到底识别的表现上有两个非常重要的指标,一个是识别的准确率,我们界定了刚才说的学术界当中,每年一比的人脸识别大赛,现在基本上测试水平都在95%以上,但是是人和图片之间相互比对,说明是这个人,这算一个,再比对一个,又对了,算第二个。所有的人和照片都是匹配好的,最后正确率在99.2%左右,这是我们说的目前的正常的比对方法。 还有一个非常重要的方法,我们看到商业银行和淘宝在内的一些人脸识别的技术,会提出一个 错误率 的问题,这个数据,目前来看可以做到十万分之一的错误率,别人拿着我的身份证去比对,如果机器能够区分出来,是不通过,这是对的。如果机器把我的身份证给别人的时候也通过了,这可能就是一个错误的,错误率要在十万分之一左右才可以,目前能达到这样错误率的公司是屈指可数的,这是一个识别准确率的问题. 另外还是在多大样本中可以实现这样的准确率,这个是至关重要的。一个公司里面也就是两三百个人,在这些人当中,挑选出来通过,没有什么难度。但是在公安部的大平台当中,省级的平台当中,都是上亿人的身份证照片中,要准确的挑出来十个或者是一百个候选人,这个范围缩小到这个概率当中,你的准确率能有多大,这是一个很重要的指标。 第二点, 识别的速度问题 。同样还是刚才我们说到的样本集的大小决定了识别的速度。本身你在可供比对的样本中,没有很大的数据,比如说是成千上万的,识别的数大家都是差不多,都是在1秒之内作出反映,但是如果在一个上亿的大的样本当中,去把照片准确的识别出来,这样对时间的要求,对效率反映的要求就提高了。所以识别速度是一个很重要的指标。 以上我们说了五个指标,我们说这个确实是可以对公司的具体能力和技术进行综合判断的。 基于以上我们说的这些,关注的公司是有识别技术的公司,这个识别技术是人脸识别的技术。我们前面讲了,本身国内发言的几支学术界的力量大家非常清楚,来源于哪一支,背靠着哪一支强大的学术团队,研究团队的力量,使得这家公司是一个很好的位置。比如说我们前面讲到的科大讯飞,在汤晓鸥教授的支持下,他们的团队是学术界第一的力量在支持他们,这是一个资源性的优势。比如说川大智胜,这个和李教授他们有密切的合作,同时他们自己在图象识别领域当中,也有自己独特的技术,承担着国家大量的科研基金的项目,同时我们也特别强调一个就是川大智胜的人脸识别技术,是目前我们看到的 人机交互 ,因为这个和二维的平面识别有很大的区别,优势非常明显,因为采集到了五官之间立体曲面之间的结合,所以采集到的数据量更丰富。可供比对的特征也是更多的,我们之前在视频当中找到拍到的侧脸,不清晰的照片,很难去识别出来犯罪嫌疑人到底是谁,是因为我们二代身份证库当中,本身就是只有正脸的可供比对的数据。三代或者是四代身份证采集数据的过程当中生物特征肯定要被提取出来,首先是指纹,三维的人脸识别会更快,三代四代可能就会被提取。 一旦需要被提取到三维的人脸的数据,那么这个时候川大智胜作为国内目前唯一一家有产品和技术的公司,面临的是广阔的市场。但是我们同时也要看到,三维人脸识别虽然有非常惊人的优势,同时劣势也是非常明显的,特征点的选取,包括侧脸的选取,是有难度的。同时表情的因素,其实对于数据处理的影响,没有在立体表情的因素那么好,提取的时候效率是偏低的,消耗的数据也非常大。所以现在来看,我们能够看到的应用场景目前还是小范围的,包括像美国对犯罪的有案底的犯人,我们国内目前在监狱当中也逐步的推广,将来全民都要采集,这肯定是一个非常巨大的市场。 同时这家公司在人脸识别公司当中,技术特点和现在持续的对三维人脸识别加码,有一个项目是1.8个亿,要投入到研发当中,国家自然科学基金也已经持续的支持他们三维人脸识别的学术研究的项目,已经支持了很多年。所以在这个领域,应该是到了开花结果的地步。所以这一点,我们特别提示大家要关注这个公司,在技术上确实是有稀缺性的。 科大讯飞,就是典型的我们刚才讲的商业模式,可以实现人脸识别数据正循环的公司,是拥有互联网端的入口的。之前在语音的领域当中,讯飞语音云走的就是这样的模式,我获取的是你语音的数据,用你的数据持续的训练我后台的算法,使得他们提升和保持和其他竞争对手的领先优势。这样的话,数据端的循环,从语音的这个领域当中,复制到图像识别,就是人脸识别当中。大家如果关注讯飞,大家可以看到,在上个星期的时候,推出了双重生物特征的识别的因素,双重是什么呢?两重加密以后,确实就是这个人,把出错的概率降到非常低的水平。同时识别,双重加密之后,这个身份验证的过程可以做到数量级上面的提升。 有了这样一种开放云的平台之后,讯飞的数据正规化的过程也在逐步的建立,他下一步会和非常多的第三方的应用方合作,包括可以刷脸开锁的智能硬件方面,包括和电话银行,电话客服,还有邮箱去实现他的数据入口的正循环的过程。我们核心的问题就是以上的这样的一些判断的标准来去甄别的。我认为讯飞实际上是非常有希望的人脸识别的公司。我们在报告当中,也提到了讯飞是一个生态级的公司,不光是在人脸识别的这个领域当中有比较强的资源优势和技术优势,以及商业模式的优势。同时在我们整个的人工智能领域当中,讯飞超脑可以不断的用它孵化,基于学习的模式,从语音迁移到现在的图像,下一步迁移到语义当中,不断的做技术的衍生,这样的生态链一旦形成的话,在人工智能产业的地位是不可动摇的。所以人工智能整个的产业,我们想推的是科大讯飞。 人脸识别的领域当中,讯飞的优势也是非常明显的,同时我们也是看好川大智胜拥有的三维人脸识别的技术。其他的品牌公司,我们可以看到欧比特收购的公司,在安防领域的人脸识别当中,在监狱当中是超过50%的,在产品化方面也做的非常好。其他的两家,刚刚推出了自己的识别技术,现在了解的信息当中,还没有办法很好的甄别他们现在是否拥有满足我们以上的五个标准。在以后的调研和跟踪当中,我们会对他们的标准进行梳理和进一步的分解。这是对识别类公司的分析. 下一个阶段,我们觉得还有比较好的投资机会,除了第一类识别类的,第二类应该是数据资源类的,数据资源目前来看就是视频资源,有比较好的视频资源的公司,可以通过视频资源进行持续的深度学习的算法和优化,也许他自己没有这个技术和能力,但是可以通过技术合作的方式,找到研发团队或者是公司进行合作,共同开发优势。目前在视频资源当中的这些公司进行梳理的话,我觉得东方网力在这个当中步子迈的最前。目前产品端还是没有关于人脸识别成型的产品推出来,但是他的应用是在于多年的视频数据的积累。这个是和后期有密不可分的关系。先收购了广州的安防领域的视频监控的智能化的公司,这个步子一迈出去,布局的意图非常的明显。摄象头公司会往视频的公司侵占,后面的公司将来可能会往存储的环节去挤压,有可能将来会把分析和存储在一个环节当中就完成了,这个时候面临的压力是比较大的,所以转型的动力也是最迫切的,意愿也是最强烈的。 所以总体总结下来,现在人脸识别技术大爆发,并不是偶然的,应该说很好的满足了我们讲的人工智能的三大条件。深度学习的算法,大数据和云计算,这三个条件成熟了以后,在拐点到来的时候,大规模的商业化应用是水到渠成的。下一个阶段,基于计算机视觉的应用,在视频监控领域当中,对人的行为模式的识别、跟踪和分析,这些都会成为一个非常大的市场,成熟度还有待于进一步的检验。但是这个市场我们已经都看得到了,所以现在我跟大家探讨人脸识别的产业的发展机会,我觉得其实大家需要关注的不仅仅在于人脸识别技术本身的发展,也不仅仅在于哪几家上市公司拥有哪几项技术,而是看到背后代表的是整个计算机视觉的兴起。 人工智能报告当中也提到过,计算机视觉的1.0版本,是对静态图像的识别,2.0版本,肯定是动态视频内容的理解和学习,包括像谷歌的无人驾驶汽车,包括报告里面提到过的以色列的那个公司,也是纳斯达克上市的,他们用计算机视觉的技术实现了汽车的辅助的无人驾驶。在这个领域当中,实际上计算机视觉可供开发的应用非常丰富的。现在还有一个法律的问题,就是允许不允许无人驾驶的汽车上路,合法不合法的问题,大家不用担心这个问题。因为这个公司IPO的时候,这个公司的CEO说过一句话,他说现在还在担心无人驾驶的汽车上路合法不合法,但是我可以肯定的告诉你,十年以后,人开车上路是不合法的,这肯定是一个大的方向和趋势。这就是我从人工智能的领域延伸出来的,人脸识别只是一个点,更多的还有待于大家去一点一点的发掘。
一、渲染层级 从渲染流程上分,Skia可分为如下三个层级:
1、指令层:SkPicture、SkDeferredCanvas->SkCanvas
这一层决定需要执行哪些绘图操作,绘图操作的预变换矩阵,当前裁剪区域,绘图操作产生在哪些layer上,Layer的生成与合并。
2、解析层:SkBitmapDevice->SkDraw->SkScan、SkDraw1Glyph::Proc
这一层决定绘制方式,完成坐标变换,解析出需要绘制的形体(点/线/规整矩形)并做好抗锯齿处理,进行相关资源解析并设置好Shader。
3、渲染层:SkBlitter->SkBlitRow::Proc、SkShader::shadeSpan等
这一层进行采样(如果需要),产生实际的绘制效果,完成颜色格式适配,进行透明度混合和抖动处理(如果需要)。
二、主要类介绍 1、SkCanvas 这是复杂度超出想像的一个类。
(1)API设计
a、创建:
在Android中,主要的创建方法是由SkBitmap创建SkCanvas:
explicit SkCanvas(const SkBitmap& bitmap);
这个方法是由bitmap创建一个SkBitmapDevice,再将这个SkBitmapDevice设定为SkCanvas的渲染目标。
5.0之后提供了一个快捷方法创建SkCanvas:
static SkCanvas* NewRasterDirect(const SkImageInfo&, void*, size_t);
这样Android的GraphicBuffer就不需要建一个SkBitmap和它关联了,可以解除SkBitmap类和android runtime的关系(虽然如此,目前Android5.0上,还是按建SkBitmap的方法去关联GraphicBuffer)。
5.0之后引入的离屏渲染:
static SkCanvas* NewRaster(const SkImageInfo&);
创建一个SkCanvas,绘制的内容需要通过readPixels去读取,仍然是CPU绘图的方式。(个人觉得这个是转入GPU硬件加速的一个比较方便的接口,不知道出于什么考虑还是用CPU绘图。)
b、状态:
矩阵状态:
矩阵决定当前绘制的几何变换
rotate、skew、scale、translate、concat
裁剪状态:
裁剪决定当前绘制的生效范围
clipRect、clipRRect、clipPath、clipRegion
保存与恢复:
save、saveLayer、saveLayerAlpha、restore
c、渲染:
大部分渲染的API都可由这三个组合而成:
drawRect(矩形/图像绘制)、drawPath(不规则图形图像绘制)和drawText(文本绘制)
d、像素的读取与写入
readPixels、writePixels
这两个API主要由device实现,考虑到不同绘图设备的异质性。
(2)MCRec状态栈
fMCStack是存储的全部状态集,fMCRec则是当前的状态。
在 save saveLayer saveLayerAlpha 时,会新建一个MCRec,在restore时,销毁栈顶的MCRec。
(代码见:SkCanvas.cpp internalSave函数,通过这段代码可以了解一下new的各种用法~。)
每个状态包括如下信息:
class SkCanvas::MCRec {
public:
int fFlags;//保存的状态标识(是否保存矩阵/裁剪/图层)
SkMatrix* fMatrix;//矩阵指针,若这个状态有独立矩阵,则指向内存(fMatrixStorage),否则用上一个MCRec的fMatrix
SkRasterClip* fRasterClip;//裁剪区域,若这个状态有独立裁剪区域,则指向内存(fRasterClip),否则继承上一个的。
安装环境 版本 2.1.0 对应CDH5.3.0 impala是CDH的组件,hadoop其他环境(hdfs、yarn、hive)已经准备的情况下,直接通过yum进行安装,这里提供下载地址impala下载
安装内容: 安装的用户为:root hdname (hive 元数据节点所在) impala impala-server impala-state-store impala-catalog impala-shell 其他节点 impala-server impala-shell
权限配置(所有机器都应当进行) impala 安装过程中会创建名为 impala 的用户和组,不要删除该用户和组。 如果想要 impala 和 YARN 合作,需要把 impala 用户加入 hdfs 组,相关的可以了解的是Llama项目。 impala 在执行 DROP TABLE 操作时,需要把文件移到到 hdfs 的回收站,所以你需要创建一个 hdfs 的目录 /user/impala,并将其设置为impala 用户可写。同样的,impala 需要读取 hive 数据仓库下的数据,故需要把 impala 用户加入 hive 组。
添加附属组命令 usermod -G hive,hdfs,hadoop impala 结果如图 创建impala在hdfs上的目录并设置权限 sudo -u hdfs hadoop fs -mkdir /user/impala sudo -u hdfs hadoop fs -chown impala /user/impala 设置scoket path 在每个节点上创建/var/run/hadoop-hdfs kdir -p /var/run/hadoop-hdfs 注意:该文件夹可能已经存在,应当确认用impala是否有权限进行读写 如果已经存在,将用户impala加入该文件所属的组,并修改该文件组的权限即:chmod 775 /var/run/hadoop-hdfs
在当今主流的CAD市场中,SolidEdge®为客户提供最有价值、总拥有成本最低的软件。下面我们列举了投资SolidEdge是最明智的商务抉择的10个理由。本次将会先给出前五个理由,下一期将会给出剩下的五个理由,敬请期待吧。
1.快速、灵活的产品建模
SiemensPLMSoftware拥有世界上最好的三维建模技术,其Parasolid®建模内核已经有100多万许可用户,是名副其实的三维机械CAD标准。事实上,全球很多领先的CAD/CAM/CAE/plm软件供应商都采用了备受推崇的Parasolid®建模内核。D-Cubed组件也是SiemensPLMSoftware开发和拥有的,该组件为CAD、CAM、CAE及PLM应用程序提供关键功能,包括绘制草图、零件和装配建模、运动仿真、碰撞检测、间隙测量以及隐藏线可视化等。D-Cubed同样也被全球大量软件厂商采用。
SolidEdge就是基于SiemensPLMSoftware自己拥有的Parasolid和D-Cubed技术而开发。由于采用本公司的核心技术,SolidEdge能够发挥其潜能,开发和提供更为直观、易用的设计工具,这些工具不仅具有很强大的功能和灵活性,而且还容易实施和使用。
为了提高建模灵活性的终极体验,SolidEdge提供了DirectEditing(直接编辑)功能,这在同级别软件中是绝无仅有的。通过该功能,可以编辑复杂的参数化模型,而无需依赖历史树,从而简化了设计过程。通过直接编辑,还可以编辑从Pro/Engineer、SolidWorks、Inventor或MechanicalDesktop软件导入的3D模型以及IGES或STEP格式数据。
SolidEdge革命性的RapidBlue技术克服了现有CAD系统的种种局限性,为设计人员、工程师以及工业设计人员提供了更高级别的设计控制和灵活性。有了RapidBlue技术,用户不必忍受CAD系统的限制,就能设计出任何想要的图形。例如,RapidBlue技术突破了传统的基于历史的曲面编辑方法,只需很少几步,设计者就能编辑复杂曲面,实时地修改设计并得到想要的设计结果。
2.强大的大装配管理
客户需要创建的产品往往由超过十万的零件组成。要交互式地处理如此庞大的装配,所使用的工具必须要有最优的性能。很多类似的软件实际只提供打开和显示大型装配的功能,速度也很不理想,这不能满足客户实际需求–更重要的是要能够高效地对这些装配进行导航、操作以及文件化处理。长期以来,SolidEdge一直在大装配设计领域处于领导地位,提供很多独特的功能,帮助客户处理很大的数据集。
SolidEdge率先引入了“简化装配”这一概念,可以使性能最大化并且不会限制用户交互。通过创新性的功能选项,您可以先导航整个装配树结构,然后排除干扰,将暂时不需关心的零部件“隐形”从而将注意力放在工作零部件上。
SystemsDesign(系统设计)是SolidEdge独有的方法,用于创建智能装配。传统的装配设计主要专注于零件彼此间的配合度,而SystemsDesign则强调功能,您可以用来创建智能化数字原型,对零件的实际使用情景进行仿真。通过SolidEdge里面的运动仿真工具,您可以在设计阶段快速、准确、逼真地进行运动研究,快速、容易地定义各种运动关系及驱动器,比如齿轮,滑轮,液压缸,马达等等。
3.提供针对专业应用的设计模块
针对很多专门的设计需求,例如钣金设计、焊接件设计等,SolidEdge提供了定制、集成的指令和环境来提高设计生产力,其设计速度远远高于通用的CAD建模工具。全面定制的设计模块包括:
•钢结构设计:用于开发刚性框架结构
•焊接件设计:用于提高焊件的设计及文档化速度
•管道系统:一套综合性的设计工具,用于帮助设计人员在SolidEdge装配里面快速布管并对其进行建模处理
•线束设计:集成大众化的电气布线设计程序包,并且提供用于创建电线和线束的全套工具
•模具设计:提供功能强大的自动化工作流程,能够快速、容易地设计塑胶注塑膜
•标准零件库:一个功能强大的零件管理系统,允许设计人员对共用零件进行定义、存储、选择和定位
•照片级艺术效果渲染:提供真实的渲染功能,可以用在概念评审直至制作宣传资料各个环节
4.经过实践检验的二维制图功能
SolidEdge提供了无与伦比的二维制图功能,包括卓越的制图设计、详细设计、图表注释和尺寸控制能力,它们都会根据用户选定的机械制图标准自动处理。
SolidEdge可根据三维模型自动创建和更新图纸,迅速创建标准视图和辅助视图,包括截面视图、局部放大视图、断面视图、ISO视图等。设计者能够选择多种不同的显示方式,诸如阴影方式,尽可能地表达设计意图,使交流沟通异常方便。当零件或装配件发生改动时,相关图纸会自动更新。
SolidEdge提供全面的标注和注释工具,能够快速地进行全部细节的描述。实用的、智能的尺寸标注和注释说明工具意味着设计者能够在几秒钟内创建视图的尺寸。对于每一个图形元素,设计者可以设置其对应的标准(如企业标准、国际标准等)。
5.动画和动态文档
在沟通设计意图方面,三维模型比二维图纸要有效得多,而SolidEdge则能够把您的设计提升到更高层次–提供运动仿真工具用于评估原型,提供高级功能用于显示装配、拆装顺序,并且提供一个高级的渲染环境创建逼真的情景,对你的产品使用环境进行仿真。
SolidEdge里面的爆炸和运动仿真功能能够帮助团队沟通设计理念,表述大的复杂装配,在维修手册中创建技术插图,同时用动态三维运动文件更轻松地传递更清楚的装配制造指导和培训视频。
在对装配进行“爆炸”时,一条易于操作的时间线能够捕捉事件。由电机和齿轮生成的运动允许用户创建非常棒的动画和演示。附加的摄像机和组件路径能够增加逼真度和透明度,包括真正的飞轮槽沟。在动画中,可以设置零部件的风格、纹理和阴影,以突出或淡化该项目。
前面5个理由是否就足已经让你对solidedge产生极大的兴趣呢?下一期的5个理由将会让你对solidedge有更加深入的了解,在了解了solidedge的强大功能之后,相信你会毫不犹豫地选择solidedge。
转载于:https://my.oschina.net/u/2357930/blog/411677
注意事项
1.addNamedCommand,增加一个命令对象的时候,有一个图片位图ID,该图片所在的资源编译类型必须是【不生成代码】,而且该图片的大小必须是16*16,否则图片增加不到命令上。
2.将编译文件增加到项目中的时候不能直接使用EnvDTE.Project的ProjectItems来进行增加,这样增加的文件不会加入到编译选项,正确的做法如下
VCProject vcProj = proj.Object as VCProject;
vcProj.addFile(....);
可变分区存储管理,又称动态分区模式,是实存管理中连续存储的一种实现方式。 在分区的分配和回收时,根据不同的查找规则,有5种:
first fit,最先适应分配算法,按地址递增排序。next fit,下次适应分配算法,在first fit基础上,从上次搜索结束为止开始搜索。best fit,最佳适应分配算法,按空闲区长度从大到小排序。worst fit,最坏适应分配算法,按空闲区长度递减排序。quick fit,快速适应分配算法,将常用长度的空闲区有组织地存放。 这里以一份代码来演示最先适配法,下次适配法,最佳和最差适配法。源文件命名为variable_partition.c
#include <stdio.h> #include <stdlib.h> #include <string.h> //#define JOB_MAX 10 struct { int address; int length; int id; }used_table[JOB_MAX]; struct f_table { int address; int length; }free_table[JOB_MAX+1]; int free_num = 1; int used_num = 0; int comp_addr_increase(const void *p1, const void *p2) { return ((struct f_table*)p1)->address - ((struct f_table*)p2)->address; } int comp_length_increase(const void *p1, const void *p2) { return ((struct f_table*)p1)->length - ((struct f_table*)p2)->length; } int comp_length_decrease(const void *p1, const void *p2) { return ((struct f_table*)p2)->length - ((struct f_table*)p1)->length; } int update_free_table() { int i, j; if(free_num < 2) return 0; /* sort by address */ qsort(free_table, free_num, sizeof free_table[0], comp_addr_increase); /* merge */ for(i=0; i < free_num-1; i ++) { if(free_table[i].
本文介绍RSA加解密中必须考虑到的密钥长度、明文长度和密文长度问题,对第一次接触RSA的开发人员来说,RSA算是比较复杂的算法,RSA算法本身其实也很简单,RSA的复杂度是因为数学家把效率和安全也考虑进去的缘故。
本文先只谈密钥长度、明文长度和密文长度的概念知识,RSA的理论及示例等以后再谈。提到密钥,我们不得不提到RSA的三个重要大数:公钥指数e、私钥指数d和模值n。这三个大数是我们使用RSA时需要直接接触的,理解了本文的基础概念,即使未接触过RSA的开发人员也能应对自如的使用RSA相关函数库,无需深入了解e、d、n是如何生成的,只需要知道我该如何用、要注意什么。
一、密钥长度 1、密钥是指谁? 首先我们说的“密钥”是指谁?由于RSA密钥是(公钥+模值)、(私钥+模值)分组分发的,单独给对方一个公钥或私钥是没有任何用处,所以我们说的“密钥”其实是它们两者中的其中一组。但我们说的“密钥长度”一般只是指模值的位长度。目前主流可选值:1024、2048、3072、4096...
2、模值主流长度是多少? 目前主流密钥长度至少都是1024bits以上,低于1024bit的密钥已经不建议使用(安全问题)。那么上限在哪里?没有上限,多大都可以使用。所以,主流的模值是1024位,实际运算结果可能会略小于1024bits,注意,这个值不是绝对的,跟素数的生成算法有关系,只是告诉素数生成器“帮我生成一个接近1024位的素数而已”,然后生成器“好,给您一个,这个差不多1024位”。
素数生成器这么厉害?说生成1024位就会出个1024位的大整数?真实的情况是素数生成器也只是在1024bits对应的整数附近进行“摸索”而已,大家其实都不容易,又要快又要准确又要随机性,那么素数生成器也只能应付一下,找到1024位的算是好运,没找到1024位,1023位也照样送出来:)。
3、公钥指数如何确定? 公钥指数是随意选的,但目前行业上公钥指数普遍选的都是65537(0x10001,5bits),该值是除了1、3、5、17、257之外的最小素数,为什么不选的大一点?当然可以,只是考虑到既要满足相对安全、又想运算的快一点(加密时),PKCS#1的一个建议值而已。
有意的把公钥指数选的小一点,但是对应私钥指数肯定很大,意图也很明确,大家都要用公钥加密,所以大家时间很宝贵,需要快一点,您一个人私钥解密,时间长一点就多担待,少数服从多数的典型应用。
4、私钥指数如何确定? 公钥指数随意选,那么私钥就不能再随意选了,只能根据算法公式(ed%k=1,k=(p-1)(q-1))进行运算出来。那么私钥指数会是多少位?根据ed关系,私钥d=(x*k+1)/e,所以单看这个公式,私钥指数似乎也不是唯一结果,可能大于也可能小于1024bits的,但我们习惯上也是指某个小于1024bits的大整数。
包括前文的公钥指数,在实际运算和存储时为方便一般都是按照标准位长进行使用,前面不足部分补0填充,所以,使用保存和转换这些密钥需要注意统一缓冲区的长度。
二、明文长度 网上有说明文长度小于等于密钥长度(Bytes)-11,这说法本身不太准确,会给人感觉RSA 1024只能加密117字节长度明文。实际上,RSA算法本身要求加密内容也就是明文长度m必须0<m<n,也就是说内容这个大整数不能超过n,否则就出错。那么如果m=0是什么结果?普遍RSA加密器会直接返回全0结果。如果m>n,运算就会出错?!那怎么办?且听下文分解。
所以,RSA实际可加密的明文长度最大也是1024bits,但问题就来了:
如果小于这个长度怎么办?就需要进行padding,因为如果没有padding,用户无法确分解密后内容的真实长度,字符串之类的内容问题还不大,以0作为结束符,但对二进制数据就很难理解,因为不确定后面的0是内容还是内容结束符。
只要用到padding,那么就要占用实际的明文长度,于是才有117字节的说法。我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建议的padding就占用了11个字节。
如果大于这个长度怎么办?很多算法的padding往往是在后边的,但PKCS的padding则是在前面的,此为有意设计,有意的把第一个字节置0以确保m的值小于n。
这样,128字节(1024bits)-减去11字节正好是117字节,但对于RSA加密来讲,padding也是参与加密的,所以,依然按照1024bits去理解,但实际的明文只有117字节了。
关于PKCS#1 padding规范可参考:RFC2313 chapter 8.1,我们在把明文送给RSA加密器前,要确认这个值是不是大于n,也就是如果接近n位长,那么需要先padding再分段加密。除非我们是“定长定量自己可控可理解”的加密不需要padding。
三、密文长度 密文长度就是给定符合条件的明文加密出来的结果位长,这个可以确定,加密后的密文位长跟密钥的位长度是相同的,因为加密公式:
C=(P^e)%n
所以,C最大值就是n-1,所以不可能超过n的位数。尽管可能小于n的位数,但从传输和存储角度,仍然是按照标准位长来进行的,所以,即使我们加密一字节的明文,运算出来的结果也要按照标准位长来使用(当然了,除非我们能再采取措施区分真实的位长,一般不在考虑)。
至于明文分片多次加密,自然密文长度成倍增长,但已不属于一次加密的问题,不能放到一起考虑。
基于TCP的网络应用程序的编写 1.服务器端程序
#include <Winsock2.h> #include <stdio.h> #pragma comment(lib,"Ws2_32.lib") void main() { //加载套接字库 WORD wVersionRequested; //加载的Winsock库的版本 WSADATA wsaData; //库版本的有关信息 int err; wVersionRequested = MAKEWORD( 1, 1 ); //用 MAKEWORD 宏请求一个1.1版本的WinSock库 err = WSAStartup( wVersionRequested, &wsaData );//用WSAStartup()来加载套接字库 if( err != 0) //不等于 0 表示加载套接字库不成功 return; if( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )//如果低位字节不等于1 或 高位字节不等于 1则 { WSACleanup();//释放为该应用程序分配的资源,终止对WinSock 动态库的使用 return; } //创建用于监听的套接字 SOCKET sockSrv = socket( AF_INET, SOCK_STREAM, 0 ); SOCKADDR_IN addrSrv; //地址结构体 //用htonl()将主机字节序转换为网络字节序,INADDR_ANY表示允许套接字向任何分配给本地机器的IP地址发送或接收数据 addrSrv.
在面试的时候被问了一个多线程的问题 回来仔细思考了一下,多线程是否真的能提高了效率? 我对多线程的理解就是: 比如挖一个隧道,有2种开工方法 1、只在山的一头挖,直至挖到山的另一头,从而打通隧道,这可以看成是单线程 2、在山的两头挖,同时开工,最后在山的中间接通,从而打通隧道,这感觉肯定比1快了很多,好比多线程 但是2成立的前提是必须有两个工人。而我们的计算机中一般来说只有一个CPU,也就是说只有一个工人。 多线程不过是CPU在不同的时间片之间切换,而表现出齐头并进的样子。 既然挖隧道的人只有一个,虽然我的施工方案是在山的两头开挖,但是由于工作的人只有一个,所以只有让这个人在山的两头跑,挖一会这头再去挖另一头,来回跑是要花费额外时间的(好比线程的切换和调度)。 那么,我们是不是可以说,在单CPU的机器中,多线程反而降低了效率呢? 1. 不能一概而论,你的看多线程在你的程序中为啥而生。在单cpu系统,比如有io的等待,多线程也能提高效率 2 楼主提的问题很有意思。经典的解释是 - 如果cpu确实是一个挖山工人,那么它工作就好像是挖1个小时,然后休息10个小时;这期间如果让它跑到山那头继续挖,效率还是很高的。 现在问题是 - 它是否工作1小时然后休息10小时?答案是肯定的。现在的程序时间大多花在读取数据上,真正的计算工作花时间还是相对少的,因此cpu很大时间表现都很闲,就像挖山,挖土效率高,运土效率低。多线程就是要充分利用它的挖土效率 3 pc机不光只一个cpu,cpu和其它硬件设备一起才能完成计算,分工协作,但可能出现其中某个家伙偷懒或效率低,导致大家都等它,闲着的其它设备这个时 候可以腾出手来干其它活。单cpu在同一时刻只能干一件事情,这没有问题,问题是它并不是7*24*3600都在干活,其它设备也是同样的道理,多线程的 目的可以最大限度的提高硬件设备的利用率。 4 同一个设备可以同时干几件事情,但一个设备在同一时刻肯定只能干一件事情,一般我们说并行或串行,都在以时间段来看的而不是以时刻来看的,比如你一边上je消遣还一边写代码干活,在一定的时间范围内,你是并行的,但如果这个时间范围你划分得非常非常短,那么你是串行的 5 一个cpu可以多线程。但是一个单核的cpu任何时间点,都只能在做一个任务。 如果只是像楼主说的挖隧道这么简单的事,那么的确多线程没用。 只不过很可惜,计算机不像拿铁锹挖隧道这么简单。 6 假设每挖5分钟,就需要清理一下挖出来的石土。有一个小车在清理它们。 工人只有一个。 单线程的做法是: 挖5分钟。然后工人停止挖,小车清理石土的5分钟里,工人在等待。 2个线程的做发是: 挖5分钟,小车来清理石土。这5分钟里,工人在另一头挖。 也不是很恰当的比喻。不过至少能说明点问题。 小车清理石土,就相当于磁盘io等相对于cpu计算来说比较慢的操作。 cpu不会等着io的完成,而去执行另一个进程的计算任务。 这边io完成时好象是会发出什么信号来着,忘了。计算机原理都还给老师了,惭愧啊。 7 如楼主所举的例子,我来解惑。 如果一个机器人代表CUP,哪么这个机器人一天所做的事情,并不都是只挖山。 它还有许多事情要做,比如砍柴,烧水,钓鱼,挖山等等等。 如果按以上划分是 4条线程, 每一个线程大概占用1/4CUP时间。 如果你的设定 在挖山这一快 多设几次同一个任务。 比如设定到 挖山共有3条线程。 哪么 挖山的CUP占用率将达到 1/2 这就是所谓的提高了效率。 现实中的CPU 在大部分时候的 闲置状态的。 因此 开多条线程能提高效率 不如说成是 充分利用了CPU执行时间。 8 楼主举的例子是并行,在资源有剩余的情况下(比如人都堆到一个洞里干不开),肯定是提高效率。如果资源有冲突(人手只够从一个方向挖,比如只一个CPU),那就是并发了,不一定能提高效率。 我想了个例子: 假设人手只够从一个方向挖洞。 挖洞时,总得把洞里的土运出去吧。洞越深,运土越占用时间,如果一大伙人都在那挖洞,等挖出一车土,然后一起坐着车运土(带装卸),那路上那些人就闲着了 (挖土时司机也会闲着)。为了提高工作效率,那就把人分成三组,一组人(一个挖土线程)挖土,两组人运土(两辆车,两个运土线程)。 9 我认为啊,单CPU单核、纯计算、没IO的理想状态下,单个线程肯定比多个线程快,因为省去了线程切换的开销。但真实的环境基本都有IO操作,在 异步的业务场景下,我一般会使用线程池,至于线程池的线程数目配置为多少,有资料推荐为N×(1+IO耗时/完整的业务耗时),N是CPU核数。 10 最简单的如web server,如果单线程的话,一个server同时只能接受一个用户的点击。 还点击率呢,直接就绿了。 另外多线程和快不快没有直接关系。最主要的是可以并发执行。 纯粹比较同一个任务在单线程还是多线程模式下快的话,肯定是单线程快。因为多线程会有一个线程调度的消耗。但是最为一个系统,多线程的优势是非常明显的。如果Java没有多线程直接可以去死了。 当年红极一时的plam系统因为对多线程支持的不好,在网络和媒体应用方面败下阵来。 11 多线程效率 我认为未必会高,而且有时候相反会低。 多线程并不是为了提高效率,而是不必等待 可以并行执行多条数据。 可以这么想 我们通过xp系统复制文件。你可以复制一份文件 这叫是单线呈,但是你要等这个复制完了才能复制另一份文件,而且不能多复制。这样很难受,所以你可以选择多复制文件,这就是多线程。但复制多份文件用的时 间未必会比一份一份文件所用时间少。只是它合理利用了时间进行了多个操作。 如果是买票系统 就会用到多线呈。买票是同时进行的,如果一个用户一个用户等下去不是办法,所以可以多个用户同时买票,效率也就提高了。这里的效率不是执行的效率 而是时间的合理利用,多个线呈同时进行。 12 单线程,多线程,线程池,都是不同问题的不同解决策略,不存在谁的效率一定高的问题.
本文方法主要适用于经典的OpenCV2.4.x的所有版本,3.x不在范围内。本文的配置方法可以容忍vs的所有版本,以及32位和64位的配置冲突问题,完美解决OpenCV所有配置相关问题,一次完成配置,轻松编写所有程序,并且能使各种vs版本配置的环境不冲突的方法。 如果你已经配置了opencv,有问题或者没问题,避免方法冲突可以清掉现有配置,以现在这种方法来实现最佳配置。
1.下载OpenCV:这里选择2.4.10 下载后,我们得到一个7z的exe文件压缩包,双击解压缩到指定目录如下图: 2.修改目录名 a.将build/x86下的vc10、vc11、vc12(如果有vc9、vc13等,一样修改,后面加0即可),修改为vc100、vc110、vc120,如图 b.将build/x64下的vc10、vc11、vc12(如果有vc9、vc13等,一样修改,后面加0即可),修改为vc100、vc110、vc120,如图 c.将build下的x86修改为win32 3.打开visual studio(无论你什么版本都行),这里以vs2013为例,新建一个控制台项目: a.选择配置管理器-新建解决方案平台-选择x64,确定即可,如图: b.选择视图-属性管理器 c.填入头文件和库文件路径 这里库的路径是如下,该库路径是全部通用: H:\opencv2.4.10\build/$(Platform)/vc$(PlatformToolsetVersion)/staticlib d.添加宏定义:_CRT_SECURE_NO_WARNINGS 4.写程序 在代码中写下:
#include "stdafx.h" #include <cv.h> #include <opencv2/core/core.hpp> #include <highgui.h> using namespace cv; int _tmain(int argc, _TCHAR* argv[]) { Mat img(300, 300, CV_8UC3); img.setTo(Scalar(0, 255)); imshow("Hello OpenCV", img); waitKey(); return 0; } a.打开cv.h b.在cv.h中添加一句:#include <opencv/cv_import_static_lib.h> c.打开core.hpp d.在core.hpp中添加一句:#include <opencv/cv_import_static_lib.h> e.core.hpp上点右键,打开core.hpp所在目录,进入到opencv头文件目录下,然后转到:H:\opencv2.4.10\build\include\opencv f.在目录中新建文本文件.txt,并将如下内容粘贴并保存
#pragma once #ifdef WIN32 #include <opencv2/core/version.hpp> //定义宏,保证在debug模式下,导入opencv_xxxd.lib,release模式下导入opencv_xxx.lib #ifdef _DEBUG # define CC_CVLIB(name) "opencv_" name CC_CVVERSION_ID "
原文:http://www.youxijishu.com/blogs/4.html
一,游戏服务器编程语言的选择
所谓的游戏服务器编程语言其实有很多,基本上任何一种语言都可以作为游戏服务器的编程语言。这需要根据自己游戏的类型和要求加以选择。比如C++,Java ,Erlang,go等等。目前我用过的只有C++和Java.但是以Java为主。所以接下来就以自己的经验,谈谈以Java为核心的游戏服务器开发技术体系。
Java目前作为游戏服务器开发语言已经很是普遍。但是大多数是作为页游或手游的服务器,而端游戏一般选择C++,因为端游对服务器的性能要求相对比较高一些。两种语言各有利弊。C++效率高,但是掌握度难些。没有Java易于掌握。而目前对于追求快速上线率的页游和手游来说,Java成了一个不错的选择。
二,Java的技术系统
需要学习的技术:
(1)Java基础知识,这是必须的
(2)JavaNIO编程,这是Java高性能网络编程的基础
(3)Netty,Mina网络框架精通一种,其它作为了解。
(4)一种缓存框架:Redis;memcache熟悉使用一个。
(5)SQL语言,用于数据库:mysql,oracle
(6)多线程编程,明白线程安全的重要性。
(7)Java并发集合的掌握。
(8)Linux常用的基本命令及shell脚本。
(9)数据库操作框架,比如mybatis。
(10)设计模式
以Java为服务器编程语言来说,掌握Java的基本知识就不必说了,是必不可少的。可以参考《Java编程思想》,《Java核心技术》等书。根据游戏通信协议的不同,大致有两种实现方式:Socket和http。先说简单些的http协议,这个协议已经很成熟的应用到了网站上。而Java语言也可以用于网站开发,所以相当就简单些。现在有很多开源的服务器软件,比如:tomcat ,resin等。游戏前端不管是页游flash,还是手游的Android,IOS都支持http协议,只要把游戏的逻辑数据按post方法向服务器发出请求即可了。
而对于socket来说,就需要掌握一些深入的网络通信知识。对于Java来说,一般选择NIO(非阻塞)开发方式。可以参考Java NIO编程相关资料。为了适应这个需求,现在有很多网络通信框架,比如Netty,mina。目前已经成熟的应用到了游戏开发当中。这些都是开源的,有兴趣可以阅读它们的源码。
游戏服务器开发过程中,会涉及到很多多线程的应用。这样可以提高服务器的性能和实现某些特定的操作。比如组队打怪,竞技场的事实排名。这些涉及到了并发对共享数据的操作。为了防止数据的错误,一定要做好数据的同步。这里推荐一本书《Java并发编程实战手册》。
三,学习流程
当然了,学习这些东西并不是一蹴而就的。需要根据实践循环渐进,这里推荐一个学习流程:
(1)对于初学Java的人来说,如果自学能力好些,可以买些书自己练习,而现在又更的多选择参加培训机构的培训,以快速的掌握Java的知识。
(2)掌握了Java知识之后,要多写代码实践。这个时候可以结合mysql学习SQL语言,掌握数据库的操作。比如用springmvc写一个小网站,用mybatis实现网站数据的增,删,改,查等功能。
(3)完成上步之后,可以在服务器程序和数据库之间加一个缓存,学习redis或memcache。
(4)把程序部署到linux服务器上,练习linux的基本命令及shell脚本。
原文:How to create custom Switch in Android 示例源码下载:http://download.csdn.net/detail/zhangyihui1986/8651437
在本教程中,我会演示如何定制Switch控件,添加单击监听器,使用Switch去控制媒体声音和wifi设备。 下面是本教程的运行结果: 本教程在Eclipse 4.2.0上开发。
首先,修改app的主布局文件 打开“res/layout/main.xml”文件,添加两个Switch控件,以及几个TextView和Button。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center"> <Button android:id="@+id/button1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Disable all switch" android:layout_marginBottom="15dp" android:onClick="button_click"/> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/switch1" android:layout_alignParentLeft="true" android:layout_marginBottom="10dp" android:layout_marginLeft="20dp" android:text="Media Volume"/> <Switch android:id="@+id/switch1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textOff="OFF" android:textOn="ON" android:layout_alignParentRight="true" android:layout_marginRight="20dp" android:onClick="onSwitchClicked" android:thumb="@drawable/switch_bg" android:track="@drawable/track_bg" android:layout_marginBottom="15dp" /> <TextView android:layout_below="@+id/switch1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/switch2" android:layout_alignParentLeft="true" android:layout_marginBottom="10dp" android:layout_marginLeft="20dp" android:text="Wifi"/> <Switch android:layout_below="@+id/switch1" android:id="@+id/switch2" android:layout_width="
Oracle内存在很多特殊意义的名字或者变量:ORACLE_SID,DB_NAME,INSTANCE_NAME,SERVICE_NAME,GLOBAL_DBNAME. 1.ORACLE_SID:(ORACLE SYSTEM IDENTIFIER)站点标示符 以环境变量的形式出现的。 Oracle 实例是由SGA和一组后台进程组成的,实例的创建和启动需要一个参数文件,而参 数文件的名称就是由ORACLE_SID决定的。对于init文件,缺省的文件名称是init.ora,对于 spfile文件,缺省的文件名称是spfile.ora 设置不同的ORACLE_SID值,就可以默认使用不同的参数文件启动不同的数据库实例。 另外,ORACLE_SID的作用远远不是作为一个实例入口这么简单的,在实例启动后,实例名称INSTANCE_NAME也是从ORACLE_SID得到的。 2.INSTANCE_NAME: 实例名称,这是Oracle实例的名字,用来区分不同的实例。在Oracle9i之前,该名字存储在两个地方:参数文件和数据库的内部视图(V$INSTANCE). 而在Oracle10g之后的版本中,该名字不再出现在参数文件中,而是动态从系统中获得,默认是取自ORACLE_SID。 INSTANCE_NAME的作用除了区别不同实例之外,在监听器动态注册时,还会用于向监听器注册。比如instance_name=wolf,监听中将动态注册Instance "wolf",status READY信息。 3.DB_NAME: DB_NAME概念相比于INSTANCE_NAME要重要的多,它决定实例将挂在的数据文件。它出现在数据文件,控制文件,日志文件中。在参数文件中也出现,且必须出现。这个参数涉及到系统的物理文件。 4.SERVICE_NAME和GLOBAL_DBNAME: 这两个参数之所以放在一起讲,是因为他们往往是成对出现的。SERVICE_NAME出现在Tnsnames.ora文件中,是客户端要请求的服务名。 GLOBAL_DBNAME 出现在Listener.ora文件中,是服务器提供的服务名,可以通过show paramerer service_names查看,并可以通过alter system set service_name='servicename' scope=both来修改。 SERVICE_NAMES为实例所连接的数据库定义一个或多个服务名,可以通过定义多个服务名将不同用户连接区分开来。这个参数的缺省格式为: DB_NAME. DB_DOMAIN,如果定义了DB_DOMAIN那么定义的服务名就类似: SERVICE_NAMES = sales.eygle.com, news.eygle.com 通过这样的定义,销售用户可以通过在客户端TNSNAME定义中使用SALES服务名来建 立连接,而新闻用户则可以通过NEWS服务名进行连接,最终用户可以不必关注数据库是哪 一个,他们只需要关心服务名。 二者对应,实现了Listerner.ora/Tnsnames.ora的重要功能----监听、请求与验证。 总结:一条startup命令,究竟是如何启动庞大的oracle数据库的呢?下面我们来贯穿起来整个启动流程,一探究竟: 首先,系统接收到startup命令,立刻采取行动,取得环境变量ORACLE_SID的值,启动第一阶段--实例创建。系统根据找到的参数文件启动 ORACLE数据库实例,实例启动后,一切由实例接管:注册INSTANCE_NAME,往往INSTANCE_NAME就是来自ORACLE_SID, 接着向监听器动态注册实例自己,并将INSTANCE_NAME写入系统数据字典表, 接下来,实例进一步读取参数文件,取得DB_NAME、控制文件、检查点等信息,进入第二阶段--挂载数据库。实例从控制文件中取得DB_NAME,并取 得数据文件、日志文件等信息,进行DB_NAME的一致性检验、文件的存在性判断等工作之后,实例将挂载数据库,挂载的数据库就是DB_NAME指定的数 据库。 最后,实例进入第三阶段--启动数据库。这一阶段,实例进行了两项检查:检查点和更改点检查,之后启动数据库。 init.ora 中的instance_name是可以设置的,这个大家都知道是没有错误的,但是这个和我们ORACLE_SID又有什么区别呢?其实还是有一些区别 的,ORACLE_SID就是系统表示符,这个环境变量就是要告诉OS,我要读取那个init.ora文件或者spfile来启动我的Oracle instance,比如set ORACLE_SID=mylife,这个时候当我连入Oracle后,运行startup,那么Oracle就会寻找spfilemylife.ora 或者initmylife.ora这样的参数文件,并启动我的instance,在数据库成 功open后,我们可以通过select instance_name from v$instance来观察这个已经记录的SID,这个时候我们也可以show parameter instance_name来观察这个值,没错都是mylife,一般来讲,我们启动instance所加载的pfile或者spfile中也记录了一个 instance_name这个参数,但是这个参数一般没有显示的列出,因此我们可以手动的去加上这个参数或者修改这个参数,把这个参数的值改为和 mylife不相同的一个值mylove,这个时候再重新启动数据库,会发现show parameter和select instance_name from v$instance的方式有两个不同的值分别是mylove和mylife,如果我们的tnsnames.ora中的文件是以sid方式来寻找服务,那 么这个sid 的值就不是mylife了,而要改为mylove.恩,大体上就是这个意思。还没有深入研究太多,对于大多数用户来讲,理解这些就足够了。 再 说一下service_name,如果我们的参数文件中记录了db_domain比如是cn.
EEK_SET 将读写位置指向 文件头后再增加offset个位移量。 SEEK_CUR 以目前的读写位置往后增加offset个位移量。 SEEK_END 将读写位置指向文件尾后再增加offset个位移量。 当whence 值为SEEK_CUR 或SEEK_END时,参数offet允许负值的出现。 下列是较特别的使用方式: 1) 欲将读写位置移到文件开头时: lseek(int fildes,0,SEEK_SET); 2) 欲将读写位置移到文件尾时: lseek(int fildes,0,SEEK_END); 3) 想要取得目前文件位置时: lseek(int fildes,0,SEEK_CUR);
1.遍历所有li 把li中的中文转换成拼音和拼音首字母缩写
2.声明一个26个长度的二维数组。把26个英文字母 (("a").charCodeAt(0)) - 97; 0索引就是a,1就是b 以此类推。
3.把li自身的html 放到 二维数组中。
4.清空ul 循环二维数组,从 a-z 放把保存的html到lu中
5.查询,文本框注册 keyup 事件。判断输入内容 中是否 在拼音,拼音缩写,中文名称 是否存在。存在显示,不存在隐藏。为空显示所有
html
<div class="xw_filternm">
<input type="text" class="xw_filteript clr_c6" value="" />
</div>
<div class="xw_sdlswp js-scrwp" id="div_course">
<ul class="xw_sdkcul clearfix cu_p js-beiteac">
<li class="js-dxls" data-name="1" data-name-view="潘立化">潘立化</li>
<li class="js-dxls" data-name="2" data-name-view="郭中秋">郭中秋</li>
<li class="js-dxls" data-name="1" data-name-view="邓证书">邓证书</li>
<li class="js-dxls" data-name="2" data-name-view="邓小飞">邓小飞</li>
<li class="js-dxls" data-name="1" data-name-view="光挨打">光挨打</li>
<li class="js-dxls" data-name="2" data-name-view="中午从">中午从</li>
</ul>
</div>
//js调用
pxcx("div_course","js-dxls","ul",".xw_filteript");
使用拼音的js
转载请标明是引用于 http://blog.csdn.net/chenyujing1234 使用IDA可以帮助我们模仿别人的功能如何实现,这对开发新的软件有很好的作用。
使用IDA也可以帮助我们验证我们的猜测是否是否确的。
1、在开发Gina中想知道VWare使用的认证凭据中怎么把Ctrl-Alt-Del界面去掉的,猜测是使用了SAS.dll中的接口。为了验证我们使用IDA工具来查看。
步一:
步二:
步三:
步四:
2、查看VWare中对于会话改变时是如何实现的,他们是采用对会话进行监控的方式。
二、分析CTXGina
真实的代码:
BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { DisableThreadLibraryCalls((HMODULE)hModule); L_INFO(L"====>XRedGina.dll DLL_PROCESS_ATTACH, CurrentProcessId = %d\n", GetCurrentProcessId()); if ( FALSE == g_CXRedGinaApp.LoadMsginaDll()) { L_FATAL(L"LoadMsginaDll failed(%d)\n", GetLastError()); } L_INFO(L"<====XRedGina.dll DLL_PROCESS_ATTACH\n"); break; } case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: { L_DEBUG(L"=======>!!!XRedGina.dll DLL_PROCESS_DETACH, CurrentProcessId = %d\n", GetCurrentProcessId()); g_CXRedGinaApp.ExitInstance(); L_DEBUG(L"<======!!!!XRedGina.dll DLL_PROCESS_DETACH\n"); break; } } return TRUE; } 步一、分析DllMain
Hive启动报错解决方法 启动Hive时报错如下: wamdm@WAMDM5:~/hive/build/dist/bin$ ./hive Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/hive/conf/HiveConf at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at org.apache.hadoop.util.RunJar.main(RunJar.java:149) Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) 解决方法: /home/wamdm/hadoop-original/hadoop-config/hadoop-env.sh里面被增加了HADOOP_CLASSPATH的设置,如下: export HADOOP_CLASSPATH=$HBASE_HOME/hbase/hbase-0.20.3.jar:$HABSE_HOME/hbase-config:$ZOOKEEPER/zookeeper-3.2.2.jar 将其修改为: export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HBASE_HOME/hbase/hbase-0.20.3.jar:$HABSE_HOME/hbase-config:$ZOOKEEPER/zookeeper-3.2.2.jar 所以增加CLASSPATH时要记得把原来的也加上,而不是覆盖,否则会造成找不到路径。 来自Cloud Project Team@WAMDM 本文可以自由转载,转载时请保留全文并注明出处: 转载自仲子说 [ http://www.wangzhongyuan.com/ ] 原文链接:http://www.wangzhongyuan.com/archives/807.html
人脸识别之特征脸方法(Eigenface)
zouxy09@qq.com
http://blog.csdn.net/zouxy09
因为需要,花了一点时间写了下经典的基于特征脸(EigenFace)的人脸识别方法的Matlab代码。这里仅把该代码分享出来。其实,在较新版本的OpenCV中已经提供了FaceRecognizer这一个类,里面不仅包含了特征脸EigenFace,还有FisherFace和LBPHFace这三种人脸识别方法,有兴趣的可以参考OpenCV的API手册,里面都有很详细的使用例程了。
一、特征脸
特征脸EigenFace从思想上其实挺简单。就相当于把人脸从像素空间变换到另一个空间,在另一个空间中做相似性的计算。这么说,其实图像识别的基本思想都是一样的,首先选择一个合适的子空间,将所有的图像变换到这个子空间上,然后再在这个子空间上衡量相似性或者进行分类学习。那为什么要变换到另一个空间呢?当然是为了更好的做识别或者分类了。那为什么变换到一个空间就好识别或者分类了呢?因为变换到另一个空间,同一个类别的图像会聚到一起,不同类别的图像会距离比较远,或者在原像素空间中不同类别的图像在分布上很难用个简单的线或者面把他们切分开,然后如果变换到另一个空间,就可以很好的把他们分开了。有时候,线性(分类器)就可以很容易的把他们分开了。那既然人类看起来同类的图像本来就是相似的,不同类的图像就不太相似,那为什么在原始的像素空间他们同类不会很近,不同类不会很远,或者他们为什么不好分开呢?因为图像各种因素的影响,包括光照、视角、背景和形状等等不同,会造成同一个目标的图像都存在很大的视觉信息上的不同。如下图所示。
世界上没有存在任何两片完全相同的叶子,虽然他们都是叶子。万千世界,同一类事物都存在共性,也存在个性,这就是这个世界多彩的原因。那怎么办呢?很自然,只要在我们想要的粒度上把同一类目标的共性找出来就好了,而且这个共性最好和我们要区分的类是不一样的。什么叫我们想要的粒度?我理解和我们的任务相关的。例如我们要区分人和车,那人的共性就是有脸、有手、有脚等等。但如果我们要区分亚洲人和非洲人,那么亚洲人的共性就是黄色皮肤等等。可以试着想象,上帝把世界万物组织成一个树状结构,树的根就是万物之源,下一层可以分成生物和非生物,再下一层将生物分为……(囧,想象不到),直到最底层,万物,你我,为树的一片普通得再普通的叶子。树越往下,粒度越小,分类越细(哈哈,自己乱扯的)。停!废话多了点,跑题了,回到刚才的问题,重头戏来了,要变换到什么空间,才具备上述这种良好类内相似、类间区分的效果?到这,我就只能say sorry了。计算机视觉领域发展了几十年,就为了这一个问题倾注了无数研究者的智慧与心血。当然了,也诞生和孕育了很多经典和有效的解答。(个人理解,上述说的实际上就是特征提取)。从一开始的颜色特征(颜色直方图)、纹理特征(Harr、LBP、HOG、SIFT等)、形状特征等到视觉表达Bag of Words,再到特征学习Deep Learning,技术的发展总能带给人希望,曙光也越来越清晰,但路还很远,是不? 扯太多了,严重离题了。上面说到,特征脸EigenFace的思想是把人脸从像素空间变换到另一个空间,在另一个空间中做相似性的计算。EigenFace选择的空间变换方法是PCA,也就是大名鼎鼎的主成分分析。它广泛的被用于预处理中以消去样本特征维度之间的相关性。当然了,这里不是说这个。EigenFace方法利用PCA得到人脸分布的主要成分,具体实现是对训练集中所有人脸图像的协方差矩阵进行本征值分解,得对对应的本征向量,这些本征向量(特征向量)就是“特征脸”。每个特征向量或者特征脸相当于捕捉或者描述人脸之间的一种变化或者特性。这就意味着每个人脸都可以表示为这些特征脸的线性组合。实际上,空间变换就等同于“搞基”,原始像素空间的基就是单位“基”,经过PCA后空间就是以每一个特征脸或者特征向量为基,在这个空间(或者坐标轴)下,每个人脸就是一个点,这个点的坐标就是这个人脸在每个特征基下的投影坐标。哦噢,说得有点绕。
下面就直接给出基于特征脸的人脸识别实现过程:
1)将训练集的每一个人脸图像都拉长一列,将他们组合在一起形成一个大矩阵A。假设每个人脸图像是MxM大小,那么拉成一列后每个人脸样本的维度就是d=MxM大小了。假设有N个人脸图像,那么样本矩阵A的维度就是dxN了。
2)将所有的N个人脸在对应维度上加起来,然后求个平均,就得到了一个“平均脸”。你把这个脸显示出来的话,还挺帅的哦。
3)将N个图像都减去那个平均脸图像,得到差值图像的数据矩阵Φ。
4)计算协方差矩阵C=ΦΦT。再对其进行特征值分解。就可以得到想要的特征向量(特征脸)了。
5)将训练集图像和测试集的图像都投影到这些特征向量上了,再对测试集的每个图像找到训练集中的最近邻或者k近邻啥的,进行分类即可。
算法说明白了都是不明白的,所以还是得去看具体实现。因此,可以对照下面的代码来弄清楚这些步骤。
另外,对于步骤4),涉及到求特征值分解。如果人脸的特征维度d很大,例如256x256的人脸图像,d就是65536了。那么协方差矩阵C的维度就是dxd=65536x65536。对这个大矩阵求解特征值分解是很费力的。那怎么办呢?如果人脸的样本不多,也就是N不大的话,我们可以通过求解C’=ΦTΦ矩阵来获得同样的特征向量。可以看到这个C’=ΦTΦ只有NxN的大小哦。如果N远远小于d的话,那么这个力气就省得很值了。那为什么求解C’=ΦTΦ矩阵的特征向量可以获得C=ΦΦT的特征向量?万众瞩目时刻,数学以完美舞姿登上舞台。证明如下:
其中,ei是C’=ΦTΦ的第i个特征向量,vi是C=ΦΦT的第i个特征向量,由证明可以看到,vi=Φei。所以通过求解C’=ΦTΦ的特征值分解得到ei,再左乘Φ就得到C=ΦΦT的特征向量vi了。也就是我们想要的特征脸。
二、Matlab实现
下面的代码主要是在著名的人脸识别数据库YaleB中进行实现。用的是裁切后的人脸数据库,可以点击CroppedYale下载。共有38个人的人脸,人脸是在不同的光照下采集的,每个人脸图像是32x32个像素。实验在每一个的人脸图像中随机取5个作为训练图像,剩下的作为测试图像。当然了,实际过程中这个过程需要重复多次,然后得到多次准确率的均值和方差才有参考意义,但下面的demo就不做这个处理了。计算相似性用的是欧氏距离,但编程实现的时候为了加速,用的是简化版,至于如何简化的,考验你的时候到了。
% Face recognition using eigenfaces close all, clear, clc; %% 20 random splits num_trainImg = 5; showEigenfaces = true; %% load data disp('loading data...'); dataDir = './CroppedYale'; datafile = 'Yale.mat'; if ~exist(datafile, 'file') readYaleDataset(dataDir, datafile); end load(datafile); %% Five images per class are randomly chosen as the training %% dataset and remaining images are used as the test dataset disp('get training and testing data.
崩溃案例
struct ValTest{ Json::Value bugJson; }; ValTest test; int main(int argc, _TCHAR* argv[]){ test.bugJson["init"] = 123; return 0; } 程序退出时引发崩溃。
解决办法:在构造函数中加入 bugJson["init"] = 123; 内容可以随便写,但是要初始赋值一次
Windows Azure是 微软基于 云计算的 操作系统,现在更名为“Microsoft Azure”,和Azure Services Platform一样,是微软“ 软件和服务”技术的名称。 Windows Azure的主要目标是为开发者提供一个平台,帮助开发可运行在云服务器、数据中心、Web和PC上的应用程序。 云计算的开发者能使用 微软全球 数据中心的储存、计算能力和网络基础服务。Azure服务平台包括了以下主要组件: Windows Azure;Microsoft SQL数据库服务,Microsoft .Net服务;用于分享、储存和同步文件的Live服务;针对商业的Microsoft SharePoint和Microsoft Dynamics CRM服务 [1] 。 Azure是一种灵活和支持互操作的平台,它可以被用来创建云中运行的应用或者通过基于云的特性来加强现有应用。它开放式的架构给开发者提供了Web应用、互联设备的应用、个人电脑、服务器、或者提供最优在线复杂解决方案的选择。 Windows Azure以云技术为核心,提供了软件+服务的计算方法。 它是Azure服务平台的基础。Azure能够将处于云端的开发者个人能力,同 微软全球 数据中心 网络托管的服务,比如存储、计算和 网络基础设施服务,紧密结合起来。 微软会保证Azure服务平台自始至终的开放性和 互操作性。我们确信企业的经营模式和用户从Web获取信息的体验将会因此改变。最重要的是,这些技术将使我们的用户有能力决定,是将 应用程序部署在以 云计算为基础的互联网服务上,还是将其部署在 客户端,或者根据实际需要将二者结合起来。 云计算编辑 时至今日,IT服务已经成为任何商业运作的必备设施。云计算就是要将 IT 服务变得像用电一样简单。企业不需要担心电力来自哪家发电站、电线如何布设。同理,在云计算的 Windows Azure 帮助下,企业不再费心管理每台服务器用什么处理器、装什么操作系统或者数据库 [2] 。 云计算提供商集中管理软件和硬件。使用者能够在任何地方随时调用资源,用完以后及时释放以供再分配,从而避免资源浪费,降低了 IT 运作成本。企业得以将有限的资源和人力用于拓展业务、提升核心竞争力。 根据部署模型的不同,云计算大体可以分为以下三类: 公有云 公有云平台提供商通过互联网将存储、计算、应用等资源作为服务提供给大众市场。企业不需要自己构建数据中心, 只需要根据使用量支付开支。 如果说传统 IT 设施是企业自己给每个部门准备一台发电机、铺电线。公有云就是企业从专业电力公司买电,基础设施的建设和管理完全交给电力公司,企业用多少电付多少钱。能够最高效、最经济地利用资源。 私有云 私有云是每个企业或者组织独立运作的云基础设施。私有云建立初期需要企业投入更多资源,但更适于保存敏感数据。微软提供了完善的私有云解决方案,具体请看这里。 混合云 顾名思义,混合云就是私有云和公有云的组合,同时结合不同解决方案的优势。混合云既能提供公有云的低成本,也能通过私有云满足企业对核心业务极致安全性的需求。 Windows Azure 能够与基于 Windows Server 和 System Center 的私有云解决搭配使用,兼顾企业的具体需求。 服务平台编辑 综述 Windows Azure服务平台现在已经包含如下功能: 网站、虚拟机、云服务、移动应用服务、大数据支持以及媒体功能的支持。 irtual Machines 在Windows Azure上您可以轻松部署并运行 Windows Server 和 Linux 虚拟机。迁移应用程序和基础结构,而无需更改现有代码。支持 Windows Virtual Machines、Linux Virtual Machines、Storage、Virtual Network、 Identity等功能。 Cloud Services 是Windows Azure 中的企业级云平台,使用平台即服务 (PaaS) 环境创建高度可用的且可无限缩放的应用程序和服务。支持多层方案、自动化部署和灵活缩放。支持Cloud Services、SQL Database、Caching、Business Analytics、Service Bus、Identity。 Mobile 服务 是Windows Azure提供的移动应用程序的完整后端解决方案,加速连接的客户端应用程序开发。在几分钟内并入结构化存储、用户身份验证和推送通知。支持SQL Database、Mobile 服务。并可以快速生成Windows Phone、Android或者iOS应用程序项目。 大型数据处理 Windows Azure 提供的海量数据处理能力,可以从数据中获取可执行洞察力,利用完全兼容的企业准备就绪 Hadoop 服务。PaaS 产品/服务提供了简单的管理,并与 Active Directory 和 System Center 集成。支持Hadoop、Business Analytics、Storage、SQL Database、及在线商店 Marketplace。 Media 媒体支持 支持插入、编码、保护、流式处理,可以在云中创建、管理和分发媒体。此 PaaS 产品/服务提供从编码到内容保护再到流式处理和分析支持的所有内容。支持CDN及Storage存储。 益处编辑 Azure服务平台的设计目标是用来帮开发者 更容易地创建web和互联设备的应用程序。它提供了最大限度的灵活性、选择和使用现有技术连接用户和客户的控制。 利于开发者过渡到云计算 世界上数以百万计的开发者使用.
About SQLite
See Also...
FeaturesWhen to use SQLiteFrequently Asked QuestionsWell-known UsersBooks About SQLiteGetting StartedSQL Syntax PragmasSQL functionsDate & time functionsAggregate functionsC/C++ Interface Spec IntroductionList of C-language APIsThe TCL Interface SpecDevelopment TimelineReport a Bug SQLite is an in-process library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. The code for SQLite is in the public domain and is thus free for use for any purpose, commercial or private. SQLite is currently found in more applications than we can count, including several high-profile projects.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="donghua.css"/>
</head>
<body>
<div>动动动!</div>
</body>
</html>
css:
div{
height:100px;
width:100px;
background-color:darkorange;
border-radius:50%;
-webkit-transition: width 2s, height 2s, -webkit-transform 2s;
-moz-transition: width 2s, height 2s, -webkit-transform 2s;
-ms-transition: width 2s, height 2s, -webkit -transform 2s;
-o-transition: width 2s, height 2s, -webkit-transform 2s;
transition : width 2s, height 2s, -webkit-transform 2s;
}
div:hover{
width: 200px;
height:200px;
border-radius:50%;
transform:rotate(360deg);
-webkit-transform:rotate(360deg);
}
安装完python tools for visual studio2010, 安装了.net4.5,导致直接F5可以调试一个子进程, attach to process 无法调试,只需要在attach前手动选择一下调试的类型就可以了
书:Web 性能 权威指南 著Ilya Grigorik
本人旨在自学web性能方面,主要是也看了上面那本书,本人是程序猿一枚看此书只是把重点记录下来,到时候再细研究,
大家一起学习。
一、网络部分
1、延迟与带宽
2、TCP
调整调整TCP初始拥塞窗口大小为10;
禁用空闲后的慢启动;
确保启动窗口缩放;
减少传输冗余数据;
压缩要传输的数据;
把服务器放到离用户近的地方;
尽可能重用已经建立的TCP连接。
3、UDP
与TCP不同的协议,该协议主要是传输速度快,该协议省略了连接状态、握手、重发、重组、重排、拥塞控制、拥塞预防、流量控制、错误检测等。
说了这么多,就是可以理解,只有源地址、目标地址、验证串码和元数据。
因此它简单又快,但是就没有相应的功能。
建议在局域网中使用,或是需要针对没有的功能再开发,具体咋弄就不知道,到时候再研究。、
4、TLS传输层安全
还有SSL等都是加密验证、然后再解密取数据,这中间就多了很多交互过程,也是影响性能一个因素。
性能检查清单
4.1 tls库升级到最新版本,并在此基础构建服务器;
4.2 ssl2.0 会话缓存默认是关闭的,启用并配置缓存大小及会话超时时间;
4.3在接近用户的地方完成tls会话,减少往返的延迟;
4.4配置tls记录的大小,使其恰好能封装在一个tcp段中;
4.5 确保证书链不会超过拥塞窗口的大小;比如,证书链的长度是5K,拥塞窗口大小是60K就没有问题,如果证书链是100K的话,需要多一次往返;
4.6从信任链中去掉不必要的证书,减少链条层次;无用的证书链会加大客户端和服务器的验证时间;
4.7禁用服务器tls的压缩功能,tls压缩会暴漏严重的安全漏洞,而且一般数据都是已经压缩过的,类似于zip压缩后再压缩提升的不明显;
4.8启用服务器对SNI的支持;
4.9启用服务器的OCSP(在线证书状态协议)封套的功能,客户端需要检查证书的有效性,部分浏览器支持,该检查的操作有服务器执行,浏览器跳过在线查询;
4.10追加对HTTP严格传输安全首部。
......中间扒拉一堆移动网络解释,已经完全超出我的理解。过。
10、Web性能要点
延迟、带宽、计算机性能,这些对于Web性能确实有一定的影响,但是相对而言不是主要因素,忽略。
10.1针对浏览器优化的建议
10.1.1基于文档的优化,尽量先加载页面,先保证交互产生;
10.1.2推测性优化,预先解析DNS、预先连接可能的目标。UC浏览器中百度分页下一页就有这功能,不知道是不是一个意思。
10.1.3资源欲取和有限次序
10.1.4DNS预解析
10.1.5TCP欲连接,就是根据10.1.2的需求,将TCP连接欲打开;
10.1.6页面欲渲染某些浏览器,在10.1.2中,在隐藏的标签页中预先渲染整个页面。
11、HTTP1.X
11.0网络优化
11.0.2减少DNS查询
11.0.3减少HTTP请求
11.0.4使用CDN,离用户近的地方
11.0.5添加Expires首部并配置ETag标签
11.0.6Gzip资源,所有文本资源都应该使用Gzip压缩
11.0.7避免HTTP重定向,尤其是一个完全不同的域名会更耗时间
11.1持久化连接
假设页面只有一个html一个css文件,如果不使用持久化连接的话,就需要加载html时,客户端和服务器做一个TCP连接的三次握手,css做一次,然后再传输数据。
如果有TCP连接,就会节省一套握手操作,节约的额时间(N-1)*每次TCP连接的三次握手时间,这种规模在大型网站上相当的明显。
11.2HTTP管道
顾名思义,就是管道越大,一次性传输的东西就越多。但是由于管道的技术有限,应用需要把中断的连接进行重新处理,非常麻烦,目前不建议采用,等HTTP2.0的时候再说吧,但是肯定的是它也是优化的另一个方法,apple itunes就是鲜明的例子。
11.3使用TCP多个连接
HTTP1.X不支持“多路复用”,这个是啥意思?浏览器通过并行打开多个TCP连接,最多6个。
11.4域名分区shar1.example.com shar2.example.com
原理类似于集群,假如一个页面需要加载多个资源,这些资源都指定到一个机器方面,还是将资源分散到若干的服务器上同时加载快,很显然吧,但是肯定会有个临界点。
2015-04-17 东方云洞察 点击上面的链接文字,可以快速关注“东方云洞察”公众号
混合型IT——此类系统指一部分由内部环境组成、另一部分则由公有云构成——堪称通往云时代的一条捷径,但却远算不上发展的终点,Amazon公司CTO Werner Vogels在昨天于伦敦召开的AWS峰会上向三场的三千名与会者强调称。
“我们已经建立起一整套服务集合,允许大家以无缝化方式将服务同时运行在内部环境与云环境之下,”Vogels指出。
“不过,大家必须意识到在我们看来,混合型IT并不是发展的终极目标……随着时间的推移,数据中心基础设施的总体数量将变得越来越少。混合型IT其实是一条通往更高程度云技术使用比例的道路。而大家所使用的应用程序及服务将越来越多地迁移到AWS环境当中。”
一般来讲,向云环境的拓展主要是为了获取更为突出的可扩展能力、有时候也被称为“云膨胀”,或者是为了实现更理想的弹性效果。
更进一步讲,由云供应商打造的服务涵盖范围也在不断增长。相比之下,交付成本更高而且交付速度较慢的内部解决方案越来越难以跟上云服务的快速发展脚步。
有鉴于此,企业客户完全有理由将新型应用程序部署在云环境当中,同时将现有应用继续运行在内部体系当中。
内部基础设施方案很难与AWS丰富的服务涵盖范畴相抗衡
“我们拥有来自各个行业且已经决定将业务全部交由云环境打理的客户群体,”Vogels进一步补充称,他同时提到除了已经采取了这种“全面云化”战略的长期AWS支持者Netflix公司之外,其它代表性客户还包括Intuit(金融软件)、Splunk(分析解决方案)以及Tibco(商务智能)等企业。
安全性……不是问题!
与此同时,Vogels强调称,云安全并不会构成什么严重问题。“云环境下的安全性水平要比我们当前任何客户能够在内部设置中构建起的安全机制高得多。AWS是大家存储数据的最佳环境,而且允许各位客户对数据访问的具体对象进行全方位控制。”
他给出的支持论据包括小型企业根本不可能拥有的深层安全专业知识储备、多种多样的加密及密钥管理工具以及一系列来自包括欧盟在内的各认证组织的肯定结果。
相较于采取其它云服务供应商的产品、特别是微软,在利用云服务方案实现混合型IT领域,AWS与其它云服务供应商有所不同,特别是微软公司——之所以要强调微软,是因为他们的原有内部系统拥有广泛的普及程度、而且能够为合作伙伴提供全面的技术支持与维护服务。
微软推动其Azure云拓宽市场份额的一大重要举措,在于允许客户将Azure Pack安装在内部系统当中并通过自己的原有系统实现云计算类方案天然具备的诸多优势。
从另一方面讲,AWS并不提供任何私有云产品,而且其旗下所谓“Amazon虚拟私有云”实际上也同样运行在该公司的公有云基础设施当中。
将全部注意力集中在公有云领域的指导思想让Amazon公司能够在其服务背后的深层技术领域实现更为积极甚至激进的创新步调。举例来说,目前正处于预览阶段的Aurora数据库服务在设计思路上专门针对大规模分布式基础设施进行了优化。事实上,如果没有像Amazon这样规模可观的基础设施积累,我们根本无法对这类分布式设施进行数据复制。
不过,虽然我们有诸多令人信服的理由来选择使用公有云,但同样有一些负面因素需要认真考量。而且就目前而言,选择“全面云化”的大型企业在数量上看还非常有限。
然而AWS正在快速发展壮大——就S3存储与EC2计算服务而言,其使用量与上年相比均出现了100%增幅,Vegels表示,这意味着现在正有越来越多IT系统开始将其作为自己的运行基础。
随着AWS的不断扩展,AWS在遭遇意外状况后很可能引发全球范围内的服务停机或者带来其它影响范围更广的后续问题。不过这种情况永远不会发生,对吧?
扫描二维码关注【东方云洞察】公众号
实时了解深度的公有云市场分析和洞察结果!点击右上角,在弹出的菜单中发送给朋友、分享到朋友圈。请在公众号搜索并关注:DongCloudInsight 或 东方云洞察。需要点对点交流请加微信:jackyzhang523
帮助您了解公有云相关的深度洞察结果。带来极具深度和最新鲜的:云市场分析、云机会洞察分析、云重大事件快评、云杂谈、云论坛资讯,以及公有云领域最高端的CEO面对面深度研讨。
--- 最专注、专业的“公有云洞察”分享;关注全球,聚焦中国。
1、修改PI账号的密码
password pi 2、开启root账号 树莓派使用的linux是debian系统,所以树莓派启用root和debian是相同的。
debian里root账户默认没有密码,但账户锁定。
当需要root权限时,由默认账户经由sudo执行,Raspberry pi 系统中的Raspbian
默认用户是pi 密码为raspberry
重新开启root账号,可由pi用户登录后,在命令行下执行
sudo passwd root执行此命令后系统会提示输入两遍的root密码,输入你想设的密码即可,然后在执行 sudo passwd --unlock root这样就可以解锁root账户了。
题目介绍: r语言课程的第一个程序作业。将要编写3个函数。实验数据为“美国大气污染”的数据,可以从Coursera上下载,下载后的文件为zip文件。需要自行解压缩并添加到你的作业项目中。
数据介绍: zip文件可以从这里下载: specdata.zip [2.4MB] 这个zip文件中包含了332个csv文件。csv文件中记录着检测大气质量的数据,记录着美国332个地区的“细微颗粒值(PM值)”。每个csv文件中代表着一个监测地区的记录。例如:地区200的大气数据,记录在文件“200.csv”中。每个文件包含三个变量: -Date:date的数据以“YYYY-MM-DD”的方式存储 -sulfate:空气中硫化物颗粒水平 -nitrate:空气中硝化物颗粒水平 本作业中,你需要解压缩这个zip文件,并保存在目录名为“specdata”的文件夹下。你可以打开csv文件观察数据,你会发现里面包含着很多空值,这在空气质量监控的数据集中非常常见。
Part1 第一部分功能介绍: 编写一个函数“pollutantmean”能够计算指定文件列表中所有大气数据的污染物(sulfate或者nitrate)的均值。这个函数有三个属性,分别是’directory’、’pollutant’和’id’。’directory’代表文件目录,’pollutant’代表污染物的名称,’id’代表文件序列,是一个数值向量。注意,在数据处理中,你需要去掉空值。
第一部分程序实现: pollutantmean <- function(directory, pollutant, id = 1:332) { filenames<-dir(directory, full.names=T) n<-length(id) m<-rep(0,n) ct<-rep(0,n) for(i in id){ data<-read.csv(filenames[i],header=TRUE) ct[match(i,id)]<-sum(!is.na(data[pollutant])) m[match(i,id)]<-mean(as.matrix(data[pollutant]),na.rm=TRUE) } result<-(m[ct>0] %*% ct[ct>0])[1,1]/sum(ct[ct>0]) result } 第一部分程序运行结果: > source("pollutantmean.R") > pollutantmean("specdata", "sulfate", 1:10) [1] 4.064128 > pollutantmean("specdata", "nitrate", 70:72) [1] 1.706047 > pollutantmean("specdata", "nitrate", 23) [1] 1.280833 Part2 第二部分功能介绍: 编写一个函数“complete”读取文件目录下的所有文件,计算每个csv文件中完整的记录数(每条记录都不包含空值)。函数需要返回一个dataframe,第一列为文件id,第二列为记录数nobs。
第二部分程序实现: complete <- function(directory, id = 1:332) { files_list <- dir(directory, full.
第一种方法:在左侧点击右键,选择“show line numbers”。 第二种方法:Ctrl+F10,打开视图菜单,选择“show line numbers”。
第三种方法: windows->Preferences->General->Editors->Text Editors ->show line numbers。
本文乃Siliphen原创,转载请注明出处:http://blog.csdn.net/stevenkylelee 本文针对的是cocos2d-x 3.4 版本进行研究。
做加密解密的思路 加密解密算法的简单介绍 首先,加密解密应该是一个单独的话题,一般不会涉及具体使用的引擎、框架和技术。
加密算法有Base64,DES等。
Base64的原理类似于凯撒密码,啥是凯撒密码呢,就是一个字符用另一个字符来代替。
比如:a用i代替,b用k代替,以此类推。加密和解密的过程就是一个互相映射的过程。
DES是一种使用密钥的加密算法。
DES和Base64这种无密钥的算法在使用上的区别是:
DES算法本身是可以不保密的,只要保密密钥即可,密钥才是解密的关键。
Base64如果用于加密的话,算法本身就是密钥。要保密算法。
MD5,SHA等是摘要算法。
Base64,DES都可以把密文还原出明文。
而MD5,SHA则不能对算法作用后的输出还原出原始数据。
摘要算法一般做身份验证。
我们做资源加密是要选择能把密文还原出明文的算法。
设计自己的加密解密算法 这属于密码学的内容了,可深可浅。
可以借鉴凯撒密码的原理自己对每个字节的内容进行映射来加密。
也可以对1字节,2字节,4字节的数据,用某个数进行异或运算来加密。
异或的特性是,用数A对内容B进行异或得到内容C,再用数A对内容C异或可以得到内容B。
这个特性可以被用来加密。同时,数A的作用就是密钥了。
设计的加密算法不同,加密算法的使用的接口也不同。
如果是用上面的2种思路做加密算法的话,加密算法的实现可以“in place”操作,
就是可以直接在密文所在的内存进行解密,不单独分配内存来保存解密后的数据。
如果加密算法很复杂,无法“就地还原”,就需要新申请内存来保存解密数据。
当然,执行速度一般是”就地还原“快。
我觉得,如果可以的话,最好是自己设计加密算法。
使用现成的DES之类的算法,密钥是关键。
如果是自己设计一个用密钥加密的算法,密钥和算法本身都是不公开的。
破解者要获取资源明文要经过如下步骤:
1.在程序中找到密钥的常量。
2.看懂反出来的汇编还原出算法,或者想办法利用加密算法的汇编代码。
其中步骤2会加大解密者解密的难度,这是自己设计加密算法比用现成的DES之类著名算法的好处。
加密解密的运用机制 我见过有一些人加密是对字段内容进行加密。
比如,他用xml保存数据,他只对保存的值进行加密。
内容类似这样 <Entity Hp = "密文" AttackValue = "密文" >
这并不是一种好的运用加密的方式,因为这种方式会:
1.透露程序的配置文件结构。XML、json等。
2.透露了程序可能使用的数据结构。看以上内容可猜想Entity实体类有2个字段,Hp(血量),AttackValue(攻击力)
更彻底的加密方式是,对整个xml、json等文件进行加密。
这样别人就不会知道关于你的数据的一丁点信息。
这种做法不是直接用数据解析库封装的类似LoadFile的函数直接读取文件。
而是,先把加密文件用文件读取方法读入内存,在内存解密后,再把解密数据传给解析库的解析函数。
这种做法要求解析库有对内存进行解析的接口。
比如,若用XML解析库,就会弃用LoadFile,要求有Parse方法。
有一种情况可能无法对整个数据文件进行加密。
就是使用sqlite等数据库的时候,这时候只能对字段进行加密了。
有些人设计加密机制会要求配置程序本身。
比如:程序需要一个配置(一个开关变量或者条件编译)来决定是否对资源进行解密。
发布时,把资源都加密好,开启程序对资源的解密。
开发时,资源不必加密,屏蔽程序对资源的解密。
这种做法需要来回设置解密开关,比较繁琐。
有一种实现思路更有扩展性、更灵活、使用更方便。
那就是自己设计文件头。
熟悉Win32编程的人可能会知道PE文件格式。
设计模式是每个程序员的必修课,这里将23种模式整理在一起,想学习这方面知识的朋友们有福了,呵呵。
Singleton Pattern(单例模式):Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)
Factory Pattern(工厂方法模式):Define an interface for creating an object,
but let subclass decide which class to instantiate.Factory Method lets a class defer instantiation to subclass.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延迟到其子类。)
Abstract Factory Pattern(抽象工厂模式):Provide an interface for creating families of related or dependent objects without specifying their concrete classes.(为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。)
Template Method Pattern(模板方法模式):Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.
网页网址
AnkhSVN是集成到Visual Studio里面的一个SVN插件。使用起来很直观,有SVN使用经验的人,基本上就是安装后就可以直接使用了。 在Visual Studio里面集成SVN插件,比在windows资源管理器里面使用SVN,有一些方便的地方。比如:
1。重命名。不使用插件,重命名之后,旧文件会显示为missing,而新文件要手动添加到SVN,容易遗漏。使用插件,插件会自动将文件标示为rename。
2。新增、删除文件。不使用插件,新增文件要手动添加,删除文件会显示为missing,跟上一条一样的容易产生漏签的问题。使用插件就都会自动的将文件标记为Added或者Deleted。
在AnkhSVN中使用Beyond Compare:
AnkhSVN自带的比较工具,功能有限。如果机器中安装了Beyond Compare,就可以直接在菜单项里面进行设置,即可使用。方法如下:
Visual Studio——工具——选项——Source Control——Subversion User Tools,在External Diff Tool下拉菜单里面选择Beyond Compare,在External Merge Tool下拉菜单里面选择Beyond Compare 2-Way或者3-Way。
很多客户经常问我:小钟,你们的WiFi会出现很多的WiFi名称吗?例如XX酒店WiFi 1、XX酒店WiFi 2,这样的情况会有吗?很多工程商客户之前都做过WiFi覆盖的,会有这样的困惑——WiFi不能自动切换,例如在酒店的大厅连接了WiFi了,不过走到客房里面之后,大厅的WiFi没有信号了,要自己手动去连接上另外一个WiFi,而且又要手动去输入一次密码,又要等,这样是不是比较麻烦,经常给客户投诉? 小钟在这里很诚实的告诉大家:我们的WiFi名称只会出现一个,而且无论你走到哪里,只要是我们WiFi设备发出来的信号,都不会断,全程都会自动连接WiFi, 比如一家酒店用的是我们的WiFi产品去做WiFi覆盖的,你在酒店的大厅输入了WiFi密码,连接WiFi后,无论你走到哪里,只要有我们WiFi设备发出来的信号,它们都可以自己连上WiFi,不自己手动去连接和再输入一次WiFi密码,我们叫这个功能是——WiFi 无缝漫游。 (示意图) 无线AP配置规划(无线设备在多个AP间自动无线漫游) 无线漫游中无线AP的配置与普通无线AP的配置基本相同,只是应当注意以下几个方面的问题: 所有无线AP必须使用同一SSID。 所有无线AP必须使用同一网段的IP地址,并且处于同一VLAN中。 信号相互覆盖的无线AP不能使用相同的频道。 由于多个AP信号覆盖区域相互交叉重叠,因此,各个AP覆盖区域所占频道之间必须遵守一定的规范,邻近的相同频道之间不能相互覆盖,也就是说,相互覆盖区域的无线AP不能采用同一频道,否则,会造成AP在信号传输时的相互干扰,从而降低AP的工作效率。在可用的11个频道中,仅有3个频道是完全不覆盖的,他们分别是频道1、频道6和频道11,利用这些频道作为多蜂窝覆盖是最合适的。另外,用于实现无线漫游网络的无线AP必须使用同一网络名称(SSID),使用同一网段的IP地址,否则,无线客户端将无法实现漫游功能。 无线漫游网络中,客户端的配置与接入点网络中的配置完全相同。用户在移动过程中,根本感觉不到无线AP间进行切换。 在搭建无线漫游网络时,需要注意以下几点: 1:AP信号覆盖区域应当相互交叉重叠,否则,会导致无线网络盲区。也就是说,无线AP之间的距离,应当小于无线AP的有限传输距离。 相互覆盖的无线AP必须采用不同的、甚至是不相邻频道,否则,将导致严重干扰,降低AP通信效率。信道就是之频段,IEEE 802.11b/g是工作在2400~2 483MHz,美国标准信道(channel)可以划分11个,欧洲标准可以划分13个,日本标准可以划分14个,每个channel之间相差11MHz。如channel1为2 412MHz,channel2为2 423MHz,依此类推。事实上,只有1、6、11信道之间是完全没有干扰的。 2:无线AP必须设置为相同的SSID。不同的SSID意味着不同的无线网络,而无法实现无线漫游。需要注意的是,SSID区分大小写。 必须采用相同的WEP或WPA加密。所有无线AP和客户端必须采用相同的WEP或WPA加密,否则,将无法建立彼此之间的连接。WEP和WPA也是区分大小写的。 3:无线AP与无线客户端必须处于同一VLAN、同一IP地址段。
更新时间:2002-1-1 0:00:00字数:788
我们刚开始计划写这本书,就明白我们将需要很多帮助,因为男人知道的事情虽然千差万别,他们却很少精确地了解什么。这正是写这本书的初衷:我们想精确地了解一切。因此我们同专家们交谈,同飞行员厨师意大利人足球运动员匠人挖土机司机和医生,同无数拥有特殊知识的专业人员交谈。这些专家有些是知名人物,甚至因他们的知识而大名鼎鼎,但大多数都是掌握了很多知识的无名之辈。
最难做的是筛选。今天的男人应该知道什么呢?原则上当然是:一切。但可以约略了解已知世界知识的时代已经过去数百年了。相比起世界知识,人类几乎一无所知,也有一些基本的东西失落在了时间的长河里。在有关大众教育方面,区分男女将是极其沙文主义的。如何用剃刀刮胡子,在购买一套西服或一辆阿斯顿?马丁车时应该注意什么,如何参加外籍军团,如何防止脱发,如何成为罗马教皇系领带或在没有开瓶器的情况下开啤酒。是否知道这些对大多数妇女来说并不重要,这些事情多是男人们才会感兴趣。
当本书渐渐成形时,不断有朋友送来许多提示:你们必须收进这个,绝不可以遗漏那个。这些提示有很多特别有用,吸引我们进行重新调查。有时出现有关高度文明歌剧剧场芭蕾或绘画的问题,我们并不赞成:首先,这不是典型的男人话题,而是男女都感兴趣的话题;其次,薄薄几页纸不可能展示这些世界。对绘画感兴趣的,至少必须再买一本书。反过来,如何降落一辆波音747飞机则可以在几页纸上解释。向我们透露如何做飞行员,祝所有读者在陷进这种必须降落一架飞机的棘手处境时比较走运。
本书里当然不包含男人必须知道的一切,但书里现有的内容兼顾了各种男人:猎人和收藏家,高尚人士,麻烦青少年,帮忙者和善于倾听的人,英勇无畏的人,安静和谦虚的人,吵吵嚷嚷的人,生性羞怯的人,清教徒和飞黄腾达者,犹豫不决者,特别懒惰的家伙,思想家,冒险家,甚至绅士们。
爱德华?奥古斯丁,菲利普?封?凯森贝格和克里斯蒂安?扎什克
男人在家里
更新时间:2002-1-1 0:00:00字数:17210
家庭酒吧
如果您组建一个小巧精致的家庭酒吧,您就可以在家里随时调制出几种令人满意的酒来。可是,请您切记:别在家里调制鸡尾酒。首先因为那样一来您就很少有时间陪伴客人;其次是您必须拥有大量存货;第三,如果您想像样地调制鸡尾酒,恐怕不到二巡您的冰块就用光了。因此,您要是哪天对鸡尾酒来了兴趣,那您就去鸡尾酒酒吧好了,这对所有的人都是最佳选择。但是,如果您有一个合理配置的家庭酒吧,您就能够提供足够多的饮料,保证您和您的客人至少这个晚上不会缺少鸡尾酒。
扔掉老酒较老一代的小酒橱里大多摆放着阿斯巴赫乌尔特(Asbach Uralt),玛雅龙(Mariacron),一瓶瓶子有点黏乎乎的黑加仑利口酒(Cassis),一种同样有点黏滋滋的百利甜(Bailey),还有旅游带回的Grappa(意式或法式葡萄渣白兰地),一瓶樱桃白兰地(Kirsch)和梨子白兰地(Williams Birne)。可它们大多派不上用场,如果您拥有这种“弹药库”,请您只留下自己真正喜欢喝的,将其余的统统清理掉。重新精选一批好酒并没有多贵。
基本配备您需要准备几种基本的烈性酒:伏特加杜松子酒威士忌(波本威士忌和苏格兰威士忌)朗姆酒和白兰地。一定要记住这条原则:别选最便宜的。比如,伏特加要选苏联红牌(Stolychnaja)的,杜松子酒要选添加利牌(Tangueray)的,波本酒要选威凤(Wild Turkey)或梅克斯马克(Maker’s Mark)牌的,苏格兰威士忌选12年陈酿的,朗姆酒选哈瓦纳俱乐部(Havana Club),白兰地至少要选卡洛斯一世(Carlos I.),选红衣主教(Cardenal Mendoza)就更好了。其他品牌的当然也可以使用,只要它们具备同等或更好的质量。而一瓶金巴利(Campari)和苦艾酒(Vermouth)很般配,一瓶马天尼白(Martini Bianco),一瓶马天尼红(Martini Rosso)或干苦艾酒。有了这些您就能调配出很多酒类饮料了。
冰箱里的配备您应该补充您的冰箱。您需要冰块,而且不止需要买冰箱时赠送的小杯子那样的一小杯。任何情况下您冰箱里都应该放有一瓶香槟,还要有红葡萄酒和干雪利(Dry Sherry)酒,虽然雪利酒大多数时可以常温保存,但最好放进冰箱里。此外还要准备橙汁苦柠檬奎宁水(Tonic Water)姜汁啤酒(Ginger Ale)矿泉水或苏打水及柠檬和橙子各两个。这样您的装备就齐全了,例如,您可以用冰过的杯子向客人提供马天尼(Martini auf Eis)当开胃酒,当然还有金汤尼水(Gin Tonic)柠檬伏特加(Wodka Lemon)橙汁金巴利(Campari Orange)和自由古巴(Cuba Libre,朗姆酒加可乐调制)这几种长饮,也有大杯波旁威士忌(Bourbon Highball)或莫斯科佬(Moscow Mule)(两者都使用姜汁啤酒,后者加了伏特加),一种威士忌苏打(Whisky Soda),一种事先冰过杯子的苏格兰威士忌(Scotch auf Eis),一种餐后喝咖啡时喝的白兰地,等等。
杯子现在剩下的重要事情是:您需要杯子,而且是长饮杯子,威士忌平底无脚酒杯(如果您提供Malt威士忌,也许使用突沿杯),高脚香槟杯,干邑大腹杯和葡萄酒杯(参见《社交中的男人》一章中“开葡萄酒瓶”一节)。这些杯子真的很重要,您总不至于用水杯喝这些饮料吧。另外您可以添置一只冰桶和一把冰夹,而一辆餐饮车就让这一切完美无缺了。这符合您的家庭酒吧的条件,您可以将它推到现场。下层放酒瓶,上层供您调酒,同时您又能与客人们待在一起。不过,也有男人不喜欢在住房里放一辆餐饮车,这种情况下建议您花钱买一张餐橱或吧柜。家庭酒吧成本有限,有了它您就永远不会陷入不能提供合适饮料或找不到合您口味的饮料的尴尬。
男人必须会调的一种鸡尾酒
鸡尾酒鸡尾酒酒吧和有关鸡尾酒的图书有数百万册,但男人真正必须了解和会调的鸡尾酒只有一种马天尼鸡尾酒,其中又以干马天尼(Dry Martini)最为有名(请不要将它同意大利马天尼和罗西公司的苦艾酒搞混了,它们同样叫做马天尼)。考虑到凤梨园(Pina Colada,用菠萝汁椰子汁和朗姆酒调制的饮料)和草莓戴奎利斯(Daiquiris,朗姆酒加柠檬汁等调出的鸡尾酒),如果您在一家酒吧里不知道该叫或想叫哪种鸡尾酒的话,选一杯马天尼鸡尾酒总是不会错的(这是上一节所介绍规则的唯一例外,可以在家里调制它)。这种马天尼鸡尾酒具备了一切,它简单高雅度数高,它的爱好者对如何调制研究很深。它仅由三种配料调配而成,每一种都不存在剂量问题,这一点可能特别令人吃惊。这三种配料是:杜松子酒干苦艾酒和一种有核绿橄榄。美国的传统方式是将杜松子酒和苦艾酒按5 :1的比例来调配,世界各地的比例介于2 :1和15 :1之间,另外还有一些特殊形式。
光影往杜松子酒里掺进的苦艾酒越少,马天尼就越干。因此,一些清教徒们说,一杯上好的马天尼鸡尾酒可以用放在苦艾酒旁的一瓶杜松子酒来调制。另一些清教徒说,如果透过一瓶苦艾酒照射的阳光在杜松子酒里留下光影,这就是好马天尼。另一些人又主张,在倒杜松子酒时将瓶口侧向法国方向,心里想着苦艾酒就够了。因为通常使用的干苦艾酒诺丽普拉(Noilly Prat)产自法国,但这么说的都是清教徒。
方法一值得推荐的有两种方法。两种方法都需要一只调酒杯一个隔冰器一只马天尼杯子一把搅拌长匙和许多冰块。第一种方法,将5厘升的杜松子酒和0.5厘升的苦艾酒倒在调酒杯里的冰上。注意:请使用不滴水的硬冰块。最好的冰块来自冰箱的冰格里,它们大多比制冰机制造的冰更合适。请您预先用冰块冷却马天尼酒杯,杯子必须真正是冰的才行。鸡尾酒端上去时必须没有冰,因此,斟酒前必须一点不剩地从马天尼杯子里去掉冰块。现在请将杜松子酒和苦艾酒透过隔冰器倒进马天尼酒杯(专用术语:滤净),加进橄榄,这样就大功告成了。有些酒吧侍者发明出了某种技能,他们不用隔冰器过滤酒,而是用搅拌长匙挡住冰块。
方法二第二种方法更具有清教徒特点。请用冰块冰镇马天尼杯子,直到杯子变得冰凉;然后将冰块全部倒掉,往杯子里倒点苦艾酒;接下来是一场小小的仪式:倾斜杯子,转动杯脚,直到苦艾酒将整个内侧荡一遍,像一层膜覆盖在杯子里;随后倒掉酒,因此苦艾酒只是润湿了杯子。请将不滴水的硬冰块和5厘升的杜松子酒放进调酒杯,小心搅拌。随后将杜松子酒过滤进被润湿的马天尼酒杯,放进橄榄。
签名虽然这种鸡尾酒的调制听起来很简单,可当您叫这种鸡尾酒时,每个优秀的酒吧侍者都会视之为挑战。您要这种酒是在发出信号,表明您是当真的,您甚至有可能对酒很精通。有些酒吧侍者视马天尼鸡尾酒为他们的签名,类似于厨师对调味汁的态度。如果酒吧侍者将一颗包有东西的(也就是不带核的)橄榄放进杯子,他虽然是个可爱的家伙,但不是一名优秀的酒吧侍者。如果您的马天尼鸡尾酒杯里还浮有冰块,他也不是一名优秀的酒吧侍者。简单地说,这种饮料只由烈性酒组成,将它变成美味的混合饮料,这是一种艺术。您也许需要多试几次,直到它变得真正好喝,也许那将是一项永恒的任务,但没有比这更适合男人的鸡尾酒了。大概也没有比这更好的了,当然这只是个人口味的问题。
搅拌,不是摇晃如果您在喝马天尼鸡尾酒时想到了詹姆斯?邦德,那您就错了,但并非错得离谱。邦德喝一种被他叫作“干马天尼”的饮料,但它同马天尼鸡尾酒没有多少共同处。邦德在弗莱明的小说《皇家赌场》里发明了这种饮料,它的配制让人感觉有点奇怪(“一杯干马天尼,”他说道,“一杯,用高脚香槟杯装。”“噢,先生。”“等一下。三份歌顿杜松子酒(Gordon’s),一份伏特加(Vodka),半份基纳利口酒(Kina Lilltet),彻底摇匀,直到冰凉,然后再搁一大片柠檬皮。明白了吗?”)
作家金斯利?阿米斯估计,他的同事弗莱明在调配让他的主角喝的饮料时可能将细节搞错了一点。可是,这种有些怪异的配方或许正是弗莱明的目的,因为书中的邦德不同于以前电影中的邦德不是个有教养的绅士,而首先是个杀手。当然,人们喝的马天尼从来不像邦德喝的那样不是摇晃的,而是搅拌的。
在家里酿造爽口的啤酒
啤酒在男人的生活中扮演着十分重要的角色。有些女人抱怨,她们对一个男人的意义永远比不上啤酒对他的意义。当然,不是所有的男人都这样迷恋啤酒,有些男人甚至厌恶啤酒。但几乎每个男人都会认识很多这样的男人,啤酒在他们的生活中扮演着重要角色。您应该在冰箱里放上一两瓶,要么去商店里买啤酒,要么自己动手酿造。只需要一些配料,几样配件和些许耐心,您就能在家里成功酿制爽口的啤酒。
10升啤酒的配料2公斤麦芽(50小麦,50大麦),50克啤酒花(丸状啤酒花),20毫升啤酒酵母。这些配料啤酒厂(最好是去一家小厂试试)或网络商人那里有卖。
配件1只锅(15至20升),1只桶(15至20升),1把烹饪木勺,1条枕罩或1块麻布,1只温度计(密封温度计,0至100度),1根塑料管(2米长,直径10毫米),1个啤酒锤,1个标准缸(同啤酒锤配套),1只研磨机(咖啡或粮食研磨机),1箱带瓶塞的啤酒瓶,1种清洁剂(比如AetzNatron),0.5的过氧化氢溶液。
啤酒锤在啤酒厂或互联网上都有。奇怪的是有几家意大利高速公路休息站提供啤酒锤,多作为一套小型而简易的酿酒工具的配件。姑且试一试开车前往意大利,购买一只啤酒锤(尤其对于住在易北河以北的人们)。知道有一些意大利的高速公路休息站出售如此有用的东西,是很开心的事。
准备工作酿酒前先洗净所有容器。用AetzNatron(某种清洁剂)配制1的溶液,用来洗涤瓶子和桶;随后彻底冲干净,再用0.5的过氧化氢消毒;然后将枕套(或麻布)煮沸消毒。
酿造在研磨机里研碎麦芽,不要太精,不要磨成精面粉,壳子(谷子的皮)应该还留在上面。将6升水加热到45度,边搅拌边加进粗磨的谷粒。随时检查温度,介于42度52度之间。边搅拌边加热到52度,在刚好52度时保持5分钟(这很重要!不要高也不要低);加热到62度,在刚好62度时保持30分钟;加热到72度,在刚好72度时保持20分钟,同时将枕套绷在桶上;将锅加热到正好78度,将锅中物透过枕套倒进桶里(之后的糊状物一定要留在枕套里。这就是所谓的渣滓)。往锅里倒进4.5升水,加热到78度,将加热过的水通过枕套里的渣滓倒进桶里;在桶上绞干枕套,将液体(早期麦芽汁)从桶里倒回锅里烹煮,10分钟后加入25克啤酒花,再继续煮60分钟。
中间步骤:现在提取一份样本,倒进标准缸。将啤酒锤慢慢插进缸里。现在可以从锤上读取含糖度(原麦汁度)。如果它在12度左右,可以加入剩下的啤酒花;如果它低于12度,则再煮10分钟,然后重新测量;如果测量结果高于12度,表明没有问题,可以添加啤酒花。
让锅散热,用勺搅拌,放置10分钟后通过橡胶管将液体从锅里倒进桶里。必须让橡胶软管抽吸,但要小心:液体是热的!另一种选择,也可以透过枕套加入液体,但必须事先将枕套煮沸消毒。无论如何,重要的是让液体得到过滤。将桶放进一只盛满冰块的浴缸里,等温度达到20度后添加酵母。在20度时泡36小时,然后提取样本,倒进标准缸,放入啤酒锤。如果啤酒锤显示的是3至4度:通过管子将液体装瓶。如果啤酒锤显示4度以上:将液体放在那里,直至啤酒锤测量值变成3至4度,然后再装瓶。不要太早装瓶,将密封的瓶子在20度的环境下存放三至四天,再将瓶子放进冰箱里两周,啤酒就酿成了。味道好香,令人吃惊。干杯!
烧烤智利方法
要让烧烤的炭火尽快达到可以先后将烤架和肉放上去的程度,有许多耗时费力和不健康的方法。扇子电吹风酒精烧烤点火装置,全都没用。一段时间以来,烧烤专业商店里就出售各种点火炉,它们能做出惊人的事情,让炭火几分钟内就达到可以烧烤的程度。智利方法采用的是相同的原则,但它只需要一些废纸和一只啤酒瓶或葡萄酒瓶。
塔楼和金字塔请您将瓶子放在您的烤架底部的中间位置。请取一令报纸,竖着卷成卷,将纸卷捻上一两次,抓住纸卷两端,分别向反方向转动;然后将纸卷套在瓶子上,将木炭或蜂窝煤堆在瓶子周围,直到形成一座“金字塔”。现在请您小心取出瓶子不要碰倒“金字塔”,然后给就此形成的壁炉生火,将一根大火柴一片纸或一个纸卷扔进敞开的井状空间里就够了。数分钟后炭就会很热,火势很快会弥漫开来。
像艾卡特?维茨格曼一样煎肉排
艾卡特?维茨格曼是全球最优秀的厨师之一。他是如此优秀,当别人向他提出如何做一块肉排这样普通的问题时,他一点儿也不气恼,而是说:“呃,一块肉排,很好。然后我们再烤点土豆怎么样?”他非常喜欢普通菜肴,真叫人吃惊。维茨格曼是被《米其林指南》评为三星的首位德国厨师,高勒?米罗将他选为年度厨师包括法国人在内,另外全世界只有三名厨师拥有这个头衔。“一个男人也许还应该知道如何炒菠菜,”他说道,“荷包蛋怎么样?而真正必须会做的,是一份漂亮的生菜。”这种大师级的厨师很可能不知道如何回答有关普通菜肴的问题,他会觉得它们有辱一名顶级厨师的尊严。可艾卡特?维茨格曼兴致勃勃地说:“我们这就开始吧。”
平底锅煎肉排您要极早从冰箱里取出切好的里脊肉排,因为必须让它在煎之前达到室温。如果它是湿的,请拿厨房用纸将水擦干净。应该挑选您用得最顺手的平底锅,一只结实的平底铁锅无论如何是没错的。烧热平底锅千万不要盖上用猛火短暂地(各一分钟)煎烤肉排的两面,让毛孔合上,形成一层柔嫩的硬壳。一只很好用的铁锅不用植物油或加少量中性植物油就可以做到。随后放入盐和胡椒粉。同时要注意,别在翻转时碰伤了肉,因此,切勿使用叉子。
转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 上一篇文章已经提到USB接口在wifi模块中的最重要两个函数是usb_read_port()和usb_write_port()。那它们是怎么和wifi扯上关系的呢?我们可以从以下三个方面去分析:
1、首先需要明确wifi模块是USB设备,主控(CPU)端是USB主机;
2、USB主机若需要对wifi模块进行数据的读写时,就必须经过USB接口;
3、既然涉及到数据的读写操作,必然要用相应的读写函数,那么usb_read_port()和usb_write_port()即是它们的读写函数。
我们先从读数据开始进行分析,在分析之前,我们必须了解USB设备驱动的读数据过程。USB读取数据操作流程如下:
(1)通过usb_alloc_urb()函数创建并分配一个URB,作为传输USB数据的载体;
(2)创建并分配DMA缓冲区,以DMA方式快速传输数据;
(3)初始化URB,根据wifi的传输数据量,我们需要初始化为批量URB,相应操作函数为usb_fill_bulk_urb();
(4)将URB提交到USB核心;
(5)提交成功后,URB的完成函数将被USB核心调用。
现在我们一步步地详细分析整个过程,所谓的创建和分配,实质上是对内存的分配。作为一名Linux驱动开发程序员,必须了解Linux内存管理相关知识及合理使用内存。
那么我们应该怎样合理地创建和分配URB和DMA缓冲区呢?很明显,我们应该在用的时候分配,在不用的时候释放。
那么问题来了……什么时候在用,又什么时候不用呢?问题很简单,就是主控端读数据时分配,读完后释放,而只有当wifi模块有数据可读时,主控端才能成功地读取数据。那么wifi模块什么时候有数据可读呢?——下面重点来了!wifi模块通过RF端接收到无线网络数据,然后缓存到wifi芯片的RAM中,此时,wifi模块就有数据可读了。
经过上面的分析,我们找到了一条USB接口与wifi模块扯上关系的线索,就是wifi模块的接收数据,会引发USB接口的读数据;
现在,我们转到wifi模块的接收函数中,看看是不是真的这样?
在wifi接收函数初始化中,我们可以看到usb_alloc_urb()创建一个中断URB。伪代码如下:
int xxxwifi_init_recv(_adapter *padapter) { struct recv_priv *precvpriv = &padapter->recvpriv; int i, res = _SUCCESS; struct recv_buf *precvbuf; tasklet_init(&precvpriv->recv_tasklet, (void(*)(unsigned long))rtl8188eu_recv_tasklet, (unsigned long)padapter); precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); //创建一个中断URB precvpriv->int_in_buf = rtw_zmalloc(INTERRUPT_MSG_FORMAT_LEN); //init recv_buf _rtw_init_queue(&precvpriv->free_recv_buf_queue); _rtw_init_queue(&precvpriv->recv_buf_pending_queue); precvpriv -> pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF *sizeof(struct recv_buf) + 4); precvbuf = (struct recv_buf*)precvpriv->precv_buf; for(i=0; i < NR_RECVBUFF ; i++) { _rtw_init_listhead(&precvbuf->list); _rtw_spinlock_init(&precvbuf->recvbuf_lock); precvbuf->alloc_sz = MAX_RECVBUF_SZ; res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf); precvbuf->ref_cnt = 0; precvbuf->adapter =padapter; precvbuf++; } precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; skb_queue_head_init(&precvpriv->rx_skb_queue); #ifdef CONFIG_PREALLOC_RECV_SKB { int i; SIZE_PTR tmpaddr=0; SIZE_PTR alignment=0; struct sk_buff *pskb=NULL; skb_queue_head_init(&precvpriv->free_recv_skb_queue); for(i=0; i<NR_PREALLOC_RECV_SKB; i++) { pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); if(pskb) { pskb->dev = padapter->pnetdev; tmpaddr = (SIZE_PTR)pskb->data; alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); } pskb=NULL; } } #endif return res; } 在rtw_os_recvbuf_resource_alloc函数中,创建一个批量URB和一个DMA缓冲区。伪代码如下:
斐波那契数列 文章框架 基础实现,最原始的实现code,让Recurrence有了bad name why it is extremely inefficient how to improve第二重实现手段 code相关lisp思想与实现Algorithmic AnalysisThe third level golden ratiomore efficient ? what’s the running time?
相关的三个函数:
(LoadLibrary,GetProcAddress,FreeLibrary)
动态载入 DLL
动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数。
方法是:用 LoadLibrary 函数加载动态链接库到内存,用 GetProcAddress函数动态获得 DLL 函数的入口地址。当一个 DLL 文件用 LoadLibrary 显式加载后,在任何时刻均可以通过调用 FreeLibrary 函数显式地从内存中把它给卸载。
个人觉得,安全稳妥起见,装载过程应放在构造函数中,而释放动态库应在析构函数中进行操作。这样可以防止多次加载后,而在释放中少释放导致内存浪费问题。
(1)LoadLibrary 函数
注:Delphi 中还提供了 SafeLoadLibrary 函数,它封装了 Loadlibrary 函数,可以装载由 Filename 参数指定的 WindowsDLL或 Linux 共享对象。它简化了DLL的装载并且使装载更加安全。
[格式]: function LoadLibrary(LibFileName : PChar): Thandle; 复制代码
[功能]:加载由参数 LibFileName 指定的 DLL 文件。
[说明]:参数 LibFileName 指定了要装载的 DLL 文件名,如果 LibFileName 没有包含一个路径,系统将按照:当前目录、Windows 目录、Windows 系统目录、包含当前任务可执行文件的目录、列在 PATH 环境变量中的目录等顺序查找文件。
如果函数操作成功,将返回装载 DLL 库模块的实例句柄,否则,将返回一个错误代码,错误代码的定义如下表所示。
错误代码
含义
0
系统内存不够,可执行文件被破坏或调用非法 2
文件没有被发现
3
路径没有被发现
5
背景: 专栏之前写过许多关于DICOM协议的相关文章,有关于概念解析的理论性文章,也有实例演示的应用性文章。目的只有一个,希望能引导大家快速掌握DICOM协议,并着手进行自定义化开发。
目前DICOM协议实现有多种开源库,例如基于C++的DCMTK、基于C#的fo-dicom、基于Java的dcm4che。由于时间关系博文中的相关实例演示经常会穿插着使用三种开源库,因此具体到某一种库可能博文中并未给出示范工程。例如,近期有网友咨询希望利用DCMTK开源库自己动手实现C-FIND查询请求,并对服务端返回的信息进行定制化处理。因此周末动手编写了一个极简版的示例,代码裁剪于DCMTK开源库的findscu工程,供大家交流学习。
准备知识: 为了更好的理解代码示例,请耐心阅读之前专栏里的相关文章,如果已经对DICOM协议很了解且有过开发经验,或者干脆就想先动手敲代码,想从实践中学习,那么请自行跳到下一节。 在开始工作之前先阅读DICOM医学图像处理:DICOM网路传输了解DICOM协议的含义以及简单的建立规则,随后阅读DICOM医学图像处理:全面解析DICOM3.0标准中的通讯服务模块和DICOM:DICOM3.0网络通信协议(续)进一步了解DICOM协议,以及熟悉DCMTK开源库中对DICOM协议的具体实现。阅读完上述理论概念性文章后,进一步浏览下面两篇实例演示博文DICOM医学图像处理:基于DCMTK工具包学习和分析worklist、DICOM医学图像处理:利用fo-dicom发送C-Find查询Worklist 。
DCMTK实现C-FIND SCU: 待一切先验知识储备完成后,就可以进入我们的正题了,网友的需求是:
在阅读DICOM医学图像处理:基于DCMTK工具包学习和分析worklist、DICOM医学图像处理:利用fo-dicom发送C-Find查询Worklist 两篇实例博文后,希望利用DCMTK尝试发送C-FIND-RQ请求,然后将返回的C-FIND-RSP消息进行解析和后处理。 经过上述【准备知识】阶段后,想必大家已经了解了C-FIND请求建立的正题过程,因此不罗嗦了直接贴代码,用一个简单的实例来进行实际讲解。
a)网络环境初始化 //1)初始化网络环境 WSAData winSockData; /* we need at least version 1.1 */ WORD winSockVersionNeeded = MAKEWORD( 1, 1 ); WSAStartup(winSockVersionNeeded, &winSockData); b)DCMTK库初始化 //2)DCMTK环境监测 if(!dcmDataDict.isDictionaryLoaded()) { printf("No data dictionary loaded, check environment variable\n"); } c)建立DUL连接 //3)网络层ASC初始化 T_ASC_Network* cfindNetwork=NULL; int timeout=50; OFCondition cond=ASC_initializeNetwork(NET_REQUESTOR,0,timeout,&cfindNetwork); if(cond.bad()) { printf("DICOM 底层网络初始化失败\n"); return -1; } //4)创建底层连接,即TCP层 T_ASC_Association* assoc=NULL; T_ASC_Parameters* params=NULL; DIC_NODENAME localHost; DIC_NODENAME peerHost; OFString temp_str; cond=ASC_createAssociationParameters(¶ms,maxReceivePDULength); if(cond.
例如错误代码10061, 说明服务器已经找到,但连接被服务器拒绝,
连接失败原因可能是:
端口号设置错误; 2.服务器没有处于监听状态 (即ServerSocket –>Active=true);
3.数据包被服务器端的防火墙过滤掉。
附:Socket常见错误代码与描述
Socket error 0 – Directly send error Socket error 10004 – Interrupted function //call 操作被终止 Socket error 10013 – Permission denied //c访问被拒绝 Socket error 10014 – Bad address //c地址错误 Socket error 10022 – Invalid argument //参数错误 Socket error 10024 – Too many open files // 打开太多的sockets Socket error 10035 – Resource temporarily unavailable // 没有可以获取的资料 Socket error 10036 – Operation now in progress // 一个阻塞操作正在进行中 Socket error 10037 – Operation already in progress // 操作正在进行中 Socket error 10038 – Socket operation on non-socket //非法的socket对象在操作 Socket error 10039 – Destination address required //目标地址错误 Socket error 10040 – Message too long //数据太长 Socket error 10041 – Protocol wrong type for socket //协议类型错误 Socket error 10042 – Bad protocol option // 错误的协议选项 Socket error 10043 – Protocol not supported //协议不被支持 Socket error 10044 – Socket type not supported //socket类型不支持 Socket error 10045 – Operation not supported //不支持该操作 Socket error 10046 – Protocol family not supported //协议族不支持 Socket error 10047 – Address family not supported by protocol family//使用的地址族不在支持之列 Socket error 10048 – Address already in use //地址已经被使用 Socket error 10049 – Cannot assign requested address //地址设置失败 Socket error 10050 – Network is down //网络关闭 Socket error 10051 – Network is unreachable //网络不可达 Socket error 10052 – Network dropped connection on reset //网络被重置 Socket error 10053 – Software caused connection abort //软件导致连接退出 Socket error 10054 – connection reset by peer //连接被重置 Socket error 10055 – No buffer space available //缓冲区不足 Socket error 10056 – Socket is already connected // socket已经连接 Socket error 10057 – Socket is not connected //socket没有连接 Socket error 10058 – Cannot send after socket shutdown //socket已经关闭 Socket error 10060 – Connection timed out //超时 Socket error 10061 – Connection refused //连接被拒绝 Socket error 10064 – Host is down //主机已关闭 Socket error 10065 – No route to host // 没有可达的路由 Socket error 10067 – Too many processes //进程太多 Socket error 10091 – Network subsystem is unavailable //网络子系统不可用 Socket error 10092 – WINSOCK.
共阳数码管和共阴数码管用法区别 学习单片机将近一年半了,今天突然发现,我学习东西只是单纯的去记忆知识,并不涉及什么推理,基本上也没有什么思考.学得不真,学得也不深.长此以往,自己的思维将会变得越来越呆滞……. 总结能梳理自己的思绪,所以从今天起开始写博客来记录自己的学习过程…….. 好了,废话不多说,今天在使用数码管的时候发现数码管的亮度很低,怎么调都不好使…..不是因为数码管没有驱动(用了74hc573作为驱动芯片),也不是因为电压不高(单片机IO输出5v)。。。。 先贴出电路,相信大家很快就明白怎么回事了。。。。 共阳数码管公共端为阳极,接一个IO口,电流非常小。。。 解决办法:可以在各个阴极接三极管放大。 共阴数码管公共端为阴极极,接多个IO口,电流非常比较大。。。
axis2的版本是 axis1.6.2 在struts2中整合axis2后,访问wsdl的时候显示404 not found There is no Action mapped for action name xxxxxxxx. 解决办法: 在struts.xml配置文件中加入排除过滤的地址 <constant name="struts.action.excludePattern" value="/services.*"/> value中的“.”符号是必须的,如过滤地址为 “/services/*” value必须配置为 "/services.*" 黑色头发:http://heisetoufa.iteye.com
下表为签名中,类型的对应关系。
Java类型 对应的签名booleanZbyteBcharCshrotSintIlongLfloatFdoubleDvoidVObjectL用/分割包的完整类名; Ljava/lang/String;Array[签名 [I [Ljava/lang/String;
例: void set(String str); 签名:"(Ljava/lang/String;)V"
其实除了自己对照手写之外,JDK也提供了一个很好用的生成签名的工具javap,cmd进入控制台到你要生成签名的那个类的目录下。在这里用 Order类打比方,敲入: javap -s -private Order。所有方法签名都会被输出,关于javap的一些参数可以在控制台下面输入 javap -help查看。(做coder的 毕竟还是要认几个单词的)
居然一次就过了。。做了两天,泪流满面啊。不过代码跑得很慢。。有机会优化一下
这道题想清楚了还是很简单的,但是一开始的思路不容易理顺。下面文中我的f和g与Rujia书中的定义相反,请注意区分。
题目里说,把所有的无向边去掉之后,最终答案则一定是由剩下的有向边组成的最长路径长度k或者k+1。
所以我们的工作就变成了:给无向边分配方向,使得最后得到的树里,最长路径长度不大于k。若可以做到则答案为k,否则答案为k+1
对于树中某一个以结点a为根的子树来说(即不考虑a的祖先),经过a的最长有向路经s等于下行最长路+上行最长路。我们设这两条路的长度分别为f和g,则经过a的最长路经s的结点数为f+g+1。
转化无向边的过程分为两种情况:
a. 如果一个子树中不存在无向边,则经过子树的根结点的最长有向路结点数为f+g+1(recall that f是下行的最长路长度,g是上行的最长路长度)。
b. 如果一个结点a的子结点存在无向边,则我们先递归求出所有a的子结点的f和g,然后暴力枚举将所有无向边转化为上行/下行有向边,对于每一种枚举,按照上面不存在无向边时的方法,求出f, g和f+g+1,检查是否大于k。枚举的过程中,记下所有成功的枚举中最小的f和g,把它们和原本就是有向边子结点的最小的f和g比较,取较大值。(f和g本身是最长路的长度,这里要取的是不同成功的枚举情况下,遇到的最小的f和g。概念有点绕,可能要多考虑一下)
但是如果我们完全枚举无向边的转换方法,则复杂度为O(2^n),n为子结点中无向边的数量。这里有一个非常棒的优化:
求出所有子结点的f和g之后,把无向边的f和g值存到一个数组中,按照f值排序。
之后我们从第一位开始考虑,将无向边换为下行有向边,考虑到第p位的时候,我们可以将前p-1位的无向边一并换为下行有向边。因为第p位的f值大于前p-1位无向边的f值,将前p-1位同时换为下行有向边,整个树的f值不会变(f为最长路的长度,而排序后,前p-1位形成的路都不会比第p位长),而g值有可能变小。这时,我们找出第p+1位到第n位中最大的g值,求出f+g+1,检查是否小于等于k即可。一旦有某一个p满足了要求就可以得出结果并终止枚举。复杂度为线性。
求g的过程相同,按照g值排序、枚举即可。
需要注意的细节包括
1、容易混淆边的长度和边上结点的数量
2、f、g值在计算的时候什么时候要+1,什么时候不应该+1,要仔细考虑
3、dir数组的大小问题
4、枚举的边界值 - 全部换成下行/上行的情况
Run Time: 0.022s
#define UVa "LT9-26.1380.cpp" //A Scheduling Problem char fileIn[30] = UVa, fileOut[30] = UVa; #include<cstring> #include<cstdio> #include<algorithm> #include<vector> #include<iostream> using namespace std; //Global Variables. Reset upon Each Case! typedef pair<int,int> Pair; const int maxn = 200 + 5, DOWN = 0, UP = 1, UND = 2, INF = 1<<30; int dir[150]; vector<int> G[maxn]; vector<int> Gdir[maxn]; int f[maxn], g[maxn]; int n, x, k; int vis[maxn], len[maxn][2], lenvis[maxn][2]; / int dfs(int u, int direction); void readSon(int fa); void readG(int u); void clearG(); void dp(int u, int& ans_f, int& ans_g) { if(vis[u]) { ans_f = f[u]; ans_g = g[u]; return; } vis[u] = 1; f[u] = g[u] = INF; if(G[u].
使用树莓派时,需要在其系统中部署几个不同功能的程序系统,并涉及到数据库读写、串口读写、web访问等,使系统使用压力较大,在查看树莓派使用情况时也遇到些许问题。 树莓派操作系统基于Linux,故linux命令均可用于此系统中。
free命令
pi@raspberrypi ~ $ free total used free shared buffers cached Mem: 447864 230508 217356 0 22892 112896 -/+ buffers/cache: 94720 353144 Swap: 102396 0 102396 可以查看当前系统内存使用情况(总量,已用,未用,多进程共享,磁盘缓存): Mem 物理内存使用,其中已用部分包含磁盘缓存(缓存中并非已经全部使用,这里只已经分配出去的全部大小) buffer/cache 缓存使用,其中free部分为缓存中未使用部分 Swap 内存页交换时缓存,这部分不必太关注(基本为内存不足时进行的内存交换缓存) 其中cache为常用数据缓存,buffer为IO缓冲区,定期flush到硬盘(个人理解)
该命令还可使用 free -s n 设置每隔n秒打印一次
除这个命令以外,还可使用 cat /proc/meminfo查询详细内存使用情况,详细解释参照:http://blog.csdn.net/tenfyguo/article/details/7476833
还可直接使用Python建立脚本查询使用情况,详细内容可参考:http://shumeipai.nxez.com/2014/10/04/get-raspberry-the-current-status-and-data.html
注:这里使用这些方法获得的内存物理大小与实际大小或有出入,如上面我获得内存大小为437M,而使用的树莓派大小为512M,其原因为系统为GPU分配了一定的内存空间(若差别较大也可能为当前系统版本原因,可查询当前系统是否支持实际内存大小)。 修改GPU内存分配大小可在/boot/config.txt文件中查找
gpu_mem=64 即分配给GPU64M,其值只可选16,64,128,256.
df -hl 命令可查询当前硬盘使用情况,不再详述。
另外: 在此记录访问树莓派方法 1.硬件可使用一个HDMI分配器,将树莓派图像转到显示器 2.ssh 使用ssh方式连接树莓派,只显示命令行,使用putty软件 http://jingyan.baidu.com/article/335530daa0146319cb41c30b.html 3.远程连接树莓派,需安装xrdp http://jingyan.baidu.com/article/29697b91291927ab20de3c0c.html
假设源目录在192.168.1.1机器上,目录为/data
客户端集群在192.168.1.2, 需要将192.168.1.1机器上的/data目录到本地的/data目录
1、在两台机器上安装nsf 、 portmap
yum install nfs-utils portmap 安装好了之后。 2、
在192.168.1.1机器上面修改/etc/exports文件,加入如下内容
/data/ 192.168.1.2(rw,sync,no_root_squash)表示开放本机器上面/data目录, 主机192.168.1.2对该目录拥有rw权限。其他参数可以去查看nsf文档,这里不解释 然后启用nsf与portmap服务
service rpcbind start service nfs start 3、
在192.168.1.2机器上面启动nsf与portmap服务然后挂载remote目录
service rpcbind start service nfs start mount -t nfs 192.168.1.1:/data/ /data/ 将机器192.168.1.1上面的/data目录挂在到本机的/data目录下面 现在就可以在192.168.1.2机器上面对/data目录进行读改操作了。
poly2trellis(7, [171 133])代表什么意思呢?首先是7,他是1*k的vector,此处k为1,[171 133]是k*n的vector,此处n就是2,那么这个编码就是1/2码率的卷积码,这个卷积码的约束长度是7,也就是输出与前7个输入相关,171,133是十进制数,代表的是前面寄存器的抽头位置。 转载于:https://www.cnblogs.com/lianjiehere/p/4343853.html
VisualStudio下的C++调试方法
概述: 介绍如何利用VisualStudio的调试属性,各类断点设置,利用pdb与dump文件来定位崩溃问题。
• 调试属性设置
工程的的调试属性中,我们可以对调试的程序目录及路径进行设置。
• 工作目录: 通常为调试程序的运行目录,当我们的程序需要使用相对路径的外部资源时就需要使用此参数了,指定一个运行目录给它。
• 生成后事件
1)当我们调试DLL工程的时候我们的调试命令通 常是exe程序,每次完成编译后我们需要手动将动态库拷贝到exe所在目录中。
3)通过生成后事件我们可以自动完成拷贝动态库等操作来提高我们的调试效率。
3)拷贝命令示例
a)命名使用的是windows的cmd命令
b) Copy “a.dll”“c:\demo\”
c) Copy “C:\*.dll”“c:\demo\”
启动调试
• 启动提示,通过点击VS工具栏上的调试按钮来对运行我们程序进入调试模式(F5)
• 停止调试,启动调试后通过点击终止按钮来停止调试( Shift+F5)
• 暂停调试,如果程序中没有命中断点的情况下程序会顺序的执行代码,在执行过程中我们可以通过暂停按钮来暂时停止代码的执行,程序会停止在当前的执行代码行中。点击运行后又会继续执行.
输出窗口的使用
• 当我们启动调试程序之后我们可以使用调试窗口来获取程序的运行信息。
• 通过菜单-》视图-》输出,我们则可以打开输出窗口
• 快捷键为alt+2
• 启动调试后系统会利用输出窗口反馈程序中所有资源的加载顺序和信息。
输出窗口的使用
• 对于有符号DLL,在输出窗口内将会显示,“已加载”,表示挂在DLL对应的符号文件已经完成加载,并观察加载DLL路径是否正确。
• 此外输出窗口还可以显示程序调试运行过程中的输出信息。
• 我们可以在代码中利用如OutputDebugString这样的API将文本内容输出到输出窗口中显示以便于我们进行调试。
断点窗口
• 断点窗口显示程序中加载的所有断点的位置及类型。
• 通过菜单-》调试-》窗口-》断点或者快捷键Alt+F9,可以打开断点窗口
• 我们可以通过断点窗口的工具栏按钮完成以下的操作:
A、删除所有的断点或选定断点
B、禁用启用所有的断点或选中断点,禁用后此断点不会命中
C、导出断点或导入断点
位置断点的设置
默认情况下我们通过F9设置的断点产生的断点类型为位置类型,即只要运行到这个位置, 就会产生命中。
断点常用的还有 : 命中次数:
命中次数断点则可以设置当经过此处固定次数后才进行命中,可供选择的命中次数条件是:总命中,等于某一次数,大于等于某一次数或者几倍于某一次数。
筛选器断点的设置:
对特定的线程、计算机、进程进行断点命中。
命中条件断点的设置:
命中调试断点可以在命中此断点时输出信息到输出窗口,并且可以直接打印输出变量的数据
新建断点:
在函数处中断: 在函数运行到某一函数位置处产生中断;
http://blog.csdn.net/ziren235/article/details/1525599
PS(PostScript)是专门为打印图形和文字而设计的一个编程语言,与打印的介质无关,即不管是在纸上、胶片上打印,还是在屏幕显示都合适。
PostScript是一种页面描述语言,与HTML语言类似。是由Adobe公司在1985年提出来的,首先应用在了苹果的LaserWriter打印机上。PS的主要目标是提供一种独立于设备的能够方便地描述图像的语言。独立于设备意味着,不需要借助任何具体设备的特性(例如,打印机的分辨率)来描述一个图像,因而这个描述不需要经过任何修改即可用在其他的PS打印机上进行打印。
下面介绍一个最著名的PostScript实用工具Ghostscript。 Ghostscript是一个Postscript解释器,它可以在许多操作系统上运行,如DOS,WINDOWS31,WINDOWS95,WINDOWS NT,MACHINTOSH,UNIX,OS/2,VAX/VMS等。
Ghostscript主要有两个功能: 1.屏幕输出:可以在屏幕上显示Postscript文件。 2 打印输出:可以在非Postscript打印机上打印Postscript文件。
Ghostscript还提供了一个前端产品:GSVIEW。GSVIEW不能单独运行,必须先安装了Ghostscript,然后才能运行GSVIEW。GSVIEW的WINDOWS版是标准的WINDOWS程序,使用十分方便.
EPS(Encapsulated PostScript)封装的PostScript。EPS文件就是包括文件头信息的PostScript 文件,利用文件头信息可使其他应用程序将此文件嵌入文档之内。EPS文件还有一些限制,而这些限制并不适用于标准的PostScript文件。这些限制主要就是一些规则,以保证EPS文件可以插入到不同的文件中,而不会损伤该文件。例如:在Microsoft Word中,可以在一个Word中,可以在一个Word文档中嵌入ESP文件。EPS文件最流行的应用就是将其嵌入桌面出版文件中,特别是由PageMaker或是QuarkXPress创建的文件。桌面分色(DCS)就是由Quark公司开发的,用于套印色(Process color)处理。DCS图像是EPS格或图像,由5部分组成:低分辨率的屏幕预览,再加上青色、品红色、黄色和黑色图层。 DCS2.0版文件可包括4种以上的套印色,也可以在其中包括一定数量的专色(spot color) 或者是高保真度的分色。
区别:PostScript格式(PS格式)。它是PostScript语言的标准格式,由一个以PostScript语言所对应的ASCII字符(或者它的二进制形式)所构成的多页面描述文件,并以描述矢量图形为其特长,但也可以容纳点阵图像。PS格式是可以直接向打印设备输出的文件格式。本格式是PostScript页面描述语言的“原始”格式,它的最大特点是一个PS文件中可以包含整章整节的许多页面。和PS格式相比,EPS文件格式的“封装”单位是一个页面,也就是一个。EPS文件只包含一个页面的描述。这样,如果有50个页面的出版物就会产生50个EPS文件。
常常听老师说容器,容器是什么?spring中是如何体现的?一直有疑惑,这两天看了一下Spring管理bean的Demo,对于Spring中的容器有了简单的认识。
我们知道,容器是一个空间的概念,一般理解为可盛放物体的地方。在Spring容器通常理解为BeanFactory或者ApplicationContext。我们知道spring的IOC容器能够帮我们创建对象,对象交给spring管理之后我们就不用手动去new对象。
BeanFactory与ApplicationContext的区别是什么?
BeanFactory采用了工厂设计模式,负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。而ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:国际化支持、aop、事务等。同时BeanFactory在解析配置文件时并不会初始化对象,只有在使用对象getBean()才会对该对象进行初始化,而ApplicationContext在解析配置文件时对配置文件中的所有对象都初始化了,getBean()方法只是获取对象的过程。
因此我们一般在使用的时候尽量使用ApplicationContext。
ApplicationContext是如何管理Bean呢?下面这个Demo简单模仿了这个原理:
1.建立一个类PersonServiceBean,并在xml文件中进行配置。
public class PersonServiceBean implements PersonService { public void save(){ System.out.println("我是save()方法"); } } <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean> 2.建立类BeanDefinition,提供一个构造函数,将其作为每个bean的公共转型类。
public class BeanDefinition { private String id; private String className; public BeanDefinition(String id, String className) { this.id = id; this.className = className; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getClassName() { return className; } public void setClassName(String className) { this.
介绍一些组件 原文:[Introduction to some Components] (http://forums.kleientertainment.com/topic/47542-introduction-to-some-components)
翻译: @czfshine Prefabs(预设物), Components(组件), Stategraphs(状态图), 这一些名词意味着是什么呢?我希望它们像XYZ一样简单。
目录: 介绍一些组件目录General一般Armor护甲 重要的变量重要的函数例子 Beard胡子 重要变量重要函数例子 Burnable可燃的 重要的变量重要的函数例子 Container容器 重要的变量重要的函数例子 Cookable烹饪 重要的变量例子 Dapperness衣衫褴褛 重要的变量例子 Eater吃者 重要的变量重要的函数基本的食物类型例子 Edible可食用的 重要的变量例子 Equippable可装备的 重要的变量例子 Finite Uses耐久 重要的变量重要的函数例子 Harvestable收获 重要的变量重要的函数例子 Health生命 重要的变量重要的函数例子 Hunger饥饿 重要的变量例子 Insulator保暖 重要的变量例子 Inventory-Item可存放 重要的变量重要的函数例子 Perishable腐败 重要的变量重要的函数例子 Pickable可采摘 重要的变量重要的函数例子 Propagator传播算子 重要的变量重要的函数 Repairable可修理 重要的变量例子 Sanity-Aurasan光环 重要的变量 Talker话语者 重要的函数例子 Tool工具 重要的函数例子 Tradable交易 例子 Useable Item可使用的 重要的变量例子 Workable能工作的 重要的变量重要的函数例子 Light亮 使用重要的函数例子 General(一般) 假设你已经熟悉基本的Lua
mysql 日期增加一年的更新语句: UPDATE table SET date = DATE_ADD ( date , INTERVAL 1 YEAR ) DATE_FORMAT函数用法 一、在oracle中,当想把字符串为‘2011-09-20 08:30:45’的格式转化为日期格式,我们可以使用oracle提供的to_date函数。
sql语句为:
SELECT to_date('2011-09-20 08:30:45', 'yyyy-MM-dd hh24:mi:ss') FROM dual; 反之,可以使用to_char()函数把日期转化为字符串。
sql语句为:
SELECT to_char(SYSDATE, 'yyyy-MM-dd hh24:mi:ss') FROM dual; 二、在mysql中,DATE_FORMAT(date, format) 函数根据format字符串格式化date值。
%M 月名字(January……December) %W 星期名字(Sunday……Saturday) %D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。) %Y 年, 数字, 4 位 %y 年, 数字, 2 位 %a 缩写的星期名字(Sun……Sat) %d 月份中的天数, 数字(00……31) %e 月份中的天数, 数字(0……31) %m 月, 数字(01……12) %c 月, 数字(1……12) %b 缩写的月份名字(Jan……Dec) %j 一年中的天数(001……366) %H 小时(00……23) %k 小时(0……23) %h 小时(01……12) %I 小时(01……12) %l 小时(1……12) %i 分钟, 数字(00……59) %r 时间,12 小时(hh:mm:ss [AP]M) %T 时间,24 小时(hh:mm:ss) %S 秒(00……59) %s 秒(00……59) %p AM或PM %w 一个星期中的天数(0=Sunday ……6=Saturday ) %U 星期(0……52), 这里星期天是星期的第一天 %u 星期(0……52), 这里星期一是星期的第一天 %% 一个文字“%”。 把字符串转为日期格式
meshBaker版本:3.31 ps:(原本使用的3.6,结果发现那个版本貌似有些问题) unity3d版本:4.61 作用:本人项目中,从drawCall 60左右 降到了 十几个,优化利器。。 最基本的使用 一.搭建场景 如上图场景,新建4个材质,分别附上这4个贴图,贴图是MeshBaker自带的。
运行后
二.使用meshBaker 1.创建对象,GameObject->CreateOther->MeshBaker->Mesh And MaterialBaker 上面有2个组件,注意,3.6版本的结构和这个有点区别 点击Open Tools For Adding Objects,弹出如下窗口 List Shaders In Scene 按钮是可以打印当前场景中物体使用的shader,lightmapping,等一些信息,可以做参考 选中需要合并的物体,点击Add Selected Meshes,一定要选中物体 输出如下信息 点回MeshBaker0会看到Objects To。。。里面已经有4个物体了,也就是我们刚才选中的物体,当然,你自己手动拖进去也是可以的。 接下来点击Create Empty Assets For Combined Material 弹出如下窗口,选好路径,自定义名字保存即可,这个主要是用来储存合并材质和合并信息的 之后点击Bake Materials Into Combined Material 等待操作完成后,找到下面这个脚本,点击Bake就可以了 会生成一个 CombinedMesh-MeshBaker0-mesh 的对象 然后点击Disable Renderers on Source Objects,就是隐藏原来物体的Render组件 运行后可以看到 DrawCalls 从 5 降到 2 了 完
<?php $my_array = array("20" => "Dog", "21" => "Cat", "22" => "Horse","99"=>"adsfasdf"); $res = suiji($my_array); echo "随机打乱数组!"; var_dump($res); function suiji($a){ $res=$a; $arr=array(); $num=count($res); for($i=0;$i<$num;$i++){ $res=array_values($res); $b=rand(0,$num-$i-1); $arr[$i]=$res[$b]; unset($res[$b]); } return $arr; } //print_r($my_array); //shuffle($my_array); //print_r($my_array); ?>
char ch3=(char)62; //ASCII码
计算机中一切都是“数”,char用ASCII码值来对应“数”
ASCII码
链接:http://baike.baidu.com/link?url=v53finXSfwxDSTOPvbzvOkA5S5SfHOC6po_DW_iccIWjbeAOqCWLP6NcSiO6xj9XKAS_iXA7CDzpUPmyywwyX_
int i = 9;
//char c = (char)i;
//Console.WriteLine(c);
char c = (char)(i+'0');//9+48 => '0':48
Console.WriteLine(c);
0-9数字转化为char (+‘0’)
char 转化为0-9数字(-‘0’)
字母大小写转化
大写转小写
char ch = 'A';
char ch2 = (char)(ch + ('a' - 'A'));
Console.WriteLine(ch2);
转载于:https://www.cnblogs.com/linyongqin/articles/4285163.html
昨天在测试号上用OAuth2.0网页授权方式静默获取用户openid,然后暂存在session中,最后连同注册表单信息一起填入数据库,以达到自动绑定的目的。
然而今天偶然发现订阅号无法开通网页授权接口!!!!!!欲哭无泪。。。
解决方案如下,虽然用户体验照比网页授权差一点,但总比日后让用户手动绑定体验好得多:
如果是view类型自定义菜单的话,修改为click类型。click事件中是包含fromUserName参数的,也就是用户的openid。那么就设置当用户点击该按钮时返回文字,在文字中添加超链接,并把fromUserName通过get方式作为参数添加到链接后面,示例如下:
String Url = "http://......(填写你的链接)....."; String text = "<a href=" + Url + "?openid=" + openid + "\">点此链接注册</a>"; 注意转义字符 \
也可以回复图文消息,同样把fromUserName作为参数放到图文消息链接里
先调用init()函数,执行pygame的一些初始动作,然后创建窗口,准备画圆,
(255,255,255,255)为白色窗口填充。(255,0,0)为红色圆。
while是每次循环绘制一个动画中的一帧
display.update()更新图像
如果想画透明的可以为(255,0,0,127)表示透明度为50%。
注意pygam.Color中C为大写。
import pygame width = 640 height = 480 radius = 100 fill = 1 pygame.init() window=pygame.display.set_mode((width, height)) window.fill (pygame.Color(255,255,255)) while 1: pygame.draw.circle(window, pygame.Color(255,0,0), (width/2, height/2), radius, fill) pygame.display.update() 效果如下:
利用花生壳+终端服务器搭建小型企业远程系统平台 案例说明: Myhat公司最近在西安搭了一个分点,由于公司在ERP上使用的是同一套系统,之前一直是使用VPN来连的.最近因为公司需要减少相关的费用决定使用其他方式来实现远程访问. 应用分析:
因为金融危机,公司决定在网络应用方式减少相关的费用.因为公司大部分费用是用于VPN上,公司VPN主要是使用SDH的方式���的,大家知道SDH一般都很贵的!所以,就从它下手吧! 因为VPN主要是用于分点对总部的访问,总部对分部的访问同乎为0,所以我们只需要让分点能够访问到我们总部就行了.按照这个思想,觉得使用微软的终端服务器可以实现这个需求! 通过终端服务器,我们可以实现多个用户并发访问!并且可以清晰的管理用户的会话,通�放�SDH,公司�定�普通的ADSL方式���部�分部�的��。 实验环境: 1.拓补如图 相关说明: 1.终端服务器系统使用windows server 2003 R2企业版 2.利用花生壳获取终端服务器的免费域名为admingroup.vicp.net 3 .如果你确定需要使用IE访问的话,那么终端服务器需要有固定的公网IP(动态IP经博主测试,无法登入系统,只能打开WEB登陆界面.估计是由于动态解析供应商做了相关的限制吧) 来自湖北和西安的用户通过网络直接连到我们的终端服务器,直接使用上面的ERP软件.相信这可能是部分公司目前正在使用的拓补吧! 好的.现在我们来看看如何实现Terminal Server的安装部署吧! Terminal Server的安装部署 需要这安装以下组件(当你需要安装WEB方式 时,你就需要安装万维网服务) 如果你希望从远程方式管理你的服务器,你就需要把下面这个也勾上! 哈哈,终端服务器授权我就不多说了!非安装不可的嘛! 按照这个步骤走吧! 当然是要选择完整安全模式 在这里我们需要选择终端服务需要对哪些进行授权,是设备还是用户.我想只要你的授权许可证允许或是足够多,你选哪个都一样!在这里我就对用户进行授权吧! 将这台服务器指定为许可证服务器(许可证服务器主要是对用户或是设备进行授权的) OK,终于完成了组件的安装! 现在我们来看看: 终端管理服务器 现在博主给你看一下,博主测试使用的域名(哈,只在晚上开放)这个域名还没有申请,那我就多搞几个,反正放哪里也是没人用,况且只有一个字母之差,忘记了好也找嘛!有关域名的申请在此就不多说了,到花生壳网站注册一个不到5分钟! 当然光是这样,远程用户仍无法登入!我们还需要在路由上映射相关的端口!ADSL直连用户除外!如果你的网络里有ISA,你需要发布RDP服务器!
更改路由器设定:
哈哈,我们使用的是TP-Link402路由器,大部分家用都会选这个!那就来设定吧!无论哪种路由器,方法都是将相应的端口映射到相应的计算机上!
配置一下虚拟服务器(映射80,6060,3389)
再设定一下DMZ区吧,这样利于外部用户的快速访问:
现在我们使用MSTSC远程桌面连接连过去看看吧!
打开IE输入http://admingroup.vicp.net/tsweb(内网测试OK,估计使用公网IP同样也行) OK,远程的远程Web使用平台搭建成功,去试试吧!
OK,现在我们做了这么多,是啊!平台是搭建好了,可是如何来保障它是安全的呢?除了给他配置相应的防护软件以外,我们还需要修改终端服务器的相关端口. 我们都知道终端服务器的相关端口为3389,现在很多黑客工具都会对这个端口进行扫描,所以我们需要更改这个端口,不让有恶意企图的人知道我们在跑什么服务!至少让他要花费一翻功夫吧! 在互联网上有不少教大家如何来手动改这个端口,今天博主给大家带来一个脚本!当然声明一下:这个脚本不是我写的,作者嘛,脚本上已经标明了.我就不多说了,在此非常感谢他提供了这么好的脚本!(附件提供下载哟)
'********************************************** '*BY r05e '*改变终端服务端口号 '********************************************** Set WshShell=CreateObject("W..Shell") Function Imput() imputport=InputBox("请输入一个端口号,注意:这个端口号目前不能被其它程序使用,否则会影响终端服务"," 更改终端端口号", "3389", 100, 100) If imputport<>"" Then If IsNumeric(imputport) Then WshShell.RegWrite "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp\PortNumber",imputport,"REG_DWORD" WshShell.RegWrite "
Handler是什么 是Android中给我们提供的一套UI更新,消息的处理以及消息的发送的机制 其中有Handler,MessageQueue,Looper,Message 我们可以形象的将handler比喻成学生,将Loop比喻成老师,学生要和老师报告,要sendMessage,老师同意以后要执行Looper.looper,学生听到以后要去执行,则要handleMessage
为什么要用Handler 在Android设计过程中,就封装了一套消息机制(消息的创建,传递,处理机制),如果不遵循这样的机制就没有办法更新UI,就会抛出异常(不能在一个非UI线程中更新UI)
Handler怎么用 用途: 1.定时发送一个message或runnable对象 2.可以在一个线程中处理action Message: arg1,arg2,obj Message message = new Message(); Message message = handler.obtainMessage(); message.sendToTarget();==handler.sendMessage(message); 移除一个handler handler.removeCallbacks(runnable) 截获handler发来的消息
Handler handler = new Handler(new Callback){ boolean handleMessage() }void handlMessage() 4.Android中为什么要设计只能通过Handler更新UI 最根本的目的就是解决多线程并发问题 假设如果在一个Activity中有多个线程去更新UI,并且没有加锁机制,那么会产生什么样的问题? UI界面错乱 如果每次更新UI,并且都有加锁机制,那又会产生什么样的问题? 性能下降 综上所述: Android给我们提供了一套更新UI的机制,所有的更新UI操作,都是在主线程的消息队列当中去轮询处理的
5.Handler原理 一:Handler封装了消息的发送(主要包括消息发送给谁) 1.内部包含一个消息队列,也就是MessageQueue,所有的Handler发送的消息都会走向这个消息队列当中去。 2.Loop.looper(),就是一个死循环,他会不断的从MessageQueue中取消息,如有消息就会处理,没有消息就会阻塞。 二:MessageQueue就是一个消息队列,可以添加消息,可以处理消息 三:handler也很简单,内部会跟Looper关联,也就是说找到了looper就找到了messagequeue, 在handler中发消息,其实就是向messagequeue中发送消息 总结:handler负责发送message,looper负责接收message,并直接把消息回传到handler自己
输入一个整数并把整数所有数字倒序输出
#include #include int reverseInt( int num ){
int result = 0;
// 将整数倒序
for (int i = num; i ; )
{
// 去掉个位上的数
i = i/10*10;
// 将result进一位,并加上当前个位上的数(num-i)
result = result * 10 + num - i;
i = i /10;
num = num/10;
}
return result;
}
// 第二种实现
int reverseInt2( int num ){ int result = num%10;
for (; num/=10; )
{
result = result*10 + num%10;
}
return result; }
void main(){
int num;
scanf("
#include <boost/cast.hpp> // void test1() { int i = 0; size_t ui = -1; //编译警告:warning C4245: '=' : conversion from 'int' to 'size_t', signed/unsigned mismatch //把这个值0xFFFF-FFFF放入ui,按照补码理解-1。 i = (int)ui; //强制转换,无编译警告. i的值为 0xFFFF-FFFF } // void test2() { int i = 0; size_t ui = std::numeric_limits<int>::max() + 1; //把 0x7FFF-FFFF + 1 放入ui i = static_cast<int>(ui); //无编译警告,当强制转换时,也会无警告,是一样的。 //i的值是0x8000-0000 } //由test1和test2可见: //无符号的size_t和有符号int相互转换时,内存是直接拷贝的,二进制值不变,但是对二进制值的解释方式不同。 //编译器会给出警告,也可能不警告(被diable或者因强制转换语法而不显示警告了) // void test3() { int i = 0; size_t ui = std::numeric_limits<int>::max()+1; //这个值,是故意设置的,int容纳不了的最大值。 try{ i = boost::numeric_cast<int>(ui); } catch(boost::bad_numeric_cast&) { std::cout<<"
public class SHashMap<K, V> implements Serializable,Cloneable { /** * hashMap工具类方便进行转换,改工具类具有所有HashMap的属性和方法 */ private static final long serialVersionUID = 1L; private HashMap<K, V> map; public SHashMap() { this.map = new HashMap(); } public SHashMap(Map<K, V> map) { this.map = ((HashMap) map); } public void put(K key, V value) { this.map.put(key, value); } public void remove(K key) { this.map.remove(key); } public void removes(String keys) { if (!StringUtil.isNotNullStr(keys)) return; String[] keyArr = keys.split(","); for (String key : keyArr) this.
js平滑滚动到顶部,底部,指定地方 采用锚点进行页面中的跳转的确很方便,但是要想增加网页的效果,可以使用jquery中的animate,实现滚动的一个动作,慢慢的滚动到你想跳转到的位置
滚动到顶部:
$('.scroll_top').click(function(){$('html,body').animate({scrollTop: '0px'}, 800);});
滚动到指定位置:
$('.scroll_a').click(function(){$('html,body').animate({scrollTop:$('.a').offset().top}, 800);});
示例演示地址:http://www.daixiaorui.com/Public/demo/js/scroll.html 源码参考:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>js平滑滚动到顶部、底部、指定地方</title>
<script type="text/javascript" src="http://www.daixiaorui.com/Public/js/jquery.min.js"></script>
<style>
.box{ height:200px; width:100%; background:#ccc; margin:10px 0;}
.location{ position:fixed; right:0; bottom:10px; width:20px; background:#FFC; padding:5px; cursor:pointer;color:#003};
</style>
</head>
<body>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box a">产品介绍产品介绍 http://www.daixiaorui.com 产品介绍产品介绍产品介绍产品介绍产品介绍产品介绍产品介绍产品介绍产品介绍产品介绍产品介绍</div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="
排好广告、画册、年历后,需要把版面内容输出成PS文件,在把PS 文件拿去出片后,再拿去印刷,将设计的版面变成印刷品。
如何阅读ps文件
编者按——在INTERNET上查找资料的朋友可能会经常碰到*.ps文件,这些*.ps文件可能是某个大学的入学申请表,也可能是某个软件的使用文档,或者是某个公司的简历。你把这些文件下载下来后可能会发现不知道怎样读它!用EDIT等文本编辑器打开一看,文件开头都是些乱七八糟的字符,用Microsoftword也不能读它,再打开图像编辑软件如Photoshop还是读不了!那么这些*.ps文件到底是什么东西呢?
什么是PS
这里的ps是PostScript的缩写.PostScript是Adobe公司开发的一种可编程打印控制语言。大家平常看到的所谓“PostScript"打印机就是指支持“PostScript”语言的打印机。
现在常用的打印控制语言有三种:
一种是针打的标准,EPSON公司的EPSON打印控制语言,凡是针式打印机都标明同EPSON兼容,其实这里的兼容就是指支持EPSON打印控制语言;一种是HP的PCL,即PrintControlLanguage的缩写;还有一种就是今天要介绍的PostScript。
*.ps文件就是指这个文件已经用PostScript语言处理过了,可以直接在PostScript打印机上输出(相当于文本文件加上HTML标记后就成了HTML文件一样)。例如我们只需用下面命令:copy/bfilename.psprn即可把一个*.ps在PostScript打印机上打印出来。
大家可能觉得这样做很麻烦,直接用个文本文件或WORD文件不就可以了吗?既然INTERNET上流行*.ps文件,自然有它的道理了。
假设一个大学要在网上发布入学申请表,最简单的办法是搞一个文本文件,任何机器都可识别,但是在文本文件里无法加入排版信息,这样每个人寄回来的表格格式可能都不一样。用WORD当然可以,但如果机器没装WORD怎么办?如果是一台工作站根本不能装WORD又怎么办呢?
PostScript是一种页面描述语言,由Adobe公司于1985年开发成功(Adobe正是靠PostScript起家的)PostScript最重要的用途是以设备无关方式描述图形,这样,同一个描述可以不加修改地在任一台PostScript打印机上输出。另外,用PostScript还可以在计算机屏幕及其它绘图设备上绘图,可以在屏幕上显示相应的PostScript文件。PostScript由于可以满足上述条件,所以在网上广为流行。
阅读PS文件的工具 *.ps是网上广为流传的文件格式,如何使用这种文件格式呢?下面介绍一个最著名的PostScript实用工具Ghostscript。
Ghostscript是一个Postscript解释器,它可以在许多操作系统上运行,如DOS,WINDOWS31,WINDOWS95,WINDOWSNT,MACHINTOSH,UNIX,OS/2,VAX/VMS等。Ghostscript主要有两个功能:
1.屏幕输出:可以在屏幕上显示Postscript文件。
2打印输出:可以在非Postscript打印机上打印Postscript文件。
现在Ghostscrip的WIN95最新版是5.10版,Ghostscript采用的是命令解释行,使用不太方便。运行Ghostscript后屏幕出现如下所示的命令窗口:
GS>__ 注意这是Ghostscript的窗口提示符,而不是DOS下的提示符。在该提示符下使用有关命令即可。
比如输入:
GS>((tiger.ps)run
就可以在屏幕上显示tiger.ps文件。具体的命令你得学习随机提供的用户手册。
由于命令解释方式使用不太方便,Ghostscript还提供了一个前端产品:GSVIEW。GSVIEW不能单独运行,必须先安装了Ghostscript,然后才能运行GSVIEW。GSVIEW的WINDOWS版是标准的WINDOWS程序,使用十分方便,这里介绍最新版GSVIEW2.4。
下面通过介绍各个菜单项的作用来说明GSVIEW的功能(仅列了最常见的菜单选项):
1.File
Open:打开一个文件,目前GSVIEW支持的文件格式有:*.ps,*.eps,*.epi,*.pdf.在文件选择窗口中选中你希望的文件即可在屏幕上阅读文档了。
Selectfile:同Open相似,但不显示文件,主要用于在打印文件前先选择一个文件(你可能只想打印文件,对浏览文件不感兴趣)。
Extract..:从当前文档中拷贝几页到一个新的.ps文件中。
Close:关闭文档。
Info:提示当前文档的一些信息,如文件名,页数,创建日期,标题,页码顺序等。
Print:打印。如果你的打印机不支持Postscript,则选择该选项。然后根据屏幕提示选择你当前使用的打印机类型,分辨率(各个打印机可用的分辨率不一样),打印页码即可开始打印。多么简单!
Printfile:如果你的打印机是Postscript打印机,则选该选项直接打印,GSVIEW直接将打印序列发到打印机,什么都不做。
Showmessage:显示程序运行的一些消息,如GhostscriptDLL的位置等,同用户关系不大。
Exit:退出GSVIEW。
以上其实就可以满足基本需要了,当然GSVIEW还提供了其它许多功能。
2.Edit
Copy:这里的Copy和一般程序里的Copy概念不一样,这里是将当前页显示的内容作为BMP图片拷贝到剪贴板中。
PasteTo:将用Copy命令拷贝到剪贴板中的内容输出到BMP文件中。
TextExtract:将.ps文件中的文本输出到文本文件中。
Find:在文档中查找字符串。
3.Oretenation
显示方式,如可以左转90度,右转90度等。
4.Media
DisplaySettings:设置显示方式:如分辨率,放大分辨率等。下面还列出了许多纸张类型,如A4、A3.....等,就不一一列出。
GhostScript和GSVIEW的获得及安装 读者可通过以下地址下载GhostScript和GSVIEW:
http://www.cs.wisc.edu/~ghost/aladdin/
get510.html
你总共需要下载以下四个文件:
GSV24W32.ZIP553,953 GS510W32.ZIP568,543 GS510INI.ZIP827,092 GS510FN1.ZIP1,170,038 将以上四个文件拷贝到一个子目录中,然后用WINZIP打开GSV24W32.ZIP,在WINZIP中直接运行其中的SETUP即可(编者注:我们在该网址发现了GSVIEW2.6版本-GSV26W32.ZIP,用它代替第一个文件下载,用WINZIP将其解压至一个目录,把另三个文件拷至该目录,执行SETUP)。
相关资源 下列站点中有一些关于PS的资源:
http://www.adobe.com/prodindex/postscript/
main.html
postscript的老家,包括postscript描述语言的最新版postscript3的资料,白皮书及相关资源。
http://www.lasergo.com/
又一个观察postscript文件的工具,并提供一个NetscapeNavigator插件,可以在NetscapeNavigator中观看ps文件。
check if a tree is balanced
public int getHeight (TreeNode root) {
if (root == null) return 0; return Math.max(getHeight (root.left), getHeight(root.right)) + 1; } public boolean checkBalance(TreeNode root) { if (root == null) return true; int left = getHeight(root.left); int right = getHeight(root.right); int diff = Math.abs(left - right); if (diff > 1){ return false; } else { return checkBalance(root.right)&&checkBalance(root.left); } }
(function(e){var i={shadecolor:"#FFD24D",shadeborder:"#FF8000",shadeopacity:.5,cursor:"move",layerwidth:400,layerheight:300,layerborder:"#DDD",fade:true,largewidth:1280,largeheight:960};var t=function(t){t=e.extend({},i,t);e(this).each(function(){var i=e(this).css("position","relative");var h=i.children().first();var r={x:h.width()/t.largewidth,y:h.height()/t.largeheight};var o={shade:{width:t.layerwidth*r.x-2,height:t.layerheight*r.y-2}};var a=e("<div>").css({position:"absolute",left:"0px",top:"0px","background-color":t.shadecolor,border:"1px solid "+t.shadeborder,width:o.shade.width,height:o.shade.height,opacity:t.shadeopacity,cursor:t.cursor});a.hide().appendTo(i);var d=e("<img>").css({position:"absolute",display:"block",width:t.largewidth,height:t.largeheight});var s=e("<div>").css({position:"absolute",left:i.width()+5,top:0,"background-color":"#111",overflow:"hidden",width:t.layerwidth,height:t.layerheight,border:"1px solid "+t.layerborder});d.attr("src",i.attr("href"));d.appendTo(s);s.hide().appendTo(i);var n={x:o.shade.width/2,y:o.shade.height/2};var l={width:i.innerWidth()-a.outerWidth(),height:i.innerHeight()-a.outerHeight()};var g=function(){a.show();if(t.fade)s.stop().fadeIn(300);else s.show()};var c=function(){a.hide();s.hide()};var f=i.offset();i.mousemove(function(e){var t=e.pageX-f.left;var h=e.pageY-f.top;if(t<0||t>i.innerWidth())return c();if(h<0||h>i.innerHeight())return c();t=t-n.x;h=h-n.y;if(t<0)t=0;if(h<0)h=0;if(t>l.width)t=l.width;if(h>l.height)h=l.height;a.css({left:t,top:h});d.css({left:0-t/r.x,top:0-h/r.y})}).mouseenter(g).mouseleave(c)})};e.fn.extend({enlarge:t})})(jQuery);
调用上面的插件 $(function(){
$("#demo").enlarge({ // 鼠标遮罩层样式 shadecolor: "#FFD24D", shadeborder: "#FF8000", shadeopacity: 0.4, cursor: "move", // 大图外层样式 layerwidth: 480, layerheight: 360, layerborder: "#DDD", fade: true, // 大图尺寸 largewidth: 960, largeheight: 720 });
}); html中代码:
<a href="../upload/{$data['img']}" id="demo" style="position: relative;float: left; z-index:999;">
<img src="../upload/{$data['img']}">
</a>
一个放大镜就做好啦,
中国X银行间联POS终端规范解读
一、标准POS报文设计思路解读 以下表格为标准POS报文结构,由TPDU+HEAD(报文头)+ISO8583MSG(8583报文数据)构成;其中8583报文体中包括”位元素”,代表后面的数据是哪几个域被用到,这样就最大化的缩小了发送报文的字节数。(详细见附录A)
TPDU
报文头
应用数据
ISO8583Msg
ID
目
的
地
址
源
地
址
应
用
类
别
软
件
版
本
号
终
端
状
态
处
理
要
求
保
留
使
用
交易数据
60H
N2
N2 N2
N2
N1
N1
N6
不定长度
XXX银行对此进行了改造,加入了双倍加密模式,由于3des算法对原文字节长度要求为8的倍数,所以需要加入一个“加密信息”区域了解原始报文长度,从而能在解密后得到原始报文。
二、报文结构解读 2.1X银行pos报文格式 TPDU
报文头
加密信息
应用数据
ISO8583Msg
ID
目
的
地
址
源
地
址
应
用
类
别
软
件
版
这几天我梳理了1年以来的工作内容,并将产品经理的工作职责整理出来。按照产品阶段划分,可分为5个方面:
一、市场及用户研究 1.1、市场分析:
发现并掌握目标市场和用户需求的变化趋势,对未来几年市场上需要什么样的产品和服务做出预测;
1.2、竞品分析:
收集竞争对手的资料、试用竞争对手的产品,从而了解竞争对手产品;
1.3、用户研究:
通过定性(用户访谈)、定量(调查问卷)等分析方法对用户需求进行挖掘和分析;
二、产品规划及设计 2.1、产品规划:
确定目标市场、产品定位、发展规划及路线图;
2.2、需求管理:
对来自市场、用户等各方面的需求进行收集、汇总、分析、更新、跟踪;
2.3、产品设计:
编写产品需求文档,包括业务结构及流程、界面原型、页面要素描述等内容;
2.4、版本管理:
维护产品的每个版本的功能列表;
三、开发及项目管理 3.1、需求确认:
组织协调市场、研发等部门,对需求进行评估及确认开发周期;
3.2、项目跟踪:
跟踪项目进度,协调项目各方,推动项目进度,确保完成项目按计划完成;向领导及相关部门沟通项目进度;
3.3、产品测试:
配合测试部门完成产品的测试工作;BUG管理;
四、产品运营 4.1、流程制定:
组织客服、运维部门,建立用户问题投诉、意见反馈及其他产品相关的工作流程、分工、响应时间要求;
4.2、协调沟通:
与公司领导、相关部门协调资源、沟通产品发展规划、产品发展现状及问题;
4.3、对外合作:
与合作方商讨合作可行性、方案,参与商业合同的编写,跟踪项合作项目的进度、完成;
4.4、问题处理:
跟踪产品运营过程中出现的故障、问题,并进行总结、分析,制定解决方法或纳入到产品改进计划;协助市场、客服、运维部门,解答或协调解决用户提出的产品问题;
4.5、数据分析:
组织建立并逐步完善业务数据分析系统,确定数据报表样式,建立日/周/月报制度,整理并定期向相关部门提供产品运营数据;对产品数据进行监控,分析产品运营效果、用户使用行为及需求,以便对产品进行持续性优化和改进;
4.6、文档编写:
建立产品文档库;编写产品相关文档,如产品白皮书、用户手册、客服手册及其他产品相关文档;
4.7、培训演示:
编写培训教程,并为公司相关部门、用户进行产品培训、产品演示;
五、市场推广 5.1、营销支持:
协助营销部门,提炼产品核心价值、产品卖点、产品资料,参与制定营销、运营推广方案并提供产品支持;
5.2、市场支持:
协助市场部门,参与各类产品发布、推广及各类市场活动。
确定工作职责后,同时也就确定了日常工作文档的保持结构,这样所有的工作资料都能有条不紊地保存,以便于分类管理及查找。以下就是目前我的工作文档存放目录。
由此可见要做好产品经理真不容易,需要思考的东西多,负责的事情多,沟通的次数多。当然,如此磨练几年,收获也会很多互联网产品经理的工作职责。
php有两个json转换函数 :
json_encode 把数组转换为json
json_decode 把json转换为字符串对象, json_decode第二个参数可以使bool值
json_decode($a,true); 这样就把json对象转换为了数组。
注意:必须是utf8格式的。
在开始正文之前,首先要感谢UnitedStack工程师朱荣泽对这篇博文的大力帮助和悉心指教。本文主要针对UnitedStack公司在巴黎峰会上对Ceph可靠性的计算方法(https://www.ustack.com/blog/build-block-storage-service/)做了一个更明确的分析和阐述,供对此话题感兴趣的朋友一起来讨论、研究,文章中如果有不当之处,还请各位高人指教。
什么情况下数据会丢失? 这个话题的另外一种提法就是存储的可靠性,所谓存储的可靠性最基本的一点就是数据不要丢失,也就是我们俗称的“找不回来了”。所以,要分析Ceph的可靠性我们只需要搞清楚,到底在什么情况下我们的数据会丢失,并且再也无法恢复,基于此我们便可以创建我们的计算模型。 我们先来假定一套简单的Ceph环境,3个OSD节点,每个OSD节点对应一块物理硬盘,副本数为3。那么我们排除MON的因素影响Ceph集群的运行的问题,显而易见,当三个OSD对应的物理硬盘全部损坏时,数据必然无法恢复。所以此时集群的可靠性是与硬盘本身的可靠性直接相关。 我们再来假定一套更大的Ceph环境,30个OSD节点,分3个机架摆放,每一个机架有10个OSD节点,每个OSD节点仍然对应一块物理硬盘,副本数为3,并且通过CRUSH MAP,将每一份副本均匀分布在三个机架上,不会出现两份副本同时出现在一个机架的情况。此时,什么时候会出现数据丢失的情况呢?当三个机架上都有一块硬盘损坏,而恰恰这三块硬盘又保存了同一个Object的全部副本,此时数据就会出现丢失的情况。 所以根据以上的分析,我们认为,Ceph的可靠性的计算是与OSD的数量(N)、副本数(R)、每一个服务节点的OSD数量(S)、硬盘的年失败概率(AFR)。这里我们使用UnitedStack相关参数进行计算,具体取值如下图所示: 硬盘年失败概率 根据维基百科的计算方法(http://en.wikipedia.org/wiki/Annualized_failure_rate),AFR的计算方法如下:
例如,计算Seagate某企业级硬盘的AFR,根据文档查到MTBF为1,200,000小时,则AFR为0.73%,计算过程如下:
但是,根据Google的相关计算,在一个大规模集群环境下,往往AFR的值并没有硬盘厂商那样乐观,下面的统计告诉了我们在真实环境下AFR变化的情况:
所以我们可以看到实际的AFR的变化范围随着年份而变化,取值范围在1.7%-8%左右,所以本文中AFR为1.7%。
硬盘在一年之内损坏的概率 有了AFR,我们就可以尝试计算硬盘在一年中出现故障的概率,根据相关研究,硬盘在一定时间内的失败概率符合Possion分布(已经把知识还给老师的同学请移步:http://en.wikipedia.org/wiki/Poisson_distribution)。具体的计算公式为: 当我最初拿到这个计算公式时,一下子懵了,到底该如何确定数学期望值lamda呢? lamda的计算过程 根据相关的研究资料,单块的硬盘损坏的期望值(Failures in Time)是指每10亿小时硬盘的失败率(Failure Rate λ),计算过程如下: 这里的Af(Acceleration Factor)是由测试时间乘以阿伦尼乌斯方程的值得出来的结果,好吧,我承认,我也是现学现卖,这个方程式是化学反应的速率常数与温度之间的关系式,适用于基元反应和非基元反应,甚至某些非均相反应。不过可以看出Failure Rate的计算过程实质主要是计算环境因素引起的物理变化,最终导致失败的数学期望值。所以根据相关研究,最终FIT的计算方法为: 有了这些参数后,我们就可以开始正式计算Ceph集群中,不同机架上有三块硬盘同时出现损坏的概率啦。 任意一个OSD出现损坏的概率P1(any) 我们不太容易直接去计算任意一个OSD出现损坏的概率,但是我们很容易计算没有OSD出现问题的概率,方法如下,用一减去无OSD节点出现问题的概率,得到P1(any)。 在恢复时间内第二个节点出现故障的概率P2(any) 我们知道当Ceph发现一个有问题的OSD节点时,会自动的将节点OUT出去,这个时间大约为10min,同时Ceph的自我修复机制会自动平衡数据,将故障节点的数据重新分配在其他的OSD节点上。 我们假设我们单盘的容量为1000 GB,使用率为75%,也就是此时将有750 GB的数据需要同步。我们的数据只在本机架平衡,节点写入速度为50 MB/s,计算方法如下: 注意:由于每个节点有三个OSD,所以要求每台物理机所承受的节点带宽至少要大于150 MB/s。并且在这个计算模型下,并没有计算元数据、请求数据、IP包头等额外的信息的大小。 有了Recovery Time,我们就可以计算我们第二个节点在Recovery Time内失败的概率,具体的计算过程如下: 在恢复时间内第三个节点出现故障的概率P3(any) 计算方法同上,计算过程如下: 一年内任意副本数(R)个OSD出现故障的概率 所以将上述概率相乘即可得到一年内任意副本数(R)个OSD出现故障的概率。 Copy Sets(M) 在这个计算模型中,因为任意R个OSD节点的损坏并不意外着副本的完全丢失,因为损坏的R个OSD未必保存着一个Object的全部副本信息,所以未必造成数据不可恢复,所以这里引入了Copy Sets的概念。简单来说,Copyset就是存放所有拷贝的一个集合,具体的定义和计算方法可以查看参考链接。那么这里的场景下,Copy Sets为三个机架OSD数量相乘,即M=24*24*24。当然如果是两个副本的情况下,M应该为24*24+24*24+24*24。 CEPH的可靠性 所以最终归纳出CEPH可靠性的算法为: 可以看出Ceph三副本的可靠性大约为9个9,由于Recovery Time和AFR取值的问题,所以计算结果和UnitedStack上略有出入。 参考链接 Annualized Failure Rate
Poisson distribution
Calculating Reliability using FIT & MTTF: Arrhenius HTOL Model
Google’s Disk Failure Experience
搭建了一个confluence平台,日子久了,管理员admin密码居然忘记了。
以下恢复方法:
1. 运行此sql 找到你的管理员帐户:
select u.id, u.user_name, u.active from cwd_user u join cwd_membership m on u.id=m.child_user_id join cwd_group g on m.parent_id=g.id join cwd_directory d on d.id=g.directory_id where g.group_name = 'confluence-administrators' and d.directory_name='Confluence Internal Directory'; 并记住管理员帐户的id
2. 运行此sql, 恢复管理员密码为 admin
update cwd_user set credential = 'x61Ey612Kl2gpFL56FT9weDnpSo4AV8j8+qx2AuTHdRyY036xxzTTrw10Wq3+4qQyB+XURPWx1ONxp3Y3pB37A==' where id=xxxxxx; 注意此处xxxxxx 为上一步的 id
如果你的密码是{PKCS5S2}前缀开头的,则用下面这个sql:
update cwd_user set credential = '{PKCS5S2}ltrb9LlmZ0QDCJvktxd45WgYLOgPt2XTV8X7av2p0mhPvIwofs9bHYVz2OXQ6/kF' where id=xxxxxx; 这个管理员密码为 Ab123456
完毕!
这个问题我在网上百度了很多下终于百度出来了,现在特别的记一下,为了兼容性,我们在css中添加浏览器标识前缀,如 -webkit-opcity:0.9;
那么在js中如何设置css样式并保持兼容性呢?
this.style.webkitOpacity='0.9';
this.style.opacity='0.1';
这些就可以兼容支持opacity和webkit内核的浏览器,其他的属性也像这样就可以了。
如果你的url里面包含中文字符,你可以使用 urlencode()函数进行编码,如 $city=urlencode(”保定“), $url="http://www.kaixinbd.com?city=".$city
1. 定义一个Employee类,
该类包含:private成员变量name,age,birthday,其中 birthday 为 MyDate 类的对象;
并为每一个属性定义 getter, setter 方法;
并重写 toString 方法输出 name, age, birthday
MyDate类包含:
private成员变量month,day,year;并为每一个属性定义 getter, setter 方法;
创建该类的 5 个对象,并把这些对象放入 TreeSet 集合中(下一章:TreeSet 需使用泛型来定义)
分别按以下两种方式对集合中的元素进行排序,并遍历输出:
1). 使Employee 实现 Comparable 接口,并按 name 排序
2). 创建 TreeSet 时传入 Comparator对象,按生日日期的先后排序。
package A; /** * Created by left on 17/10/13. */ public class MyDate { private int year; private int month; private int day; public int getYear() { return year; } public void setYear(int year) { this.