首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 50)——扩展计算属性、方法

可以在原始类型上扩展计算属性,包括实例计算属性和静态计算属性。添加计算属性的定义,与普通的计算属性的定义是一样的。 实例计算属性示例:在网络编程时,为了减少流量,从服务器端返回的不是信息描述,而是编码,然后在本地再将编码转换为描述信息。为此定义了如下Int类型扩展: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 extensionInt{ //定义Int类型的扩展 varerrorMessage:String{ //只读计算属性 varerrorStr= "" switch (self){ case - 7 : errorStr= "没有数据。" case - 6 : errorStr= "日期没有输入。" case - 5 : errorStr= "内容没有输入。" case - 4 : errorStr= "ID没有输入。" case - 3 : errorStr= "据访问失败。" case - 2 : errorStr= "您的账号最多能插入10条数据。" case - 1 : errorStr= "用户不存在,请到http://51work6.com注册。" default : errorStr= "" } return errorStr } } letmessage=(- 7 ).errorMessage //获得-7编码对应的描述信息 print( "ErrorCode:-7,ErrorMessage:\(message)" ) 注意整个-7包括负号是一个完整的实例,因此调用它的属性时需要将-7作为一个整体用小括号括起来。然而,如果是7则不需要括号。 下面再看一个静态属性的示例: 1 2 3 4 5 6 7 8 9 10 11 12 structAccount{ //定义Account结构体 varamount:Double= 0.0 //账户金额 varowner:String= "" //账户名 } extensionAccount{ //定义Account结构体的扩展静态 static varinterestRate:Double{ //利率 return0. 0668 } } print(Account.interestRate) //打印输出interestRate属性 打印输出interestRate属性,访问方式与其他的静态计算属性一样,通过“类型名”加“.”来访问静态计算属性。 扩展方法 可以在原始类型上扩展方法,包括实例方法和静态方法。这些添加方法的定义与普通方法的定义是一样的。 下面先看一个示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 extensionDouble{ //定义Double类型的扩展 static varinterestRate:Double= 0.0668 //利率 funcinterestBy1()->Double{ return self*Double.interestRate //静态属性利率 } mutatingfuncinterestBy2(){ //定义实例方法interestBy2 self=self*Double.interestRate } static funcinterestBy3(amount:Double)->Double{ //定义静态方法interestBy3 return interestRate*amount //返回值是计算利息结果 } } letinterest1=(10_000. 00 ).interestBy1() //调用interestBy1方法计算利息 print( "利息1:\(interest1)" ) varinterest2=10_000. 00 //调用interestBy2方法计算利息 interest2.interestBy2() print( "利息2:\(interest2)" ) varinterest3=Double.interestBy3(10_000. 00 ) //调用interestBy3方法计算利息 print( "利息3:\(interest3)" ) 代码self = self *Double.interestRate,把计算结果直接赋值给当前实例self。在结构体和枚举类型中给self赋值会有编译错误,需要在方法前面加上mutating关键字,表明这是变异方法。 调用interestBy1方法计算利息,调用它的实例10_000.00,它的返回值被赋值给interest1常量,这是很常见的调用过程。 调用interestBy2方法计算利息,我们不能使用10_000.00实例调用,而是需要一个Double类型的变量interest2。interestBy2是变异方法,它会直接改变变量interest2的值,因此interest2.interestBy2()语句调用完成后,变量interest2的值就改变了。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1747538,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 24)——枚举(Day 24)——枚举

Swift中的枚举可以定义一组常量、提高程序的可读性;还具有面向对象特性。 使用enum关键词声明枚举类型,具体定义放在一对大括号内,枚举的语法格式如下: enum枚举名 { 枚举的定义 } “枚举名”是该枚举类型的名称。它首先应该是有效的标识符,其次应该遵守面向对象的命名规范,它由一组成员值和一组相关值组成。 成员值 枚举的成员值默认情况下不是整数类型,以下代码是声明枚举示例: 1 2 3 4 5 6 7 enum WeekDays{ case Monday case Tuesday case Wednesday case Thursday case Friday } 在这些成员值前面要加上case关键字,也可以将多个成员值放在同一行,用逗号隔开,如下所示: 1 2 3 enum WeekDays{ case Monday,Tuesday,Wednesday,Thursday,Friday } 下面我们看一个示例,代码如下: 1 2 3 varday=WeekDays.Friday day=WeekDays.Wednesday day=.Monday 使用枚举成员赋值时候,我们可以采用完整的“枚举类型名.成员值”的形式,也可以省略枚举类型采用“.成员值”的形式。这种省略形式能够访问的前提是,Swift编译器能够根据上下文环境推断类型。因为我们已经在第1行和第2行给day变量赋值,所以即使第3行代码采用缩写,Swift编译器能够推断出数据类型是WeekDays。 原始值 出于业务上的需要,要为每个成员提供某种基本数据类型,我们可以为枚举类型提供原始值(raw values)声明,这些原始值类型可以是:字符、字符串、整数和浮点数等。 原始值枚举的语法格式如下: 1 2 3 4 5 enum 枚举名:数据类型 { case 成员名=默认值 ... } 在“枚举名”后面跟“:”和“数据类型”就可以声明原始值枚举的类型,然后在定义case成员的时候需要提供原始值。 以下代码是声明枚举示例: 1 2 3 4 5 6 7 enum WeekDays:Int{ case Monday= 0 case Tuesday= 1 case Wednesday= 2 case Thursday= 3 case Friday= 4 } 我们声明的WeekDays枚举类型的原始值类型是Int,需要给每个成员赋值,只要是Int类型都可以,但是每个分支不能重复。 相关值 在Swift中除了可以定义一组成员值,还可以定义一组相关值(associated values),它有点类似于C中的联合类型。下面看一个枚举类型的声明: 1 2 3 4 enum Figure{ case Rectangle(Int,Int) case Circle(Int) } 枚举类型Figure(图形)有两个相关值:Rectangle(矩形)和Circle(圆形)。Rectangle和Circle是与Figure有关联的相关值,它们都是元组类型,对于一个特定的Figure实例,只能是其中一个相关值。从这一点来看,枚举类型的相关值类似于C中的联合类型。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746420,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop Hive概念学习系列之hive的索引及案例(八)

hive里的索引是什么? 索引是标准的数据库技术,hive 0.7版本之后支持索引。Hive提供有限的索引功能,这不像传统的关系型数据库那样有“键(key)”的概念,用户可以在某些列上创建索引来加速某些操作,给一个表创建的索引数据被保存在另外的表中。 Hive的索引功能现在还相对较晚,提供的选项还较少。但是,索引被设计为可使用内置的可插拔的java代码来定制,用户可以扩展这个功能来满足自己的需求。 当然不是说有的查询都会受惠于Hive索引。用户可以使用EXPLAIN语法来分析HiveQL语句是否可以使用索引来提升用户查询的性能。像RDBMS中的索引一样,需要评估索引创建的是否合理,毕竟,索引需要更多的磁盘空间,并且创建维护索引也会有一定的代价。 用户必须要权衡从索引得到的好处和代价。 Hive的索引目的是什么? Hive的索引目的是提高Hive表指定列的查询速度。 没有索引时,类似'WHERE tab1.col1= 10' 的查询,Hive会加载整张表或分区,然后处理所有的rows。但是如果在字段col1上面存在索引时,那么只会加载和处理文件的一部分。与其他传统数据库一样,增加索引在提升查询速度时,会消耗额外资源去创建索引和需要更多的磁盘空间存储索引。 Hive 0.7.0版本中,加入了索引。Hive 0.8.0版本中增加了bitmap索引。 如何在hive里创建索引? 说明:索引测试表是user,索引是user_index。 步骤一:先创建索引测试表 create table user( id int, name string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE; 步骤二:往索引测试表里导入数据 LOAD DATA LOCAL INPATH '/export1/tmp/wyp/row.txt' OVERWRITE INTO TABLE user; 步骤三:给索引测试表,创建索引之前测试 SELECT * FROM user where id =500000; 默认会去,加载整张表或分区,然后处理所有的rows。 Total MapReduce jobs = 1 Launching Job 1 out of 1 ....... Ended Job = job_1384246387966_0247 MapReduce Jobs Launched: Job 0: Map: 2 Cumulative CPU: 5.63 sec HDFS Read: 361084006 HDFS Write: 357 SUCCESS Total MapReduce CPU Time Spent: 5 seconds 630 msec OK 500000 wyp.Time taken: 14.107 seconds, Fetched: 1 row(s) 可以看出,一共用了14.107s。 步骤四:对索引测试表,创建索引,即这里是在表的属性id上,创建索引 hive > CREATE INDEX user_index ON TABLE user(id) //索引一定是建立在某个属性或某些属性上的 > AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' > WITH deferred REBUILD > IN TABLE user_index_table; 或者 CREATE INDEX user_index ON TABLE user(id) AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' WITH deferred REBUILD IN TABLE user_index_table; 这样就对索引测试表user创建好了一个索引。索引名字为user_index。创建索引后的表命名为, user_index_table。 步骤五: 填充索引测试表的索引数据 ALTER INDEX user_index on user REBUILD; 步骤六:查看下创建索引后的表的内容 hive> SELECT * FROM user_index_table LIMIT 5; 0 hdfs://mycluster/user/hive/warehouse/table02/000000_0 [0] 1 hdfs://mycluster/user/hive/warehouse/table02/000000_0 [352] 2 hdfs://mycluster/user/hive/warehouse/table02/000000_0 [704] 3 hdfs://mycluster/user/hive/warehouse/table02/000000_0 [1056] 4 hdfs://mycluster/user/hive/warehouse/table02/000000_0 [1408] Time taken: 0.244 seconds, Fetched: 5 row(s) 步骤七:对创建索引后的user再进行测试 hive> select * from user where id =500000; 在表user的字段id上面存在索引时,那么只会加载和处理文件的一部分。 Total MapReduce jobs = 1 Launching Job 1 out of 1 ... MapReduce Total cumulative CPU time: 5 seconds 630 msec Ended Job = job_1384246387966_0247 MapReduce Jobs Launched: Job 0: Map: 2 Cumulative CPU: 5.63 sec HDFS Read: 361084006 HDFS Write: 357 SUCCESS Total MapReduce CPU Time Spent: 5 seconds 630 msec OK 500000 wyp.Time taken: 13.042 seconds, Fetched: 1 row(s) 可以看出,明显加快了些。 扩展 若在Hive创建索引还存在bug:如果表格的模式信息来自SerDe,Hive将不能创建索引: hive> CREATE INDEX employees_index > ON TABLE employees (country) > AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' > WITH DEFERRED REBUILD > IDXPROPERTIES ('creator' = 'me','created_at' = 'some_time') > IN TABLE employees_index_table > COMMENT 'Employees indexed by country and name.'; FAILED: Error in metadata: java.lang.RuntimeException: \ Check the index columns, they should appear in the table being indexed. FAILED: Execution Error, return code 1 from \ org.apache.hadoop.hive.ql.exec.DDLTask 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/6104090.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day54)——抛出错误

能放到try后面调用函数或方法都是有要求的,他们是有可能抛出错误,在这些函数或方法声明的参数后面要加上throws关键字,表示这个函数或方法可以抛出错误。 声明抛出错误方法示例代码如下: 1 2 3 4 5 6 7 8 //删除Note记录方法 funcremove(model:Note) throws { ... } //查询所有记录数据方法 funcfindAll() throws ->[Note]{ ... } 上述代码remove(_:)方法没有返回值,throws关键字放到参数后面。findAll()有返回值throws关键字放到参数和返回值类型之间。 在函数或方法中抛出错误 一个函数或方法能够声明抛出错误,是因为在函数或方法中产生并抛出了错误,这样函数或方法声明抛出错误才有实际的意义。 在产生并抛出错误方式: 在函数或方法中通过throw语句,人为地抛出错误。 在函数或方法中调用的其他可以抛出错误函数或方法,但是没有捕获处理,会导致错误被传播出来。 示例代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //删除Note方法 funcremove(model:Note) throws { guardletdate=model.date else { //判断抛出时候是有了guard语句 //抛出"主键为空"错误 throw DAOError.PrimaryKeyNull } //比较日期主键是否相等 for (index,note)inlistData.enumerate()wherenote.date==date{ listData.removeAtIndex(index) } } //查询所有数据方法 funcfindAll() throws ->[Note]{ guardlistData.count> 0 else { //判断抛出时候是有了guard语句 //抛出"没有数据"错误。 throw DAOError.NoData } return listData } funcprintNotes() throws { //声明抛出错误 letdatas= try findAll() for noteindatas{ print( "date:\(note.date!)-content:\(note.content!)" ) } } try printNotes() guard语句最擅长处理这种早期判断,条件为false情况下抛出错误。 findAll()语句本身有可能产生错误,但是并没有使用catch语句捕获并处理,这样就导致了这个错误传播给该函数或方法的调用者,如果它的调用者也都不捕获处理,那么最后程序会出现运行期错误。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1748307,如需转载请自行联系原作者

优秀的个人博客,低调大师

Linux学习之CentOS(三十三)--DNS基础及域名系统架构

本篇文章将主要讲解DNS的一些基础知识以及域名的系统架构,当然这篇随笔是为后面的配置自己的DNS服务器来奠定基础的... 一、域名 在讲解DNS之前,首先粗略的说一下域名这个东西 比如说我们在用浏览器访问网址的时候,我们输入的网站的地址就是一个域名,例如 www.google.com,但其实我们知道我们标志互联网中的每一个机器都是有一个IP地址的,我们若需要访问一个网站的服务器,实际上是需要输入该网站的IP地址来进行访问的,但是IP地址往往难以记忆,IPv4尚且难记,IPv6就更不用说了,所以我们就通过使用域名来对其进行管理,但是在访问的时候,系统底层还是通过ip地址来进行访问的,域名和IP地址直接的转换就是通过DNS服务器来完成的。首先我们先来看看域名的一些知识,就拿 www.google.com 这个域名来说。 通常对于一个域名来说,其主要分为3个部分 www.google.com主机名域名类型 ①类型 标志着该域名的类型(com、cn、edu、org等) ②域名 域的名称,如上面的 google ③主机名 域里面一台主机的名字,如www这台主机 其实严格的来说,域名后面还有一个 ".",所以完整的域名应该是 www.google.com. 对于域名来说,其大小写是不敏感的,在浏览器里面我们输入大小写都指向的同一个ip地址 二、DNS 从上面可以知道,每一个域名都对应了一个IP地址,我们访问一个域名时,其实底层的操作系统进行通信时还是通过IP地址来进行通信,所以我们就需要有一个服务能将域名转换成对应的IP地址,或者反向的将IP地址转换成域名,这个服务就是DNS(Domain Name System)。 DNS提供的服务就是在IP和域名之间进行转换,DNS服务是由DNS服务器来提供的,一般提供DNS服务的都有一个单独的DNS服务器,这个DNS服务器的作用就是用来保存我们的域名到其IP地址之间的解析,例如我们在访问 www.google.com 这个域名的时候,我们的主机首先会向一个DNS服务器发起一个DNS的请求,请求DNS服务器告诉我www.google.com这个域名的IP地址,此时DNS服务器就会给我们返回该域名的IP地址,这个时候我们再根据这个IP地址访问www.google.com这台服务器 DNS服务就是将我们的域名解析成其对应的IP地址,我们日常使用的支持网络的计算机一般是做为DNS客户端来使用的,应用程序、服务、进程等等通过操作系统底层的功能发起对DNS服务器的查询,来对指定的域名进行解析 在Linux系统当中,一般是使用系统底层提供的gethostbyname()这个函数来进行域名解析的 在Linux系统当中,解析域名通常可以基于以下三种方式: ①文件 (/etc/hosts、/etc/networks) hosts是主机文件,里面存放的是域名到IP地址的一个对应,在windows下也有这样一个文件,通常linux下通过文件来解析域名都是通过 /etc/hosts 这个文件 [root@xiaoluo~]#cat/etc/hosts127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.localdomain4 ::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6 因为hosts文件里面保存的就是域名到IP地址直接的对应关系,我们也可以手动的去将我们的域名指定为其它的IP,例如我们将 www.google.com 的 ip 修改为 192.168.1.1 [root@xiaoluo~]#pingwww.google.com PINGwww.google.com(173.194.72.103)56(84)bytesofdata. [root@xiaoluo~]#vim/etc/hosts127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.localdomain4 ::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6192.168.1.1www.google.com[root@xiaoluo~]#pingwww.google.com PINGwww.google.com(192.168.1.1)56(84)bytesofdata. 我们看到,我们在 /etc/hosts 文件里加上 192.168.1.1 www.google.com 这条映射关系以后,此时在ping www.google.com时,其ip地址变成了我们自己设定的 192.168.1.1了,但是我们知道其IP地址肯定不是这个。为此,我们可以在操作系统上将一些域名的IP地址直接写到 hosts 文件里面,这样在进行解析时可以直接去访问我们指定的IP地址 ②DNS 这个就是通过我们指定的DNS服务器来对我们的域名进行解析了 ③NIS 这个用的非常少 我们可以通过查看 /etc/nsswitch.conf 这个文件来查看DNS解析的顺序 [root@xiaoluo~]#cat/etc/nsswitch.conf # #/etc/nsswitch.conf # #AnexampleNameServiceSwitchconfigfile.Thisfileshouldbe #sortedwiththemost-usedservicesatthebeginning. # #Theentry'[NOTFOUND=return]'meansthatthesearchforan #entryshouldstopifthesearchinthepreviousentryturned #upnothing.Notethatifthesearchfailedduetosomeotherreason #(likenoNISserverresponding)thenthesearchcontinueswiththe #nextentry. # #Validentriesinclude: # #nisplusUseNIS+(NISversion3) #nisUseNIS(NISversion2),alsocalledYP #dnsUseDNS(DomainNameService) #filesUsethelocalfiles #dbUsethelocaldatabase(.db)files #compatUseNISoncompatmode #hesiodUseHesiodforuserlookups #[NOTFOUND=return]Stopsearchingifnotfoundsofar # #Tousedb,putthe"db"infrontof"files"forentriesyouwanttobe #lookedupfirstinthedatabases # #Example: #passwd:dbfilesnisplusnis #shadow:dbfilesnisplusnis #group:dbfilesnisplusnispasswd:files shadow:files group:files#hosts:dbfilesnisplusnisdns hosts:filesdns#Example-obeyonlywhatnisplustellsus... #services:nisplus[NOTFOUND=return]files #networks:nisplus[NOTFOUND=return]files #protocols:nisplus[NOTFOUND=return]files #rpc:nisplus[NOTFOUND=return]files #ethers:nisplus[NOTFOUND=return]files #netmasks:nisplus[NOTFOUND=return]files bootparams:nisplus[NOTFOUND=return]files ethers:files netmasks:files networks:files protocols:files rpc:files services:files netgroup:nisplus publickey:nisplus automount:filesnisplus aliases:filesnisplus 我们看到我们 hosts 解析的顺序先是通过 file 文件来进行解析,再是通过DNS进行解析,我们可以直接修改该文件来控制我们的查询顺序 三、DNS查询 我们可以通过 host 或者 dig 命令来查询我们域名对应的IP地址 ①host(显示内容较少) [root@xiaoluo~]#hostwww.google.com www.google.comhasaddress74.125.31.104www.google.comhasaddress74.125.31.147www.google.comhasaddress74.125.31.106www.google.comhasaddress74.125.31.99www.google.comhasaddress74.125.31.103www.google.comhasaddress74.125.31.105www.google.comhasIPv6address2404:6800:4008:c01::6a ②dig(显示内容详细) [root@xiaoluo~]#digwww.google.com ;<<>>DiG9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6<<>>www.google.com ;;globaloptions:+cmd ;;Gotanswer: ;;->>HEADER<<-opcode:QUERY,status:NOERROR,id:65143;;flags:qrrdra;QUERY:1,ANSWER:6,AUTHORITY:0,ADDITIONAL:0;;QUESTIONSECTION: ;www.google.com.INA ;;ANSWERSECTION: www.google.com.5INA74.125.31.104www.google.com.5INA74.125.31.147www.google.com.5INA74.125.31.106www.google.com.5INA74.125.31.99www.google.com.5INA74.125.31.103www.google.com.5INA74.125.31.105;;Querytime:2012msec ;;SERVER:192.168.198.2#53(192.168.198.2) ;;WHEN:MonJun319:49:552013;;MSGSIZErcvd:128 我们看到dig命令查询出来的内容非常多,对于里面的每一行语句的含义,将在后续随笔中详细讲解 对于DNS查询来说,其实DNS是一个树状的结构,查询的时候是根据域名从右到左来进行查询,域名每一级由独立的一个或者多个DNS服务器来进行查询 我们看到,当我们在对 www.google.com 这个域名进行查询时,首先是通过 . 这个根DNS服务器去查询 com 这个类型的 DNS 服务器地址,然后再通过 com 对应的多台DNS服务器(每一层都有多个DNS服务器)去查询 google 这个域名的DNS服务器,最后再通过 google的DNS服务器去查询主机名为 www 的这台主机的资源记录,从而得到 www.google.com 的IP地址。我们可以通过dig +trace www.google.com这个命令来追踪整个DNS查询的过程 [root@xiaoluo~]#dig+tracewww.google.com;<<>>DiG9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6<<>>+tracewww.google.com ;;globaloptions:+cmd .5INNSf.root-servers.net. .5INNSg.root-servers.net. .5INNSh.root-servers.net. .5INNSi.root-servers.net. .5INNSj.root-servers.net. .5INNSk.root-servers.net. .5INNSl.root-servers.net. .5INNSm.root-servers.net. .5INNSa.root-servers.net. .5INNSb.root-servers.net. .5INNSc.root-servers.net. .5INNSd.root-servers.net. .5INNSe.root-servers.net. ;;Received508bytesfrom192.168.198.2#53(192.168.198.2)in28138ms com.172800INNSa.gtld-servers.net. com.172800INNSb.gtld-servers.net. com.172800INNSc.gtld-servers.net. com.172800INNSd.gtld-servers.net. com.172800INNSe.gtld-servers.net. com.172800INNSf.gtld-servers.net. com.172800INNSg.gtld-servers.net. com.172800INNSh.gtld-servers.net. com.172800INNSi.gtld-servers.net. com.172800INNSj.gtld-servers.net. com.172800INNSk.gtld-servers.net. com.172800INNSl.gtld-servers.net. com.172800INNSm.gtld-servers.net. ;;Received492bytesfrom193.0.14.129#53(193.0.14.129)in26867ms google.com.172800INNSns2.google.com. google.com.172800INNSns1.google.com. google.com.172800INNSns3.google.com. google.com.172800INNSns4.google.com. ;;Received168bytesfrom192.54.112.30#53(192.54.112.30)in8681ms www.google.com.300INA173.194.72.103www.google.com.300INA173.194.72.99www.google.com.300INA173.194.72.106www.google.com.300INA173.194.72.104www.google.com.300INA173.194.72.147www.google.com.300INA173.194.72.105;;Received128bytesfrom216.239.38.10#53(216.239.38.10)in82ms 我们看到整个DNS查询过程就是上述的根据域名从右到左来一步步查询, . root DNS -> com DNS -> google DNS -> www DNS查询类型一共有两种,一种是 迭代查询 (Iterative Query),另一种是 递归查询 (Recursive Query)我们通过下面两个示意图就可以知道这两种查询的区别了 ①迭代查询 (Iterative Query) ②递归查询 (Recursive Query) 我们看到迭代查询时本地DNS Server会首先向 . DNS Server发出请求,此时 . DNS Server会返回给本地DNS Server com的 DNS Server,这样依次类推下去,最后将 www.google.com的ip地址返回,而递归查询,则只是本地DNS Server向 . DNS Server发出一个请求,然后解析IP是交给了其下属的DNS Server来完成,最后将IP地址返回,由于递归查询在每个DNS Server上会有缓存信息,所以一般我们都是使用两种查询方式相结合的方式来进行DNS查询的 四、资源记录 在DNS服务器上,DNS的信息都是通过一个叫做资源记录(RR Resource Record)的格式来进行保存的,RR不仅能够保存域名到IP地址的信息,还能保持其他很多的信息 资源记录常用的属性有: -NAME (主机名) -CLASS (类别,通常是IN) -TYPE (类型,资源记录的类型) -RDATA (信息) 如: www IN A 192.168.1.1 mail IN A 192.168.1.2 server1 IN CNAME www IN MX 10 mail.gmail.com.(对于MX记录,后面的域名一定要写完整,即最后的 . 也要加上) NAME CLASS TYPE RDATA 上面都是我们的资源记录。DNS的资源记录可以记录许多类型的资源,而不仅仅是IP地址,常见的资源记录类型如下: 资源记录类型(TYPE) 表示内容 A IPv4地址 AAAA IPv6地址 MX 邮件记录 CNAME 别名 PTR 指针(逆向解析) SRV 服务资源 我们可以使用DNS的高级查询命令来查看这些资源记录的信息 ①dig -t awww.google.com 查看域名的IPv4地址 [root@xiaoluo~]#dig-tawww.google.com;<<>>DiG9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6<<>>-tawww.google.com ;;globaloptions:+cmd ;;Gotanswer: ;;->>HEADER<<-opcode:QUERY,status:NOERROR,id:52161;;flags:qrrdra;QUERY:1,ANSWER:6,AUTHORITY:0,ADDITIONAL:0;;QUESTIONSECTION: ;www.google.com.INA ;;ANSWERSECTION: www.google.com.5INA74.125.31.103www.google.com.5INA74.125.31.99www.google.com.5INA74.125.31.147www.google.com.5INA74.125.31.104www.google.com.5INA74.125.31.106www.google.com.5INA74.125.31.105 // 这些都是www.google.com的IPv4地址;;Querytime:2010msec ;;SERVER:192.168.198.2#53(192.168.198.2) ;;WHEN:MonJun320:45:302013;;MSGSIZErcvd:128 ②dig -t mx gmail.com 查看gmail.com这个域名的邮件记录 [root@xiaoluo~]#dig-tmxgmail.com;<<>>DiG9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6<<>>-tmxgmail.com ;;globaloptions:+cmd ;;Gotanswer: ;;->>HEADER<<-opcode:QUERY,status:NOERROR,id:44633;;flags:qrrdra;QUERY:1,ANSWER:5,AUTHORITY:0,ADDITIONAL:4;;QUESTIONSECTION: ;gmail.com.INMX ;;ANSWERSECTION: gmail.com.5INMX40alt4.gmail-smtp-in.l.google.com. gmail.com.5INMX30alt3.gmail-smtp-in.l.google.com. gmail.com.5INMX10alt1.gmail-smtp-in.l.google.com. gmail.com.5INMX5gmail-smtp-in.l.google.com. gmail.com.5INMX20alt2.gmail-smtp-in.l.google.com. //gmail.com的邮件服务器 ;;ADDITIONALSECTION: alt3.gmail-smtp-in.l.google.com.5INAAAA2607:f8b0:400d:c02::1a alt1.gmail-smtp-in.l.google.com.5INAAAA2a00:1450:4010:c03::1b gmail-smtp-in.l.google.com.5INAAAA2607:f8b0:400e:c01::1a alt4.gmail-smtp-in.l.google.com.5INAAAA2607:f8b0:400c:c01::1a //gmail.com邮件服务器对应的IP地址 ;;Querytime:2003msec ;;SERVER:192.168.198.2#53(192.168.198.2) ;;WHEN:MonJun320:47:322013;;MSGSIZErcvd:262 ③dig -x42.121.135.98 逆向解析42.121.135.98 这个IP地址得到其域名 (博客园的IP) [root@xiaoluo~]#hostwww.cnblogs.com www.cnblogs.comhasaddress42.121.135.98[root@xiaoluo~]#dig-x42.121.135.98;<<>>DiG9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6<<>>-x42.121.135.98;;globaloptions:+cmd ;;Gotanswer: ;;->>HEADER<<-opcode:QUERY,status:NXDOMAIN,id:22590;;flags:qrrdra;QUERY:1,ANSWER:0,AUTHORITY:1,ADDITIONAL:0;;QUESTIONSECTION: ;98.135.121.42.in-addr.arpa.INPTR ;;AUTHORITYSECTION:121.42.in-addr.arpa.5INSOAhidden-master.aliyun.com.hostmaster.aliyun-inc.com.201306030072009002592000600;;Querytime:2004msec ;;SERVER:192.168.198.2#53(192.168.198.2) ;;WHEN:MonJun320:51:272013;;MSGSIZErcvd:126 以上这些都是对DNS以及域名进行一些简单的知识介绍、总结(自己感觉总结的有点繁琐哈。。。),在下一篇文章里面将详细讲解Linux下如何配置我们自己的DNS服务器。。。 本文转自sandshell博客51CTO博客,原文链接http://blog.51cto.com/sandshell/1947776如需转载请自行联系原作者 sandshell

优秀的个人博客,低调大师

Android学习之横竖屏切换与Activity生命周期的关系

这篇文章有着很详细的报告…. 走近科学 对于最后一点表达一下自己的看法… 关于横屏切换竖屏调用两次,我特地的看了一下全键盘的手机,在观察中发现 1,当推出键盘的时候,会触发硬件的改变,使手机竖屏变成了横屏 2,当推进键盘的时候,合上手机的一刻,触发的是同一样的固件,由于,固件是无法辨别那个是推进,和推出,发出的是一样的信号,然后系统就会认为这是一个横屏改变,等到合上手机的时候系统再接受到一个信号,然后切换成竖屏.这样系统,认为横屏切换竖屏改变了两次,这样就导致调用了两次onConfigurationChanged(); 为了证明这点我写了以下代码测试: 设置一个用来切换横竖屏的button privateButtonok; privatebooleanland=false; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.appwidget_configure); ok=(Button)findViewById(R.id.save_button); ok.setOnClickListener(newButtonlistener());} classButtonlistenerimplementsOnClickListener{publicvoidonClick(Viewv){ //TODOAuto-generatedmethodstub Log.d("app","ok"); if(!land){ //切换成横屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);land=true; }else{ //切换成竖屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);land=false;}}} @Override publicvoidonConfigurationChanged(ConfigurationnewConfig){ super.onConfigurationChanged(newConfig); //Checkstheorientationofthescreen if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){ Log.d("app","land"); Toast.makeText(this,"landscape",Toast.LENGTH_SHORT).show(); //切换到横屏的时候我们需要重新创建button ok=(Button)findViewById(R.id.save_button); ok.setOnClickListener(newButtonlistener()); }elseif(newConfig.orientation==Configuration.ORIENTATION_PORTRAIT){ Log.d("app","portalit"); Toast.makeText(this,"portrait",Toast.LENGTH_SHORT).show();}} 实验: 可以看出单纯的横竖屏切换,系统是只认一次的, 无论是横屏切换竖屏,还是竖屏切换横屏都只是调用了一次onConfigurationChanged(); 这个方法只是为了证明我的推测. 使用这个方法以后将会导致全键盘手机推入推出来无法切换横竖屏. PS:以前的想法白痴了..... 实际上,模拟器的翻转是以一个逆时针的方向旋转...你按两次 ctrl + f11实际上是翻转了三次... 版权声明:原创作品,如需转载,请注明出处。否则将追究法律责任

优秀的个人博客,低调大师

学习node.js第一天:node模块化

上一篇说完了如何创建一个简单的http服务,现在说说模块化. 在开发过程中,经常会说模块化这个词.那都表示什么含义呢?一般都有以下几层意思: 1.业务解耦. 业务耦合太多,后期不便于扩展和维护.这种情况常常出现于创业公司,当公司业务发展起来的时候,就会发现业务系统有严重的瓶颈,服务能力不足会制约公司的发展.所以需要把不相关的业务做成独立的系统. 2.微服务 在大的企业中经常会出现多种系统,每种系统又用到相同的功能.比喻说上传图片,如果每个开发小组都去造轮子,那就太浪费了.如果将图片上传做成单独的服务,以开发API的方式提供给大家使用,就会系统不少效率. 3.功能模块化 在同一个系统中可能会出现交叉使用别的模块的数据,大家都去操作别的业务的对应的表数据.在这种情况下,很难避免数据不会出现问题.吃蛋糕的人太多,而蛋糕只有一块,大家都动手去切的后果会怎么样?解决方案也一样,负责该模块的开发人员封装好该业务的代码,提供接口即可.而此时需要该使用该模块的人只管去调用,而不必去管背后逻辑的实现. 讲了废话一堆,现在就说说node怎么进行代码模块化,打包服务,方便其他地方调用. 模块化http服务:httpServer.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //业务功能:将http服务打包为一个模块,方便在其他地方调用 //引入http模块 var http=require( 'http' ); //封装启动http服务 var startHttp= function (){ var onRequest= function (request,response){ response.writeHead(200,{ 'Content-Type' : 'text/plain;charset=UTF-8' }); response.write( '大家好' ); response.end(); } http.createServer(onRequest).listen( '8888' ); console.log( 'Httpserverhasstarted.' ); } //exports生成模块beginStart,作用是调用启动http服务 exports.beginStart=startHttp; 调用模块服务 先创建一个统一入口的文件index.js 1 2 3 4 //引入httpServer模块 var httpServer=require( './httpServer' ); //启动httpserver服务 httpServer.beginStart(); 最后可以在终端启动服务:node index.js 打开浏览器http://localhost:8888,可以看到效果 本文转自 hgditren 51CTO博客,原文链接:http://blog.51cto.com/phpme/1893920,如需转载请自行联系原作者

优秀的个人博客,低调大师

阿里云云计算工程师ACP学习笔记--知识点总结

Elastic Compute Server 是一种处理能力可弹性伸缩的计算服务。 CPU内存需要停机,带宽不需要。 垂直:带宽 CPU 内存 水平:服务器 Region 地域 Zone 可用区 安全组, 允许包含跨可用区的实例 磁盘 只能挂在同一可用区 快照镜像 可以跨可用区,镜像可以复制到别的地域 发生故障时,实例只能在同一个可用区迁移 默认系统盘40GB-500GB ,系统盘设备名:/dev/xvda ECS创建时必须要选择镜像来确定其操作系统 更换系统盘不会更改实例的 IP 地址和 MAC 地址。 包年包月 最小一周 支持随时升级 带宽 不能提前释放 按量付费 不支持实例规格升级 带宽 可随时释放 高效云盘 20 -- 32768GB 3000* 80MBps 都是3个备份,不同交换机下的不同物理服务器上 SSD云盘 20 -- 32768GB 20000* 吞吐量 300MBps 普通云盘 2000GB 数百 30MBps 磁盘同一时间内,只能挂载在1个实例上。可设置是否随实例一起释放,只支持按量付费 一个ECS实例最多可以挂载16块数据盘 扩容需要重启服务器,手动去格式化,数据是保留的。 e2fsck -f /dev/vdb1 resize2fs /dev/vdb1 实例卸载 全部磁盘卸载 快照 磁盘数据在某个时间点的拷贝 增量快照 默认安装云盾 安全组 指定源IP地址段 CIDR Block 指定源安全组的ID(内网) 支持对入 出方向 每个用户最多100个安全组,每个安全组最多有1000个实例。 每个实例最多加入5个安全组,每个安全组最多100条规则。 安全组优先级1-100,1最大 4G内存以上不能选择32位操作系统 实例系列2 3 支持I/0优化,1的只有2C4G以上。 删除快照需要先删除相对应的镜像 每块磁盘提供 64 个快照额度 每个实例最多有10个标签 ECS API ecs.aliyuncs.com 签名机制 signature Access Key ID Accesss Key Secret 单个key 5000次/天 5个key Object Storage Server 云存储服务 可用性99.9% 可靠性 10个9 数据三备份 安全 防DDos 访问日志 无限扩展 Object put 5GB multipart 上传最大48.8TB 必须包含在Bucket Bucket 命名空间 1个用户最多10个 全局唯一 不能修改 容量最高2PB Server 虚拟存储空间 (用户) Access ID & Key 用户标示 API密钥 Bcuket 不可以修改所属可用区 三级域名 bucketname.endpoint 只有使用ECS实例用户 才能通过OSS内网地址访问,免流量 必须在同一区域 http://bucket名字.数据中心服务域名/object名字 私有 公共读 公共读写 不允许删除非空的bucket 没有任何碎片以及object 过期时间 自定义空间 批量删除最多1000个object 每个bucket可以绑定20个域名 当Object的Content-Type=application/octet-stream,采用OSS外网地址访问一个文件格式为jpg的Object ,默认直接下载 基于header中表头 referer 防盗链 白名单为空: -不会检查referer字段是否为空(不然所有的请求都会被拒绝) 白名单不为空: - 且设置了不允许referer字段为空的规则,则只有referer属于白名单的请求才允许,其他(包括referer为空)会被拒绝 - 设置了允许referer字段为空的故障,则referer为空的请求和符合白名单的请求会被允许;其他请求会被拒绝。 如果用浏览器浏览,需要设置允许 referer字段为空。 日志记录 用户自定义 源bucket 时间 OSS系统生成的字符串 图片服务 样式功能(将一系列的复杂的处理参数用简单的别名去代表) 规则 @ 样式@!别名(避免URL太长) 管道 | 多个处理动作一起操作 先关闭图片处理服务,再删除bucket Public-read-write Public-read 创建者可以写 Private 服务器端加密 防盗链 bucket权限控制 Acccess ID 和请求签名 OSS 本身不提供IP黑名单,但是可以通过CDN来间接使用IP黑白名单 弹性伸缩服务 免费 定时任务 20个 同一时间内的,会选取最近创建的定时任务执行 报警任务 名称唯一 必须指定ECS实例 支持RDS访问白名单 伸缩组 Scaling Group ECS实例的集合,最小值,最大值 权限最高 伸缩配置 Scaling Configuration ECS实例的规格 伸缩规则 Scaling Rule 扩展或收缩个数 伸缩活动 Scaling Activity 规则成功出发后,产生一个伸缩活动。(同一伸缩组内,同一时刻只能有一个伸缩活动在执行,无法终止互动) 伸缩触发任务 Scaling Trigger Task 用于触发伸缩规则的任务。 定时报警任务 冷却时间 Cooldown Period 伸缩活动完成后的 锁定时间 (只会拒绝云监控报警任务类型的伸缩活动请求,其他手工、定时可以绕过冷却时间)(最后一个成功后) 触发伸缩规则的任务独立于伸缩组存在,删除伸缩组不会删除任务 生效,失效,删除中 修改伸缩组属性时,地域 SLB RDS 不可以修改| 生效和失效 才可以修改 强制删除 1个伸缩桌10个伸缩规则,1个用户最多伸缩100个ECS 手工加入既有的ECS实例: 1,判断伸缩组的健康状态、边界条件和ECS实例的状态、类型。 2,分配ActivityId和执行伸缩活动。 3,加入ECS实例 4,修改Total Capacity。 5,添加RDS白名单 6,挂载SLB,将权重设为0。 7,等待60秒后,将权重设为50。 8,伸缩活动完成,启动cooldown。 虚拟专有网络 应用层 HTTP 传输层 TCP UDP 网络层 ICMP IP 路由选择 数据链路层 ARP RARP 不同VPC之间通过隧道ID进行隔离 VRouter VSwitch Route Table 1个 Route Entry 路由条目 Elastic IP Address 专线接入 每个专有网络最多容纳200个,可以工单申请。 CIDRBlock 创建成功后,不能修改网段 删除专有网络,需要先删除里面所有的东西 每个路由表最多只能创建48个自定义路由条目 一个专有网络最多只能创建24个交换机 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 Server Load Balancer 负载均衡 高可用 低成本 安全 | 公网 私网免费 LoadBalancer 代表一个SLB实例 Listener 代表用户定制的负责均衡策略和转发规则 BackendServer是后端的一组云服务器 四层 TCP/UDP LVS 健康检查是 可以选择TCP HTTP 七层 HTTP/HTTPS Tengine 可以关闭健康检查 控制系统 用于配置和监控SLB 健康检查 会话保持 session 加权轮询WRR 加权最小连接数WLC 针对HTTPS,提供证书管理服务 使用流量 只收下行流量 (为公网出流量) 固定带宽 内网限流 1Gbps 1个SLB 最多支持50个服务监听配置 权重0-100, 0是不转发,设置后,长连接仍然存在。 实时生效 证书最多100个 每个用户最多30个SLB实例。1-65535 SLB 可以是不同Zone。 同一或不同地域,创建多个SLB, 通过DNS轮询的方式对外提供服务 不会限制SLB后面的ECS 可用性高达99.95% 安全结合云盾提供防 DDoS 攻击能力,包括 CC、SYN flood 等 DDoS 攻击方式。 负载均衡各监听连接超时时间如下: TCP 900秒 UDP 300秒 HTTP 60秒 HTTPS 60秒 Content Delivery Network 内容分发网络 将源站内容分发至全国所有的节点,缩短用户查看对象的延迟。 业务: 小文件加速 大文件加速 视频点播 视频直播 用户:快捷申请 个性化配置 报表 日志分析 OPEN API接口 防盗链支持 边缘节点 cache高速缓存 带宽峰值 流量 带宽利用率=实际使用流量GB/(带宽峰值Mbpsx10.54),1Mbps带宽每日100%利用率为10.54GB。 带宽计费:阶梯计费 智能DNS 根据客户的来源返回不同的IP地址 阿里云CDN:智能调度系统和Cacha软件 构成 | L1cache - BGP - L2cache - 源 IP 源站 OSS源站 缓存刷新 : URL刷新 目录刷新 URL预热 源站: 源站决定回源时,请求到哪个IP 回源host:回源host决定回源请求到该IP 上的哪个站点 WAF防护(WEB应用防护系统) CC防护(针对CC共计) 黑白名单 (IP) 同一时间内只能生效一种。 URL鉴权 3种方式 4层防御体系结构:网络层 主机层 应用层 数据层 安全体系: 云盾 云服务 云安全运维 安全管家:防DDOS服务、端口安全检查、异地登陆提醒、主机密码暴力破解防御、网站后门检测 安全体检:WEB漏洞检测 网页挂马检测 DDOS: DNS query Flooad 、 NTP reply Flood 清洗阈值: 自动 手动 云盾技术防护不支持防护CC攻击 安骑士: 主机密码防爆破 异地登陆报警 网站后门检测 高危漏洞修复 木马文件查杀 数据库防护: 白名单限制访问源IP 内网访问模式 防暴力破解 SQL注入防护 SQL审计 应用防火墙: 跨站攻击 CRLF攻击 SQL注入攻击 FastCGI攻击 WEBSHELL攻击 Cloud Monitor System 云监控 开放性 网络优势 开放平台支持 站点监控 云产品监控 自定义监控 报警及联系人管理 监控项目: HTTP: http.response Time & http.status 监控点:监控项的一个实例 维度: 定位监控项数据位置的维度, 目前维度用“字段信息表示” 规则: 条件 报警组 报警方式 状态码 响应时间 本文转自 295631788 51CTO博客,原文链接:http://blog.51cto.com/hequan/1974241,如需转载请自行联系原作者

优秀的个人博客,低调大师

小白学习大数据测试之hadoop hdfs和MapReduce小实战

在湿货|大数据测试之hadoop单机环境搭建(超级详细版)这个基础上,我们来运行一个官网的MapReduce demo程序来看看效果和处理过程。 大致步骤如下: 新建一个文件test.txt,内容为 Hello Hadoop Hello xiaoqiang Hello testingbang Hello http://xqtesting.sxl.cn 将test.txt上传到hdfs的根目录 /usr/lib/hadoop/hadoop-2.7.4/bin/hdfs dfs -put /root/install/test.txt / 然后浏览器访问可以看到刚才上传的文件,如下图 运行官方的一个wordcount程序来统计字符数量,命令如下: /usr/lib/hadoop/hadoop-2.7.4/bin/hadoop jar /usr/lib/hadoop/hadoop-2.7.4/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.4.jar wordcount hdfs://localhost:9000/test.txt hdfs://localhost:9000/out 解释下这个命令,大致意思是用hadoop执行一个叫hadoop-mapreduce-examples-2.7.4.jar的wordcount 方法,其中输入参数为hdfs上根目录的test.txt 文件,而输出路径为hdfs跟目录下的out目录 PS:我这里没有把hadoop配置成环境变量,所以命令很长,你可以配置下,这样命令就会短很多了,至于怎么配置,自己悟~ 执行过程如下: 执行完成之后再次刷新浏览器可以看到out目录和结果了 点击part-r-00000,在弹出的页面点击download 这时候下载会出现404,我们只需要在URL里的localhost改为你服务器的ip地址就可以下载了。下载之后用编辑器打开,内容如下: PS:你也可以用命令查看,如下图 到这里,我们既完成了hadoop环境的搭建,也完成一次MapReduce的执行。其实也算是对hadoop功能的测试。如果你都成功了,那么恭喜你!如果你没有成功,那么也恭喜你,因为你发现了自己的不足! 本文转自 小强测试帮 51CTO博客,原文链接:http://blog.51cto.com/xqtesting/2068647,如需转载请自行联系原作者

优秀的个人博客,低调大师

[Android学习笔记十]Adapter如何进行视图与数据绑定资料

Android开发中视图和数据的绑定离不开Adapt系列的类,在呈现给用户的界面友好美观和内容丰富的应用中视图为骨,内容为肉,Adapter则是骨肉相连的筋。 下图是Android类库中的Adapter类层次图: 在android support库以及更多的第三方库中存在大量的Adapter类,Adapter在视图和数据绑定中起着至关重要的桥接作用。 本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1721188,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day43)——构造函数继承

Swift中的子类构造函数的来源有两种:自己编写和从父类继承。并不是父类的所有的构造函数都能继承下来,能够从父类继承下来的构造函数是有条件的,如下所示。 条件1:如果子类没有定义任何指定构造函数,它将自动继承所有父类的指定构造函数。 条件2:如果子类提供了所有父类指定构造函数的实现,无论是通过条件1继承过来的,还是通过自己编写实现的,它都将自动继承所有父类的便利构造函数。 下面看示例代码: classPerson{ varname:String varage:Int funcdescription()->String{ return"\(name)年龄是:\(age)" } convenienceinit(){ self.init(name:"Tony") self.age=18 } convenienceinit(name:String){ self.init(name:name,age:18) } init(name:String,age:Int){ self.name=name self.age=age } } classStudent:Person{ varschool:String init(name:String,age:Int,school:String){ self.school=school super.init(name:name,age:age) } convenienceoverrideinit(name:String,age:Int){ self.init(name:name,age:age,school:"清华大学") } } classGraduate:Student{ varspecial:String="" } 来看看符合条件1的继承,Graduate继承Student,Graduate类没有定义任何指定构造函数,它将自动继承所有Student的指定构造函数。符合条件1后,Graduate从Student继承了如下指定构造函数: init(name : String,age : Int,school : String) 再看符合条件2的继承,由于Graduate实现了Student的所有指定构造函数,Graduate将自动继承所有Student的便利构造函数。符合条件2后,Graduate从Student继承了如下3个便利构造函数: init(name:String,age:Int) init(name:String) init() Student继承Person后有4个构造函数。 条件1对Student不满足,因为它有指定构造函数,Student类中的便利构造函数init (name: String, age: Int)满足了条件2,它实现了父类指定构造函数init (name: String, age: Int)。另外,由于子类构造函数与父类构造函数参数相同,需要使用override关键字,表示子类构造函数重写(overriding)了父类构造函数。 由于Student类实现了父类指定构造函数,因此也继承了父类的另外两个便利构造函数。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1747499,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop HDFS概念学习系列之HDFS的特性和目标(九)

HDFS的特性 HDFS和传统的分布式文件系统相比较,具有以下明显的特性:高度容错,可扩展性及可配置性强。由于容错性高,因此非常适合部署利用通用的硬件平台构建容错性很高的分布式系统。容易扩展是指扩展无须改变架构只需要增加节点即可,同时可配置性很强。跨平台。使用Java语言开发,支持多个主流平台环境。shell命令接口。和Linux文件系统一样,拥有文件系统shell命令,可直接操作HDFS。Web界面。NameNode和DataNode有内置的Web服务器,方便用户检查集群的当前状态。文件权限和授权。拥有和Linux系统类似的文件权限管理。机架感知功能。在调度任务和分配存储空间时系统会考虑节点的物理位置,从而实现高效访问和计算。 安全模式。一种维护需要的管理模式。Rebalancer。当DataNode之间数据不均衡时,可以平衡集群上的数据负载,实现数据负载均衡。升级和回滚。在软件更新后有异常发生的情形下,能够回滚到HDPS升级之前的状态。 HDFS的目标 HDFS作为Hadoop的分布式文件存储系统和传统的分布式文件系统有很多相同的设计目标。例如,在可伸缩性及可用性上。但是HDFS的设计前提是假设和较早的文件系统有着明显的不同之处。下面简述HDFS的设计思路和目标: 1.硬件错误 硬件组件错误是常态,而非异常情况。HDFS可能由成百上千的服务器组成,每一个服务器都是廉价通用的普通硬件,任何一个组件都有可能一直失效,因此错误检测和快速、自动恢复是HDFS的核心架构目标,同时能够通过自身持续的状态监控快速检测冗余并回复失效的组件。 2.流式数据访问 运行在HDFS上的应用和普通的应用不同,需要流式访问它们的数据集。HDFS的设计中更多考虑到了数据批处理,而不是用户交互处理。相比数据访问的低延迟,HDFS应用要求能够高速率、大批量地处理数据,极少有程序对单一的读写操作有严格的响应时间要求,更关键的问题在于数据访问的高吞吐量。POSIX标准设置的很多硬性约束对HDFS应用系统不是必需的。为了提高数据的吞吐量,在一些关键方面对POSIX的语义做了一些修改。 3.大规模数据集 运行在HDFS土的应用具有很大的数据集。HDFS上的一个典型文件,大小一般都在GB至TB。因此,需要调节HDFS以支持大文件存储。HDFS应该能提供整体较高的数据传输带宽,能在一个集群里扩展到数百个节点。一个单一的HDFS实例应该能支撑千万计的文件。 4.简化一致性模型 HDFS应用需要一个“一次写入多次读取”的文件访问模型。一个文件经过创建、写入和关闭之后就不需要改变了。这一假设简化了数据一致性问题,并且使高吞吐量的数据访问成为可能。MapReduce应用或网络爬虫应用都非常适合这个模型。目前还有计划在将来扩充这个模型,使之支持文件的附加写操作。 5.移动计算代价比移动数据代价低 一个应用请求的计算,离它操作的数据越近就越高效,这在数据达到海量级别的时候更是如此。将计算移动到数据附近,比之将数据移动到应用所在之处显然更好,HDFS提供给应用这样的接口。 6.可移植性 HDFS在设计时就考虑到平台的可移植性,这种特性方便了HDFS作为大规模数据应用平台的推广。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5081509.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 35)——会使用下标吗?

