关于这句from __future__ import absolute_import的作用: 直观地看就是说”加入绝对引入这个新特性”。说到绝对引入,当然就会想到相对引入。那么什么是相对引入呢?比如说,你的包结构是这样的: pkg/ pkg/init.py pkg/main.py pkg/string.py 如果你在main.py中写import string,那么在Python 2.4或之前, Python会先查找当前目录下有没有string.py, 若找到了,则引入该模块,然后你在main.py中可以直接用string了。如果你是真的想用同目录下的string.py那就好,但是如果你是想用系统自带的标准string.py呢?那其实没有什么好的简洁的方式可以忽略掉同目录的string.py而引入系统自带的标准string.py。这时候你就需要from __future__ import absolute_import了。这样,你就可以用import string来引入系统的标准string.py, 而用from pkg import string来引入当前目录下的string.py了
参考:https://docs.python.org/2.5/whatsnew/pep-328.html http://stackoverflow.com/questions/7075082/what-is-future-in-python-used-for-and-how-when-to-use-it-and-how-it-works
最近的项目中由于要在C++代码中调用PHP的URL,所以不得不借助libcurl这个库,由于第一次用,所以很多地方很是纠结,特此写在这里,方便给同样刚入门的朋友指引。 分两篇介绍,第一篇是理论知识,第二篇是实例。快速链接–libcurl的使用总结(一)
一.下载安装 1.到http://curl.haxx.se/download.html上下载最新版本,由于公司的机器安装rpm有依赖关系,所以直接下载了source 2.编译。解压后进入curl的目录,直接执行 make all 就行。 3.等待编译结束后,可以查看目录结构。 curl/include/curl : 头文件目录 (一般只要包含curl.h即可) curl/lib/.lib/ : lib文件目录(有libcurl.a和libcurl.so,注意,如果这两个文件在同一目录下,-lcurl默认是链接.so滴)
二.函数简要说明 在基于LibCurl的程序里,主要采用callback function (回调函数)的形式完成传输任务,用户在启动传输前设置好各类参数和回调函数,当满足条件时libcurl将调用用户的回调函数实现特定功能。下面是利用libcurl完成传输任务的流程:
1. 调用curl_global_init()初始化libcurl 2. 调用 curl_easy_init()函数得到 easy interface型指针 3. 调用curl_easy_setopt设置传输选项 4. 根据curl_easy_setopt设置的传输选项,实现回调函数以完成用户特定任务 5. 调用curl_easy_perform()函数完成传输任务 6. 调用curl_easy_cleanup()释放内存
在整过过程中设置curl_easy_setopt()参数是最关键的,几乎所有的libcurl程序都要使用它。
1)CURLcode curl_global_init(long flags); 描述: 这个函数只能用一次。(其实在调用curl_global_cleanup 函数后仍然可再用) 如果这个函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动完成。 参数:flags CURL_GLOBAL_ALL //初始化所有的可能的调用。 CURL_GLOBAL_SSL //初始化支持 安全套接字层。 CURL_GLOBAL_WIN32 //初始化win32套接字库。 CURL_GLOBAL_NOTHING //没有额外的初始化。
2)void curl_global_cleanup(void); 描述:在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。
3.char *curl_version( ); 描述: 打印当前libcurl库的版本。
4)CURL *curl_easy_init( ); 描述: curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样). 相应的在调用结束时要用curl_easy_cleanup函数清理. 一般curl_easy_init意味着一个会话的开始. 它的返回值一般都用在easy系列的函数中.
在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:
1、插入器(<<)
向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<' ';就表示把字符串"Write Stdout"和换行字符(' ')输出到标准输出流。
2、析取器(>>)
从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。
在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。
一、打开文件
在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:
void open(const char* filename,int mode,int access);
参数:
filename: 要打开的文件名 mode: 要打开文件的方式 access: 打开文件的属性
打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
ios::app: 以追加的方式打开文件 ios::ate: 文件打开后定位到文件尾,ios:app就包含有此属性 ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文 ios::in: 文件以输入方式打开 ios::out: 文件以输出方式打开 ios::nocreate: 不建立文件,所以文件不存在时打开失败 ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败 ios::trunc: 如果文件存在,把文件长度设为0 可以用“或”把以上属性连接起来,如ios::out|ios::binary
打开文件的属性取值是:
0:普通文件,打开访问 1:只读文件 2:隐含文件 4:系统文件 可以用“|”或者“+”把以上属性连接起来 ,如3或1|2就是以只读和隐含属性打开文件。
例如:以二进制输入方式打开文件c:config.sys
fstream file1;
file1.open("c:\config.sys",ios::binary|ios::in,0);
如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:
file1.open("c:\config.sys");<=>file1.open("c:\config.sys",ios::in|ios::out,0);
另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:
fstream file1("c:\config.sys");
特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。
ifstream file2("c:\pdos.def");//以输入方式打开文件
ofstream file3("c:\x.123");//以输出方式打开文件
所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
1.苹果iTunes Connect内购产品信息录入。
1)创建app内购买项目(Create New),选择类型:
1.消耗型项目 对于消耗型 App 内购买项目,用户每次下载时都必须进行购买。一次性服务通常属于消耗型项目,例如钓鱼App 中的鱼饵。
2.非消耗型项目 对于非消耗型 App 内购买项目,用户仅需要购买一次。不会过期或随使用而减少的服务通常为非消耗型项目,例如游戏App 的新跑道。
3.自动续订订阅
通过自动续订订阅,用户可以购买指定时间期限内的更新和动态内容。除非用户取消选择,否则订阅(例如杂志订阅等)会自动续订。
4.免费订阅 通过免费订阅,开发者可以将免费订阅内容放入“报刊杂志”。用户注册免费订阅后,该订阅内容将会出现在与该用户Apple ID 关联的所有设备上。请注意,免费订阅不会过期,并且仅在支持报刊杂志功能的 App 中提供。
5.非续订订阅 非续订订阅允许有时限性的营销服务。对于 App 内购买项目中的限时访问内容,就需使用非续订订阅。例如,导航App 中语音导航功能的一周订阅,或者年度订阅已存档的视频或音频的在线目录。
一定要根据自己应用的情况选择正确,不然会被App Store审核团队拒绝。应用内的虚拟币要采用消耗型的,有固定时限的会员选择自动续订订阅。也可以只选择虚拟币充值自己后台购买的情况解决会员问题。
2)生成共享密钥 共享密钥是在您联系我们的服务器获取 App 内购买项目收据时使用的唯一代码。没有共享密钥,您将无法在沙箱技术模式下测试自动续订 App 内购买项目。另外,共享密钥不能在 App Store 使用。
注:无论与哪个 App 相关联,您的所有自动续订订阅都将使用同一共享密钥。
此共享密钥用于后台服务器验证用户购买项目的凭证,生成新密要服务器也立即改变验证密钥。共享密钥在验证自动续订订阅类型项目的时候必须需要。
3)内购项目的状态 A) Pending Developer Approval – Your in apppurchase has been created but has not been tested in a sandbox environment andapproved by you.
B) Approved By Developer – Your in apppurchase has been tested in a sandbox environment and has been approved by you.
关于老师发的keil软件报错如下: --- Error: failed to execute 'd:\Keil\C51\BIN\C51.EXE' 错误是因为老师直接拷贝的安装目录,里面的TOOLS.INI配置文件仍然保留了他电脑的路径,与你放置Keil的实际路径不符。 解决办法: 找到自己的keil安装目录,下面有个TOOLS.INI文件。用记事本打开这个文件,找到: [C51] PATH="d:\Keil\C51" 或类似字样,将PATH=后面的内容改为自己keil实际安装的目录,最后一个文件夹是C51。 我的keil装在了C:\Keil这个目录,那么最后类似于这样: [C51] PATH="C:\Keil\C51" 然后保存TOOLS.INI。重启keil即可生效(务必要重启keil)。 转载于:https://www.cnblogs.com/shareidea/p/5273158.html
https://www.zhihu.com/question/36224636/answer/66618532
在电脑上开启Apache服务后,如何让外部网络访问呢?
在网上查找答案和问过一些小伙伴后,得到以以下方案。大致是在httpd.conf中加入一些语句以及利用自己的WiFi建立热点,让需要访问的设备连接上。
一、httpd.conf文件更改
1、找到httpd.conf文件位置:
在你的wamp安装目录下的\bin\apache\apache2.4.9\conf文件夹中。此台电脑上我的文件路径为:C:\wamp\bin\apache\apache2.4.9\conf
2、httpd.conf代码更改
①在第240行左右的位置将
<Directory /> AllowOverride none Require all denied </Directory> 更改为:
<Directory /> AllowOverride none #Require all denied Require all granted </Directory> 也就是允许其他请求访问。
②在第280行左右的位置在“Require local”后面加上一句:“Require all granted”
即
<Directory "c:/wamp/www/"> # # Possible values for the Options directive are "None", "All", # or any combination of: # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews # # Note that "MultiViews" must be named *explicitly* --- "Options All"
由于VBScript这门古老的编程语言并没有像ASP.NET,Servlet、Struts2,PHP等封装好文件上传的方法,绝对不可能一个request.form["file"]就能够拿到文件,因此处理文件上传是很艰难的,需要自己截获HTTP传递过来的二进制报文,进行报文中的二进制字符切割,才能拿到文件以及我们想要的信息,不过这也更接近底层,更能让我们清楚HTTP文件上传的原理。
网上一些文章的VBScript的文件上传写得天华龙凤,短短的3KB代码居然能写到16KB,让人完全看不懂在干什么。或者就是用a,b,c命名,完全不知道怎么修改。而且大多数流传下来的文章都没有考虑到如果此网站是UTF-8编码的问题,容易造成乱码,毕竟文件上传涉及二进制操作,不是一句简简单单的Response.Charset="UTF-8"然后加个<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>就能完成的事,还需要对二进制文件流的编码进行修改。甚至还有些是用AspUpload来做,你不可能保证任何一个服务器都有这个组件吧?这会严重影响迁移问题。
下面,将为大家剖析如何在ASP做文件上传,让大家也写出属于自己的文件上传类!
将完成,如下图的一个文件系统:
不仅能够完成文件上传,还能自定义服务器保存文件的文件名,比如这里以原文件名+时间戳的方式保存文件,获取用户上传的后缀(你可以据此进一步加工,限定用户上传的文件类型了)等。
具体制作过程如下:
1、首先是这个工程的目录结构:
在进行代码写作之前,请保证你网站,至少是upload_file文件夹的Web共享是打开的,在属性界面有如下图的属性:
同时,Internet来宾账户有读取、写入的权限。
不然,有可能出现二进制流无法写入文件的情况,然而VBScript这门古老的编程语言是不会报错的,每次处理二进制流出现问题,它就给你看一个完全空白页面,就只会沉默,不跟你沟通,很蛋疼的。
2、之后是upload.html这个上传表单,本来没什么好说的,主要是表单有两个小地方需要注意的,这个表单必须给file标好name,同时表示这个表单是扔二进制数据上去upload.asp,同时必须用post的方式,而不是简简单单的文件。
<!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>文件上传</title> </head> <body> <form method="post" action="upload.asp" enctype="multipart/form-data"><!--一定要有enctype="multipart/form-data",表示这个表单是传递二进制数据的,同时不能再传一些text,password这些无关的文件域上去了。--> <input type="file" name="file"/><!--这里的file文件域,就是一定要有name属性,虽然在之后的二进制处理根本没有用到这个name,你随便给个名称都行,但就是要有--> <input type="submit" value="提交" /> </form> </body> </html> 如果这个file域没有name属性的话,无论你上传什么东西,upload.asp接受到的二进制流就只能是如下的东西,换句话说,是无法接受文件的。 3、最后就是这个工程的精华,upload.asp。
首先,你完全可以在upload.asp写入如下的代码:
<% filesize=Request.TotalBytes filedata=Request.BinaryRead(Request.TotalBytes) response.BinaryWrite(filedata) %> 将接受到的二进制数据打印出来,比如你将C盘的一个内容如下的aa.txt文件在upload.html的表单提交给upload.asp的话: 上述的代码,在upload.asp打印出来的东西如下:
接下来,你的目标很明了,就是对这串二进制字符进行切割,这串二进制内容里面有我们想要的一切信息,包括文件内容、客户端上传的文件名,
里面的-----------------7e010b37206c4其实是条分割线来的,如果你的表单里面有多个带name的文件域,则你会发现系统会用-----------------7e010b37206c4将多个文件报文分割。
同时,这里有部分回车在IE6浏览器中显示不出来,你可以用查看源代码的方式,看得一清二楚。
upload.asp具体代码如下所示:
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%> <% '禁止缓存' Response.CacheControl="no-cache" Response.Expires=-1 Response.Charset="UTF-8" '配合第一行设定网页编码 if Request.TotalBytes then '如果上传文件非空' set read_stream=createobject("
软流水的原理: 1.分解同一循环内的指令相关,把指令软件方式重排, 实现指令的流水。
2. 重排后的指令,以抽取的不同次的循环代码为主体进行新的循环。
3. 由于打乱了原来的指令的顺序,比如store操作出现在了Load操作之前(当然,这个load其实是下一次循环的load),需要在新的循环进入之前有装入代码来喂饱第一次循环的store,而在新循环结束时,最后一次循环的Load指令获得的数据还没有store,所以还需要额外的排空代码。
软件流水目前没有很常见的标准的做法,现提供一个比较简单和容易理解的方式来手工实现软流水。
例子是龙芯设计师胡伟武老师的《计算机体系结构》一书的习题,代码如下;
我的思路和方法,不想码字了,,,写在了纸上,有点乱,字也差,希望不影响阅读。
为了方便大家理解,我简单说下过程:
1.画结构图:根据指令的依赖关系和代码顺序,画程序(指令)结构图,同一层的指令可以合并来处理,他们内部的顺序无所谓。这样可以简化接下来的过程。
2.循环展开:将旧循环展开几次,横着写,具体需要展开的次数,和装入代码的Load指令数有关,要确保装入代码的load的操作数可以在新的循环(竖着看,画圈的地方)结束前被store完。 根据我们的这个题目,首先新循环(画圈的地方)需要展开3次,为了能把新循环展开3次,我们的旧循环(横着看)需要展开6次。
3.确定新循环主体:竖着的画圈的指令,从上往下的顺序就是新循环的循环主体,新循环里的指令的地址下标,是接下来要确定的,也是最关键的一步。指令的下标多少,需要选一个参考点,这里选取排空代码第一行(也就是旧循环的第四次循环)为基点0,然后根据这个往上倒推,可以确定新循环的第一个store指令的地址下标为-24.然后再根据这个基点,确定新循环的其他指令的地址下标,最后加上原来的循环开销指令,就完成了新循环的主体。
4.装入代码:圆圈的左上角的指令都是装入代码,按照从上往下的顺序写下来,地址下标,根据旧循环次数一次变化,在最后一步,更新地址值时,要确保新的地址值在进入新循环时和store指向的地址对应(比如新循环的第一个store存的是第一个0(R1)的load值,而当前store -24(R1),所以R1的值在装入代码最后一步,需要加24。或者换种理解:因为前面装入代码的过程是旧循环的3次展开,所以最后R1的下标递增时应该是8*3=24了)。
5.排空代码:圆圈的右下角就是排空代码。从上往下顺序写下来。因为新循环展开了3次,所以最后的排空代码开始时的store的地址下标是-24,这样刚好把在新循环里面load的值的地址对应起来了,存的数据也就不会错了。(可以看出一个规律,新循环主体的第一个store的下标和排空指令的第一个指令下标其实是一样的。)
经过以上步骤,就可以实现一个正确的软流水了。是不是感觉软流水也没那么复杂了呢?
华南理工大学计算机考研复试,在34所408联考高校中比较特别,除去各个学校都存在的面试环节,对比于其它科目传统笔试,华南理工大学更加倾向于使用C#窗体的程序制作来进行面试复试,这与部分学校使用传统的C语言编写算法不同。华南理工大学计算机考研复试的工程量、深度堪比一个小型的软件项目。
网上一直对此资料甚小,有也是部分同学的回忆版,草草地叙述一下题目,也写写简单编程思想。并没有一份详尽的资料。这对于部分没有接触过C#窗体的同学,有点痛苦。
下面讲解如何利用C#、SQL Server2005、VS2010完成华南理工大学计算机考研复试,以最新的2015年3月份的真题为例。
首先,第一大题,10分,送分的题目:
1、创建文件夹“d:\研究生复试\[你的中文姓名]\” 例: 张三,应创建“d:\研究生复试\张三”文件夹。 所有文档和答案都放在这个文件夹中。
2、在文件夹中建立一个readme文件(.txt或.doc均可),以说明所用的软件工具。
3、设计文档,文件名为Info.doc,数据库连接说明:如用户名,密码,ODBC/JDBC等数据源配置等(数据库连接方式及配置参数)如果必要,可以说明运行方式和相关参数 如果功能不能通过运行,则给出相应的源代码。
4、在你的目录中建立SOURCE目录,系统源文件放在该目录下
5、考完后请不要关机,人离开就可以了。
答:
在做题之前,自己先检测机器有没有Visual Studio 2005/2008/2010、开始菜单,找到Microsoft SQL Server 2005这个文件夹中的SQL Server Management Studio Express,没有这里工具,马上举手,换机器。毕竟做题时间非常紧,以下的所有内容不难,对于我这样平时写程序的人来说,甚至觉得就是无聊,但是如此之多的需求,我用了远超于1个半小时完成,各位考生好自为之。
第1题,建立文件夹就不展示了,相信每一个用过计算机的同学都会,第5题自己记得别关机,相信没有考生会这么傻吧?
第4题,一会在第三大题搞C#的在一开始创建工程时候注意好路径的选择~。
第2、3题的说明文档留在最后那么的10-20分钟写,做完没做完都好,对整个工程做一个好好的总结,同时给改卷老师好好说明你做了什么,这里暂时不理会,没写完程序写毛线!
直接第二大题,数据库设计,35分
一、建立数据库,并建立以下各表 一个员工可以到多个不同公司上班。
员工关系表EMPLOYEE(员工号EmpNo,员工姓名EmpName,性别EmpSex,年龄EmpAge)
工作关系表WORKS(EmpNo员工号,CmpNo公司号,Salary薪水)
公司关系表COMPANY(CmpNo公司号,CmpName公司名)
要求:
1、在数据库中根据上述表的定义创建上述数据库,同时需建立相应的约束关系
答:(1)首先,你在开始菜单,找到Microsoft SQL Server 2005这个文件夹中的SQL Server Management Studio Express打开它,直接使用如下图的Windows 身份验证登录。
(2)之后,如下图,右击“数据库”,新建一个数据库
(3)如下图,这里以新建一个SCNT(华南理工大学的英文简称)数据库为例,虽然平时做工程没有人会修改数据库路径的,直接让系统管理的,但是,现在是考试,那你就将日志、数据两个数据库文件都改到你在第1大题、第1小题,一上来就建立的文件夹。其余所有参数不改,也没时间改,点“确定”。
(4)之后,我们在SCNT这个数据库中新建查询。
记得写完的Sql语句,要涂黑之后再执行。
(5)执行如下的SQL语句,完成这一小题。题目设置得相当阴险。一般情况下,关系表是写在所有表的结尾,最后建立的。因为关系表中的所有数据都是来自于其它表,没有其它表的结构是建立不起来的。而改卷老师,故意将关系表摆在中间。
可以看到如下的SQL语句,必须将关系表的建立,摆在最后,这3张表才能顺利建立起来。
--在数据库中根据上述表的定义创建上述数据库,同时需建立相应的约束关系 create table [EMPLOYEE]( [EmpNo] varchar(8) not null primary key, [EmpName] varchar(50) not null, [EmpSex] varchar(2) check([EmpSex]='男' or [EmpSex]='女'), [EmpAge] int check([EmpAge]>0) ) create table [COMPANY]( [CmpNo] varchar(8) not null primary key, [CmpName] varchar(50) not null ) create table [WORKS]( [EmpNo] varchar(8) references [EMPLOYEE]([EmpNo]), [CmpNo] varchar(8) references [COMPANY]([CmpNo]), [Salary] int check([Salary]>0) ) 这里,所有表名、字段名补上[],是为了避免,有某些表名、字段名触发系统的关键字。 同时注意,题目,需要同时建立约束关系。
想必很多使用MFC编程的朋友都想去用微软的控件,但是很多时候我们发现控件的功能并没有想象中的那么强大,而且很多功能我们根本都用不到,我们想去自绘控件,但是又不知道如何着手。本文介绍MFC控件设计的大致步骤。
Window窗口中的控件都是有一系列的窗口组成。其实按钮就是一个窗口,至于它是如何能嵌入到其他的窗口中呢,这就关系到一个父窗口的问题了,即按钮必须是父窗口的子窗口,并且父窗口移动及时通知子窗口移动。
了解了以上,我们就来看一下自绘控件的大致步骤吧 ①重载窗口类CShowDlg,在这里我们重载的基类为CDialog 对话框类
②插入对话框资源 IDD_DIALOG1,并绑定刚刚重载的窗口类CShowDlg
③定义重载的窗口类变量m_MyControl,并为定义的变量设计窗口风格,由于控件是一定要贴入到窗口中的,而不是弹出来,所以对话框设计风格一定要有WS_CHILD类型
④子窗口随父窗口一起移动,父窗口为对话框类,为此我们可以在父窗口上添加消息映射 ON_WM_MOVE()和 ON_WM_SIZE()及时获取父窗口的移动以及大小变化,并且使父窗口能够及时通知子窗口移动窗口以及改变窗口大小等命令。
⑤控件是禁止被鼠标拖动的,所以必须去掉标题栏属性,这样控件就不会移动了。
知道了MFC的基本原理,设计自己需要的控件不再那么难。
void CShowDlg::OnMove(int x, int y) { CDialog::OnMove(x, y); // TODO: Add your message handler code here //在移动窗口之前一定要确保m_MyControl已经创建 if (::IsWindow(m_MyControl.GetSafeHwnd())) { //x,y为父窗口左上角的坐标,子窗口CRect区域为[10,20,300,400] m_MyControl.MoveWindow(x+10,y+20,300,400); // m_MyControl.SetWindowPos(NULL,x+10,y+20,300,400,SWP_NOSIZE); } } 窗口设计风格如下所示。
ModifyStyle(0, WS_CLIPCHILDREN);// BOOL ModifyStyle ( DWORD dwRemove,// 指定修改时要删除的窗风格 DWORD dwAdd,//指定修改时将要增加的窗口风格 UINT nFlags=0//该参数将被传给SetWindowPos,否则为0,如果SetWindowPos不被调用的话,一般该参数默认值 );//如果该函数成功调用返回一个非0值,否则返回0; /* 如果nFlags不为0, ModifyStyle将调用Windows API 函数SetWindowPos并且结合nFlags和以下四个预先布置好的标志重画该窗口。 SWP_NOSIZE 保持当前大小。 SWP_NOMOVE 保持当前位置.。 SWP_NOZORDER 保持当前的Z次序。 SWP_NOACTIVATE 不激活该窗口。 */ //WinUser.h中的窗口风格如下所示。 /* * Window Styles */ #define WS_OVERLAPPED 0x00000000L #define WS_POPUP 0x80000000L #define WS_CHILD 0x40000000L #define WS_MINIMIZE 0x20000000L #define WS_VISIBLE 0x10000000L #define WS_DISABLED 0x08000000L #define WS_CLIPSIBLINGS 0x04000000L #define WS_CLIPCHILDREN 0x02000000L #define WS_MAXIMIZE 0x01000000L #define WS_CAPTION 0x00C00000L /* WS_BORDER | WS_DLGFRAME */ #define WS_BORDER 0x00800000L #define WS_DLGFRAME 0x00400000L #define WS_VSCROLL 0x00200000L #define WS_HSCROLL 0x00100000L #define WS_SYSMENU 0x00080000L #define WS_THICKFRAME 0x00040000L #define WS_GROUP 0x00020000L #define WS_TABSTOP 0x00010000L #define WS_MINIMIZEBOX 0x00020000L #define WS_MAXIMIZEBOX 0x00010000L #define WS_TILED WS_OVERLAPPED #define WS_ICONIC WS_MINIMIZE #define WS_SIZEBOX WS_THICKFRAME #define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW /* * Common Window Styles */ #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | \ WS_CAPTION | \ WS_SYSMENU | \ WS_THICKFRAME | \ WS_MINIMIZEBOX | \ WS_MAXIMIZEBOX) #define WS_POPUPWINDOW (WS_POPUP | \ WS_BORDER | \ WS_SYSMENU) #define WS_CHILDWINDOW (WS_CHILD) 其他需要了解的内容 获取屏幕大小 int nFullWidth = GetSystemMetris(SM_CXSCREEN); int nFullHeight = GetSystemMetris(SM_CYSCREEN);
我们实现的是游戏开始的时候都会有不同的游戏图片切换来给玩家展示游戏中的场景,先来看看效果图片: 当然我们可以选择很多的图片进行切换,切切切。
其实实现比较简单,运用cocos引擎的Update可以轻松地实现,下面少年来给大家详细的讲解下:
首先创建一个logoScene类: class LogoScene :public Scene { public: void update(float); virtual bool init(); CREATE_FUNC(LogoScene); private: int time ; Sprite *logo; }; 再来实现以下其中的几个函数 bool LogoScene::init() { if (!Scene::init()) return false; time = 2; logo=Sprite::create("images/logo/meng_01.jpg"); logo->setPosition(Director::getInstance()->getVisibleSize().width / 2, Director::getInstance()->getVisibleSize().height / 2);//设置图片的位置为正中心 this->addChild(logo); schedule(schedule_selector(LogoScene::update), 0.5f, kRepeatForever, 0);//开启定时器 return true; } void LogoScene::update(float t) { //time==5的时候就是图片切换完毕,可以进入下一个场景。 if (time == 5){ Scene *scene = LoadingScene::createScene(MENUSCENE, TRANSITIONFADE, pics, "sound/background-music.mp3"); Director::getInstance()->replaceScene(scene); } else { //每次设置一张不同图片 char b[100]; sprintf(b, "
面试中网络方面的知识被问到的概率很大,尤其是互联网公司,要熟悉osi七层模型,其中TCP/IP方面的知识尤其重要。如果自己平时有Socket编程的经验对面试也是很有帮助的。网络方面有空可以看看TCP/IP详解卷一和UNIX网络编程。以下总结了一些面试中常问的问题:
1、TCP为什么需要3次握手,4次断开?
“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。 client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”。主要目的防止server端一直等待,浪费资源。
为什么4次断开?
因为TCP有个半关闭状态,假设A.B要释放连接,那么A发送一个释放连接报文给B,B收到后发送确认,这个时候A不发数据,但是B如果发数据A还是要接受,这叫半关闭。然后B还要发给A连接释放报文,然后A发确认,所以是4次。
在tcp连接握手时为何ACK是和SYN一起发送,这里ACK却没有和FIN一起发送呢。原因是因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据。
2、TCP和UDP有什么区别?
TCP是传输控制协议,提供的是面向连接、可靠的字节流服务。通信双方彼此交换数据前,必须先通过三次握手协议建立连接,之后才能传输数据。TCP提供超时重传,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。UDP是用户数据报协议,是一个简单的面向无连接的协议。UDP不提供可靠的服务。在数据数据前不用建立连接故而传输速度很快。UDP主要用户流媒体传输,IP电话等对数据可靠性要求不是很高的场合。
3、交换机与路由器有什么区别?
①工作所处的OSI层次不一样,交换机工作在OSI第二层数据链路层,路由器工作在OSI第三层网络层
②寻址方式不同:交换机根据MAC地址寻址,路由器根据IP地址寻址
③转发速不同:交换机的转发速度快,路由器转发速度相对较慢。
3、TCP/IP的流量控制?
利用滑动窗口实现流量控制,如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。
TCP为每一个连接设有一个持续计时器(persistence timer)。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口控测报文段(携1字节的数据),那么收到这个报文段的一方就重新设置持续计时器。
4、TCP拥塞控制?
防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
拥塞控制代价:需要获得网络内部流量分布的信息。在实施拥塞控制之前,还需要在结点之间交换信息和各种命令,以便选择控制的策略和实施控制。这样就产生了额外的开销。拥塞控制还需要将一些资源分配给各个用户单独使用,使得网络资源不能更好地实现共享。
几种拥塞控制方法:
慢开始(slow-start )、拥塞避免(congestion avoidance )、快重传( fastretransmit )和快恢复( fastrecovery )。
慢开始和拥塞避免
发送方维持一个拥塞窗口cwnd ( congestion window )的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞。
发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。
慢开始算法:当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么就有可能引起网络拥塞,因为现在并不清楚网络的负荷情况。因此,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。通常在刚刚开始发送报文段时,先把拥塞窗口 cwnd 设置为一个最大报文段MSS的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。用这样的方法逐步增大发送方的拥塞窗口 cwnd ,可以使分组注入到网络的速率更加合理。
每经过一个传输轮次,拥塞窗口 cwnd 就加倍。一个传输轮次所经历的时间其实就是往返时间RTT。不过“传输轮次”更加强调:把拥塞窗口cwnd所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。
另,慢开始的“慢”并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,使得发送方在开始时只发送一个报文段(目的是试探一下网络的拥塞情况),然后再逐渐增大cwnd。
为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量(如何设置ssthresh)。慢开始门限ssthresh的用法如下:
当 cwnd < ssthresh 时,使用上述的慢开始算法。
当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。
拥塞避免算法:让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。过程图如下:
快速重传:
那就是收到3个相同的ACK。TCP在收到乱序到达包时就会立即发送ACK,TCP利用3个相同的ACK来判定数据包的丢失,此时进行快速重传,快速重传做的事情有:
1. 把ssthresh设置为cwnd的一半
2. 把cwnd再设置为ssthresh的值(具体实现有些为ssthresh+3)
ECharts是一个图表类JS插件,地址:http://echarts.baidu.com/index.html
学习和使用起来都比较方便,最近使用的时候发现,ECharts虽然自带的有拖拽合并的功能,但在某些时候,并不想让生成的图表具有这个功能,于是可以使用下列的方法来禁用:calculable : false,
在代码中展示为:
// echart
// 路径配置
require.config({
paths: {
echarts: '../../script/build/dist'
}
});
// 使用
require(
[
'echarts',
'echarts/chart/pie',
],
function (ec) {
// 基于准备好的dom,初始化echarts图表
var myChart = ec.init(document.getElementById('main')); var dataStyle = {
normal: {
label: {show:false},
labelLine: {show:false}
}
};
var placeHolderStyle = {
normal : {
color: 'rgba(0,0,0,0)',
label: {show:false},
labelLine: {show:false}
},
emphasis : {
color: 'rgba(0,0,0,0)'
}
};
option = {
tooltip : {
引例: NLTK中对于很多自然语言处理应用有着开箱即用的api,但是结果往往让人弄不清楚状况。 下面的例子使用NLTK进行命名实体的识别。第一例中,Apple成功被识别出来,而第二例并未被识别。究竟是什么原因导致这样的结果,接下来一探究竟。
In [1]: import nltk In [2]: tokens = nltk.word_tokenize('I am very excited about the next generation of Apple products.') In [3]: tokens = nltk.pos_tag(tokens) In [4]: print tokens [('I', 'PRP'), ('am', 'VBP'), ('very', 'RB'), ('excited', 'JJ'), ('about', 'IN'), ('the', 'DT'), ('next', 'JJ'), ('generation', 'NN'), ('of', 'IN'), ('Apple', 'NNP'), ('products', 'NNS'), ('.', '.')] In [5]: tree = nltk.ne_chunk(tokens) In [6]: print tree (S I/PRP am/VBP very/RB excited/JJ about/IN the/DT next/JJ generation/NN of/IN (GPE Apple/NNP) products/NNS .
一、增加菜单项目 选择“开始”*“运行”,输入“regedit”,打开注册表编辑器。 ① 单击 “HKEY_CLASSES_ROOT”旁边的“+”号,可以看到左边窗口中有一排文件夹,都是以Windows中应用程序建立的文件的后缀名命名的(如.doc、.xls和.html等)。 ② 找出您要增加到“新建”菜单中的文件类型的后缀名,单击鼠标右键,选择“新建”*“主键”(在注册表中,每个文件夹都是一个主键),将新的主键取名为“ShellNew”。
③ 选取新建的主键,在右边视窗空白处单击鼠标右键,选择“新增”*“字符串值”。如果您使用的文件类型,其程序预设为在启动时打开空白文件,就将新字符串名称设定为“NullFile”; 如果您使用的文件类型,其程序在启动时不会自动打开空白文件的话,请将新字符串名称设定为“FileName”。双击“FileName”字符串图标(或选中后按Enter键),在“编辑字符串”对话框的“键值”文本框中输入文件类型范本的完整路径及名称 (例如:C: \ProgramData\Microsoft\Windows\Start Menu\Programs\Mictosoft Office)。然后按确定,退出注册表编辑器。您可以立刻在“新建”菜单的文件列表中看到所做的修改。
----二、删除菜单项目
推荐:打开注册表编辑器(regedit),单击展开 [HKEY_CLASSES_ROOT] 根键,在其下找到包含“ShellNew”的子键。每一种文件类型子键下只要包含了“ShellNew”子键,就会显示在新建菜单上,例如[HKEY_CLASSES_ROOT\.txt\ShellNew] 将使右键快捷菜单中出现“新建”→“文本文件”菜单命令。因此,只需将不需要的文件类型子键下的“ShellNew”子键改为“ShellNewOld” 子键,就可以不让它在“新建”菜单中出现了。
----有许多种方法可以删除“新建”菜单中的文件类型列表,以下是3种方法。
----1.删除您不使用的程序的文件类型,最好是卸载整个应用程序。可以利用“控制面板”中的“添加/删除程序”功能。此操作同时会将“新建”菜单的文件列表中的相应项目删除。
----2.如果您自行卸载软件后,该文件类型的菜单选项仍然存在,请进入资源管理器选择“查看”*“文件夹选项”,单击“文件类型”选项卡,选取您不再使用的文件类型,单击“删除”按钮,确认删除。如此可将文件类型从关联文件菜单、注册表以及“新建”菜单中删除。
----3.如果您需要保留与文件类型相关的应用程序,只想删除“新建”菜单中的图标,请按前面说明打开注册表编辑器。单击“HKEY_CLASSES_ROOT”前的“+”号,找出含有您要删除的文件类型的扩展名的文件夹,单击旁边的“+”号。在左边的树状图中,选取正确扩展名下的“ShellNew”文件夹。此时,您可以制作一个此注册表分支的备份,以便您恢复原有的设置(选择“注册表”*“导出注册表文件”,指定文件名称及保存的位置,“导出范围”项目中必须选中“选择的分支”,然后单击“保存”)。在右边窗口中选取“NullFile”或“FileName”,按下Delete键,然后按Enter键。如果您希望将此项目恢复到功能表中,请找到您导出的.reg文件,双击将其恢复到注册表中
<!doctype html> <html lang="en" ng-app="myAPP"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://apps.bdimg.com/libs/angular.js/1.3.9/angular.min.js"></script> </head> <body> <div ng-controller="toggleController"> <button ng-click="toggle()">点击</button> <ul ng-show="menuState"> <li ng-repeat="Cateroy in Cateroyes"> <a href="{{Cateroy.id}}">id:{{Cateroy.id}} 栏目:{{Cateroy.name}}</a> </li> </ul> </div> <script> var Cateroyes=[ {"id":"1","name":"特色"}, {"id":"2","name":"简介"}, {"id":"3","name":"联系"}, {"id":"4","name":"文化"}, ]; var myAPP=angular.module('myAPP',[]); myAPP.controller('toggleController',function($scope){ $scope.menuState=false; $scope.Cateroyes=Cateroyes; $scope.toggle=function(){ $scope.menuState=!$scope.menuState; } }); </script> </body> </html>
异常处理的作用
可以拦截制定异常,并进行处理返回到制定页面。
需求举例
如我的需求当用户请求不存的页面时不能出现浏览器默认的404页面,而出现我自己定义的html也面。当出现A类异常时返回到a.html。出现B类异常返回带b.html。
项目实例
例如:当为我根本没有 ind123ex.html服务请求时。 如果我不自定义错误处理器。返回404页面 当自定义错误处理器,处理NoHandlerFoundException(404的异常)异常后返回制定的请求页面。当然你也可以拦截自定义的异常,返回到不同的页面。
以下部分对Spring异常处理器执行和加载源码进行分析 1、DispatcherServlet这个前端配置器中初始化的策略对象如下图
2、initHandlerExceptionResolvers为初始化异常处理类。 可以看到初始化异常处理集合是通过类型从上下文获取。并且通过sort对异常处理器集合排序。 排序的作用: 当发生异常时,根据异常处理器的顺序来处理异常,当有异常处理其能够处理当前异常信息时,就不再执行后面的异常处理器了。 3、异常处理信息排序 根据对象的 Order属性进行排序,如果不是Order对象类那么排序就靠后。
4、执行异常处理,可以看到当发生异常时候,按顺序执行异常处理器(this.handlerExceptionResolvers)。当有异常处理器能够处理当前一场(exMv != null)。则后面的异常处理器都不会执行。
5、默认异常顺序设置: 源代码在 org.springframework.web.servlet.config. AnnotationDrivenBeanDefinitionParser 类注释说明 可以看到 <annotation-driven/> 自动加载的异常处理 ,默认加载三个分别是( ExceptionHandlerExceptionResolver、 ResponseStatusExceptionResolver、 DefaultHandlerExceptionResolver )。 6、加载源代码分析。 在org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser 类中有分别加载上面三个异常处理器的代码如下。 ①、ExceptionHandlerExceptionResolver
②、ResponseStatusExceptionResolver
③、DefaultHandlerExceptionResolver
可以看到三个异常加载器的Order分别为(0,1,2)。
6、自定义异常处理器 (继承AbstractHandlerExceptionResolver【可设置顺序】或者HandlerExceptionResolver【不能设置顺序】)以及设置异常处理类的执行顺序
7、如果考虑自定异常处理器比默认异常处理器的优先级高。那么一定要考虑设置 Order。 如果有什么错误的地方, 欢迎大家多多指正。
a、套件测试
package com.suite; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({Test01.class,Test02.class,Test03.class}) public class SuiteTest { } b、参数化设置测试 1.更改默认的测试运行器为RunWith(Parameterized.class) 2.声明变量存放预期值和结果值 3.声明一个返回值为Collection的公共静态方法,并使用@Parameters进行修饰 例如: public static Collection<Object[]>t(){ return Arrays.asList(new Object[][]{{3,2,1}{4,2,2}}); } 4.为测试类声明一个带有参数的公共构造函数,并在其中为之声明变量赋值(预期值、输入参数值等) 5.@Test构造测试类,使用通过构造函数传入参数的相关变量写测试类
@RunWith(Parameterized.class) public class ParameterTest { int expected =0; int input1 = 0; int input2 = 0; @Parameters public static Collection<Object[]> t() { return Arrays.asList(new Object[][]{ {3,1,2}, {4,2,2} }) ; } public ParameterTest(int expected,int input1,int input2) { this.expected = expected; this.input1 = input1; this.
为什么80%的码农都做不了架构师?>>> Linux nc命令
Linux nc命令用于设置路由器。
执行本指令可设置路由器的相关参数。
语法
nc [-hlnruz][-g<网关...>][-G<指向器数目>][-i<延迟秒数>][-o<输出文件>][-p<通信端口>][-s<来源位址>][-v...][-w<超时秒数>][主机名称][通信端口...]
参数说明:
-g<网关> 设置路由器跃程通信网关,最丢哦可设置8个。
-G<指向器数目> 设置来源路由指向器,其数值为4的倍数。
-h 在线帮助。
-i<延迟秒数> 设置时间间隔,以便传送信息及扫描通信端口。
-l 使用监听模式,管控传入的资料。
-n 直接使用IP地址,而不通过域名服务器。
-o<输出文件> 指定文件名称,把往来传输的数据以16进制字码倾倒成该文件保存。
-p<通信端口> 设置本地主机使用的通信端口。
-r 乱数指定本地与远端主机的通信端口。
-s<来源位址> 设置本地主机送出数据包的IP地址。
-u 使用UDP传输协议。
-v 显示指令执行过程。
-w<超时秒数> 设置等待连线的时间。
-z 使用0输入/输出模式,只在扫描通信端口时使用。
实例
TCP端口扫描
# nc -v -z -w2 192.168.0.3 1-100 2> err.txt
192.168.0.3: inverse host lookup failed: Unknown host
(UNKNOWN) [192.168.0.3] 80 (http) open
(UNKNOWN) [192.168.0.3] 23 (telnet) open
(UNKNOWN) [192.168.0.3] 22 (ssh) open