看下面的示例代码是不是使用过: 1 <span style= "font-size:14px;" >var studentList:String[] = [ "张三" , "李四" , "王五" ]<br>studentList[ 0 ] = "诸葛亮" <br><br>var studentDictionary =[ 102 : "张三" , 105 : "李四" , 109 : "王五" ]<br>studentDictionary[ 110 ] = "董六" </span> 在访问数组和字典的时候,可以采用下标访问。其中数组的下标是整数类型索引,字典的下标是它的“键”。 下标 Swift中的下标相当于Java中的索引属性和C#中的索引器。 下标访问的语法格式如下: 1 <span style= "font-size:14px;" >面向对象类型类型名 { <br> 其他属性<br> ...<br> subscript(参数: 参数数据类型) -> 返回值数据类型 { <br> get{ <br> return 返回值<br> } <br><br> set(新属性值) {<br> ...<br> } <br> } <br>}</span> 下标也有类似于计算属性的getter和setter访问器。 getter访问器是一个方法,在最后使用return语句将计算结果返回。 setter访问器“新属性值”是要赋值给属性值。参数的声明可以省略,系统会分配一个默认的参数newValue。 示例:二维数组 在Swift中没有提供二维数组,只有一维数组Array。可以自定义一个二维数组类型,然后通过两个下标参数访问它的元素,形式上类似于C语言的二维数组。 采用下标的二维数组示例代码如下: 1 <span style= "font-size:14px;" >structDoubleDimensionalArray { //定义了二维数组结构体<br> <br> let rows: Int, columns: Int //存储属性rows和columns<br> var grid: [Int]<br> <br> init(rows: Int, columns: Int) { //构造函数<br> self.rows = rows<br> self.columns = columns<br> grid = Array(count: rows * columns,repeatedValue: 0) //初始化存储属性grid<br> }<br> <br> subscript(row: Int, col: Int) -> Int { //定义下标<br> <br> get {<br> return grid[(row * columns) + col] <br> }<br> <br> set (newValue1){<br> grid[(row * columns) + col] =newValue1 <br> }<br> }<br> <br>}<br><br>var ary2 =DoubleDimensionalArray(rows: 10, columns: 10)//创建并初始化10×10大小的二维数组<br><br>//初始化二维数组<br>for var i = 0; i < 10;i++ {<br> for var j = 0; j < 10; j++ {<br> ary2[i,j] = i * j <br><br> }<br>}<br><br>//打印输出二维数组<br>for var i = 0; i < 10;i++ {<br> for var j = 0; j < 10; j++ {<br> print("\t \(ary2[i,j])")<br> }<br> print("\n")<br>}<br></span> 输出结果如下: 0 000000000 0123456789 024681012141618 0369121518212427 04812162024283236 051015202530354045 061218243036424854 071421283542495663 081624324048566472 091827364554637281 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746615,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 33)——属性观察者

为了监听属性的变化,Swift提供了属性观察者。属性观察者能够监听存储属性的变化,即便变化前后的值相同,它们也能监听到。 属性观察者主要有以下两个: willSet:观察者在修改之前调用。 didSet:观察者在修改之后立刻调用。 属性观察者的语法格式如下: 面向对象类型类型名{ 1 2 3 4 5 6 7 8 9 10 ... var存储属性:属性数据类型=初始化值{ willSet(新值){ //定义willSet观察者。“新值”是传递给willSet观察者的参数,它保存了将要替换原来属性的新值 ... } didSet(旧值){ //定义didSet观察者。“旧值”是传递给didSet观察者的参数,它保存了被新属性替换的旧值。 ... } } } 属性观察者的语法格式比计算属性要混乱。 属性观察者可以在类和结构体中使用,不能在枚举中使用。 示例代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Employee{ varno:Int= 0 varname:String= "Tony" { willSet(newNameValue){ //定义name属性的willSet观察者,newNameValue是由我们分配的传递新值的参数名 print( "员工name新值:\(newNameValue)" ) } didSet(oldNameValue){ //定义name属性的didSet观察者,oldNameValue是由我们分配的传递旧值的参数名 print( "员工name旧值:\(oldNameValue)" ) } } varjob:String? varsalary:Double= 0 vardept:Department? } structDepartment{ varno:Int= 10 { willSet{ //定义no属性的willSet观察者,注意这里没有声明参数,但是我们可以在观察者内部使用newValue print( "部门编号新值:\(newValue)" ) } didSet{ //定义no属性的didSet观察者,注意这里也没有声明参数,但是我们可以在观察者内部使用oldValue print( "部门编号旧值:\(oldValue)" ) } } varname:String= "RESEARCH" } varemp=Employee() emp.no= 100 emp.name= "Smith" vardept=Department() dept.no= 30 上述代码运行结果如下: 员工name新值:Smith 员工name旧值:Tony 部门编号新值:30 部门编号旧值:10 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746600,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册