Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 15843 articles
Browse latest View live

我所经历的“余额宝”的那些故事

$
0
0

  一年前的现在,在杭州支付宝大楼里有个叫“春秋书院”的闭关室,里面一群紧张而兴奋的年轻人在忙碌着。项目室巨大的落地窗前,站着一个面色凝重的人,他就是天弘基金创新事业部技术负责人樊振华,一个在金融IT领域有着丰富经验的老兵。他看着窗外川流不息的汽车,深深地吸了一口气。

  这是一个只有代号但没有名字的保密项目,内部称之为“2号项目”,2号项目的旺旺交流群的签名上写着“2013支付宝秘密武器”,足可见这个项目的重要性。

  截止到今天,中国近亿人因为这个项目受益,改变了自己的理财习惯。这个神秘的项目,就是余额宝。那么余额宝的初期业务背景是什么呢?由此引发出对IT系统建设的需求又是什么?

   余额宝业务背景

  在支付宝上卖基金的想法,在天弘基金电商负责人周晓明心中经过多次的思考和锤炼,已逐渐清晰。他在向阿里小微金服集团国内事业群总裁樊治铭介绍余额宝模式的雏形时,准备了5分钟内容,但只讲1分钟后,双方即达成一致意见可以做、快速做,并期望余额宝能在6月上线运营。

  双方随即行动起来,进行了简单的分工,支付宝负责余额宝在支付宝端的建设工作,而基金公司端负责与支付宝对接的直销和清算系统的建设重任,就落到了樊振华头上。

  这是一个从来没有人做过,也没有人知道该如何做的创新业务,面对支付宝巨大的用户群体,在仅不足3个月的时间内,该如何设计基金的清算和直销系统,成为了樊振华面临的头号难题。

  2013年3月,樊振华一行与支付宝技术方进行整体架构沟通,这是传统金融行业建设思路与互联网技术路线的第一次冲突,双方在闭关室足足讨论了4天,确定下来一期系统的建设目标和要解决的问题。

  当时主要面临以下难点。

  1. 要能支持“千万级”用户的系统容量。

  (1)传统的基金销售系统主要是和第三方销售机构,如银行理财专柜、网上银行进行合作销售。直销系统能够处理每天几万到几十万个用户的开户就完全够用了。但“余额宝”面对的是数以亿计的支付宝用户,用户的开户数量和并发量与传统业务有数量级的差异。

  (2)传统基金的TA系统面对的用户是以理财为目的的申购和赎回,因此每天清算的交易笔数要求也只有几万到几十万即可满足。但余额宝的业务模式里,支付宝用户的每一笔消费,都会转化为一次基金赎回,又加上海量潜在用户群,每日清算笔数将会是传统模式的百倍甚至是千倍。

  2. 直销系统和TA系统的融合。

  传统的直销和TA是分别独立的系统,但对于接入支付宝这种入口交易空前频繁、数据量极为庞大的需求而言,传统的分离式文件交互方式不能满足效率和优化利用资源的要求。因此,项目组提出了功能整合、功能简化、当前库和历史库分离的技术结构。让直销和清算系统使用同一套数据库,来避免数据拷贝带来的业务时延。

  3. 7×24小时的基金直销系统。

  由于渠道的原因,传统基金直销系统的大多数开户出现在银行的工作日。因此系统能做到5×8小时即可满足大部分客户的需求。但互联网的属性是7×24小时,因此系统也应具备7×24小时不间断的服务能力。

  4. 支付宝与天弘基金双方的数据传输与系统交互。

  余额宝的直销和清算系统会部署于天弘基金在天津的数据中心,而支付宝的“余额宝”系统部署在杭州,双方之间的通信协议,远距离数据传输面临很大的挑战。

  这样,根据早期建设需求,余额宝一期系统的架构和系统容量规划展开了序幕。

   一期系统建设

  距离上线时间只有不足3个月,樊振华和系统开发商金证科技的技术人员进行了紧张的架构工作。经过数次讨论,双方有了初步的统一意见,并形成了建设目标。

  1. 基于传统的IOE基础架构。

  在如此短的时间内,有很多功能优化、业务流程更改等开发工作,再配合相关的测试,控制改动的范围。因此基础架构决定采用传统的HP/IBM/Oracle/EMC方案,靠使用高端硬件设备的方式,提高一期系统的整体容量和性能。

  2. 直销和TA的系统整合。

  (1)为减少直销系统和TA的数据传输延迟,决定两个系统使用同一套数据库架构。

  (2)为避免单点故障引起的业务中断,应用层的直销和TA平均分布在每台服务器上,确保每个应用服务器的角色具备可替代性。

  3. 跨省的MSTP专线链路。

  天弘基金清算和交易中心在天津数据机房,通过架设两条4M的MSTP专线,连接到支付宝杭州数据机房。两条专线之间互为备份,确保通信链路安全。

  一期系统的架构如图1所示。从中可见,支付宝实时开户、申购和赎回等实时请求,与每天的离线对账文件,都通过MSTP专线与一期系统进行通信。其中实时请求通过RADWARE硬件负载均衡分发到两台前置机,前置机在做完报文解析后,将请求发送到XP的消息队列。然后由BP以主动负载均衡的机制,从XP中取出相应请求进行处理,处理结果保存到后端数据库中。

图1  一期系统构架图

   幸福的烦恼

  然而,在一期系统上线以后,面对业务量暴增的情况,系统遇到了瓶颈同时也出现了新的问题。

  2013年6月13日,一期系统如期上线,业务量远超预期,给系统来了一个“下马威”。上线后数分钟内就达到了18万的用户。在2013年6月18日晚上,余额宝的用户量已突破了100万。2013年6月30日,余额宝用户数达到251.56万。

  在如此高速的业务增长压力之下,一期系统开始面对前所未有的直销和清算压力的冲击。这个新建的系统,是否能支撑起如此大的容量冲击?什么时候系统会达到瓶颈?这些问题,悬而未解,让樊振华陷入了深深的危机感中。经过了数个失眠之夜后,他还没找到解决问题的办法,但他清楚地知道,再这样下去,一期系统将会很快面临瓶颈,成为业务增长的绊脚石。

  樊振华的担忧很快变成了现实,随着用户量的暴增,数据库的负荷越来越高,实时请求的响应时间开始变缓。清算时间由最初的半个小时慢慢地变成一个小时、两个小时、四个小时……清算系统每天会在凌晨收到支付宝最后一笔确认文件后开始清算,天弘基金的后台运营人员会等候清算出结果以后,发送给监管行和支付宝。随着这些人回家的时间越来越晚,抱怨声开始出现,樊振华的压力也随之增大。

  系统的扩容势在必行。然而,当樊振华收到金证科技发来报价表,打开第一页时,他惊呆了。如果依然使用IBM/Oracle/EMC的传统架构进行扩容,要达到预定目标,仅仅硬件设备采购及中间件的Licence费用就达到了数千万元人民币。这个数字对于樊振华来讲,甚至对于天弘基金这家公司来讲,是一个天文数字,超过了这家公司以往所有对于IT投资的总和。并且设备采购到货就要一个月以上,想在一期系统瓶颈出现前完成扩容几乎不可能实现。

  传统的路线走不通,就要找新的方法。当他得知阿里云计算作为一家云计算服务提供商,使用云计算支撑了海量的互联网企业及阿里集团自身业务时,樊振华开始和阿里云计算进行接触。2013年7月,樊振华组织阿里云、支付宝、金证科技的人一起探求解决方案。最终经过慎重思考,樊振华心一横,说了句:“不要再讨论了,上云,上阿里云!”

   上云吧,腾飞

   上云之路,困难重重,举步维艰。

  上云并非一句话那么简单,使用云计算支撑当时国内最大的基金直销和清算系统,前无古人,但开弓没有回头箭。樊振华召集了支付宝、阿里云、金证科技的人一起,启动将直销和清算系统整体迁移到云计算架构的二期系统。

  阿里金融云为二期系统提供了的云计算服务有ECS(弹性计算服务)、RDS(关系型数据库服务)和SLB(负载均衡服务)。这三个服务分别对应于一期系统中的HP和IBM服务器、Oracle数据库和硬件负载均衡设备,但这三种服务的单个实例的性能和容量,都比相应的物理设备小上一大截。如何用单机性能更小的云计算服务来支撑那些单机性能更强都难以支撑的系统呢?经过深入的了解,樊振华在心中已有了答案:“蚁群战术”。

  俗话说“三个臭皮匠,顶个诸葛亮”。“蚁群战术”就是要充分利用云计算服务的快速部署能力(5分钟内可以创建数百台ECS)、弹性伸缩能力和安全稳定等特性,使用水平拆分算法将应用系统水平拆分为数十组甚至上百组平行运行的小系统,这些小系统组合起来可以支撑起海量的请求和超高的性能。

  此时已进入到2013年7月中旬。按照对一期系统运行状况趋势的评估,一期系统的容量在没有任何运营推广活动的情况下,只能支撑到9月份便会面临瓶颈。在理清楚二期系统的性能和容量设计目标时,樊振华又接到了新的压力:天弘基金和支付宝管理层已决定余额宝要参加阿里“双十一”购物狂欢节,这对于支撑后台的技术人员来讲,绝对是一场恶战。很快,传来了支付宝对天弘提出的双十一支撑要求:

  1. 实时请求的响应要超过1000笔每秒;
  2. 清算系统要支持单日3亿笔交易清算,清算时间不得超过150分钟;
  3. 2013年10月份支付宝会展开相关运营活动,系统必须在10月份前上线。

  面对这样严酷的要求,且只有两个月的系统改造时间,项目组遇到了巨大的困难。

  1. 如何进行系统水平拆分?

  按照“蚁群战术”,需要将原有系统的业务逻辑水平拆分成多组小系统。而如何才能保证拆分尽可能平均和拆分后的扩展性是绕不过去的难点。水平拆分依据哪个字段来拆分,需要根据业务特性慎重考虑。一个细节考虑不到会导致全盘皆输。

  2. 将Oracle替换为MySQL。

  无论是单机性能还是功能,MySQL都无法与单机的Oracle匹敌。使用MySQL代替Oracle,原有的存储过程该怎么办呢?一些涉及多表join的操作在MySQL下执行效率较低该如何解决?工作量有多大?没人清楚这一系列问题的答案。

  3. 数据迁移工程浩大,难度极高。

  一期系统部署在天弘基金在天津的数据中心,而二期系统却部署在阿里云在杭州的节点,如何做到无缝割接?并且考虑到互联网用户的用户体验,一期系统和二期系统在上线期间,不允许出现业务中断,项目组必须在大数据量、异构环境、远程迁移等复杂环境下,实现无缝迁移。做到上线过程最终客户无感知。

  4. 直销和TA系统的资源争抢问题。

  一期方案将直销和TA进行了融合,来解决数据交互问题。但由于传统的TA与实时请求在不同时段运行,所以采用了主动争抢机制的负载均衡及贪婪式的CPU占用,以保证充分利用硬件资源完成业务清算。这在传统模式下没有问题,但一期系统进行合并以后,TA和实时请求的应用系统部署在同一组服务器上,每次TA系统启动清算的时间段,会严重影响实时请求的响应时间,甚至造成响应失败。

  5. 整个架构保持两年以上系统扩容能力。

  上云后的系统必须能够满足业务量飞速高涨的情况下,可以根据业务量的大小做到无缝升级。两年之内,不能因为扩容而改变系统架构。在保证扩容性的前提下,经济和投入必须控制在合理范围内。

  这些问题,不管是樊振华,还是金证科技,在分布式系统和云计算这个领域,虽然了解很多,但真正动刀枪,还是第一次。即使阿里云和支付宝的技术人员,在这么短的时间内,要解决这么多难题,也都不禁捏一把汗。

   走投无路,背水一战

  樊振华清楚自己已没有退路,只有往前走才是出路。他召集阿里云、天弘基金、金证科技和支付宝的技术人员在闭关室进行封闭式开发,一场艰苦的战役就此打响。

  “管不了那么多,这些问题只能一个一个解决。”樊振华每次面对棘手的困难时总会说这么一句。最终困难都被解决了。

  1. 系统水平拆分。系统水平拆分的基本原理很简单,就是按一个业务字段,如支付宝协议号作为拆分依据。对字段取哈希值以后根据拆分虚节点的个数进行求模。这样就可以简单地将所有请求拆分成多份。

  在二期系统的拆分过程中,经过测算,需要使用50组业务节点,但在拆分时,考虑到扩展性,并未简单地拆分成50份,而是拆分成1000份,然后每个节点处理20份数据。这样做的好处是将来如果系统遇到瓶颈,需要扩容时,不需要对拆分算法进行修改,而且数据平均迁移时只需要以库为级别进行,从而避免了拆表。

  2. 去Oracle。首先是将存储过程等MySQL不支持或支持不好的数据库逻辑上移到应用中。

  其次要将复杂度比较高的SQL语句进行拆分,变成多条简单的SQL语句,从而提高MySQL的执行效率。

  阿里云的RDS提供的慢SQL查询功能,可以将整个系统执行效率比较慢的SQL呈现给用户,帮助用户优化SQL语句。

  3. 数据迁移。数据迁移是这个项目的重头戏,迁移过程中使用全量+增量+数据订正+并行运行检查等几个阶段完成。

  二期系统在生产环境部署完成后,将在天津的一期系统的全量数据打包,按照指定拆分算法拆成1000份以后,通过专线导入到二期系统中。导入以后,将天津的一期系统前置机转发服务打开,将所有实时请求转发到二期系统,这样两个系统同时处理请求。然后,在交易日之后,以一期系统为准,将二期系统中的数据进行订正和补全。这些所有的操作必须在24小时内完成是迁移成功的必要条件。

  数据迁移成功之后,两个系统实际上在并行运行。需要使用脚本每天对比两个系统中的数据,连续2周数据对比无误以后,由支付宝将请求地址从一期系统切换到二期系统,整个迁移才算完成。

  4. 直销和TA的再次分离。借助云计算快速灵活的机制,将直销系统和TA系统的应用逻辑层进行完全分开,分开后的直销和TA系统分别运行在一组ECS中,两套系统后端连接同一套的RDS数据库服务。这样既能保证TA和直销系统在应用性能上不会发生争抢,又不会发生数据传递问题。

  5. 扩容性保证。除了在水平拆分算法时就采用双重映射的机制来保证架构本身的扩容性,还充分利用了阿里云云服务可以无缝升级的特性,来进行容量保证。

  以RDS数据库为例,阿里云提供了新1型到新7型等7个型号,性能逐渐增强。最终选择了新5型作为数据库服务器,并没有一步到位采用最高型号。这样当系统出现瓶颈时,就可以通过将所有RDS从新5型升级到更高型号来将系统容量翻倍。

图2  二期系统构架图

  这种架构(图2)将清算和直销的集群分为两组独立的集群,但使用相同的RDS数据库服务,既避免了在应用层面的资源争抢,又可以做到数据的共享。其中,实时请求会先到达4个互为冗余备份的SLB(负载均衡),避免SLB单点故障。SLB将请求转发给5台前置机,前置机会按照拆分算法,将该请求路由到相应的节点进行处理,该节点处理完毕后,数据保存到改组对应的RDS数据库。而每天的对账文件则通过文件服务器进行拆分,然后清算系统的每个节点主动取出自己处理的文件进行清算处理,再保存到数据库。

   历尽磨难,涅槃重生

  经过两个多月的封闭式开发,在上线之前,二期系统进行了严格的压力测试,测试结果让樊振华悬着的心终于放下了。

  TA系统,可以在6400秒内完成3亿笔订单的清算并将清算结果返回给支付宝,完全符合清算时间不得超过150分钟的要求。对开户的实时请求,项目目标要求达到1000笔/秒。压测的数据轻松达到5000笔/秒,并且具备11000笔/秒的储备能力随时可放开。

  二期系统终于在2013年9月26日上午正式上线成功。在上线的前一天,一期系统每天完成清算需要8个小时,而上线当天,二期系统完成了第一次清算,只用了不到30分钟。这个结果让那些经历多个不眠之夜的后台运营人员眉开眼笑,终于可以晚上回家睡觉了。

图3  实时请求的响应时间

  实时请求的响应时间老系统为180ms,上云以后,平均130ms,效果十分明显,如图3所示。

  万事俱备,只欠东风,只有经过“双十一”海量交易量的摧残,才能验证系统是符合设计要求的。

  2013年11月11日,余额宝首次参加“双十一”大促,完成1679万笔赎回,1288万笔申购的清算工作,成功为639万用户正确分配收益。当天处理了61.25亿元的消费赎回,119.97亿元的转入申购。完成这些所有的清算工作,系统只用了46分钟。

   云计算是万能的吗?

  这一路走来,直销和TA系统经历了分开、合并、再分开的演进路线,让樊振华想起一句话“天下之势,分久必合,合久必分”。过去这么多年,以IOE为主的集中式计算已告一段落,在这个互联网的时代,云计算和分布式的结合代替集中式计算已深深植入他的脑海之中。

  此时的樊振华,已和一年前的他截然不同——一年前,他还在为各种硬件选型、采购流程而忙碌。但一年后,他更喜欢在人们面前谈起的是云计算、大数据、分布式、用户体验、互联网的IT架构等名词。

  具备强大水平扩容能力的二期系统,足以让这个饱经历练的老兵高枕无忧,休息一阵子,再也不用担心系统容量和高并发的问题。但有一颗种子,在樊振华的心目中开始发芽:如今这个二期系统已不是简单的直销和清算系统,每天沉淀在50个数据库里的海量用户和交易的数据量在暴涨,如何存储这些数据?如何使用这些数据?该如何才能产生最大的价值?

   未来如何发展

  有了这颗种子,樊振华休了个短假,他又开始了新的征程,投入了大数据的怀抱,这一次,他选择了阿里云提供的ODPS(开放数据处理服务)来作为自己的大数据平台。ODPS目前是阿里集团进行离线数据处理的平台,支撑了阿里金融、淘宝等多家BU的大数据业务。有了这个平台作为后盾,樊振华清晰了很多,他脑海中复现了一幅画面:在不久的将来,通过对目前沉淀的海量数据的分析,可以把握上亿用户的理财需求及不同的风险接受能力。而天弘基金,根据这些客户的情况,提供更多更丰富的理财产品。或许到那一天,让天下所有的人享受到符合自己的理财服务真不是梦想了。

   作者白培新,阿里金融云服务业务架构师,负责金融云总体架构设计与规划。先后供职于电信、公有云服务、金融云服务等领域,“余额宝”上云过程的阿里云侧负责人。


【教育行业】互联网教育

$
0
0

目前国内外在线教育如火如荼地发展着,市场很热,但用户很冷,真正贴近用户需求的不多。大部分产品还是传统教育的填鸭式思维,无非是培训视频、课件资源、题库、个人空间、教育资讯等等,做下资源整合,较少从用户出发思考需求,从市场出发挖掘需求。

小学、初中、高中的应试教育,传统教育已经做的很好了。从互联网教育角度来讲,还需加强的是传统教育的信息化,如在线视频、在线测试、题库等等,有效补充线下教育的不足。

除开应试教育的互联网产品,素质教育、家庭教育,我觉得目前这两块是比较缺的,也是目前很多家长不是很重视的。如素质教育之舞蹈、篮球、琴棋书画等,家庭教育之为人处世、待人接物、书籍阅览等等。虽然在应试教育中不是很重要,但是在整个人生中确实非常重要的。

教育盘子很大,我觉得有必要从用户角度梳理下各种用户类型的需求:

1、老师 2、学生 3、家长 4、学校

老师:
1、提高学生成绩的需求(教学方法、教学资料、教学案例)
2、提高个人效率的需求(批改作业、解答学生的问题、想学校汇报工作)
3、完善自我的需求(网络远程教育、提高班、各类认证、与教育先锋交流)

学生:
1、全面发展自我的需求(各类知识、文体智)
2、放松自己的需求(娱乐、论坛)
3、与人交流的需求(微博、QQ、论坛)
4、展示自我的需求(个人网站、blog、空间)
5、向前辈学习的需求

家长:
1、与孩子共处的技巧(心理网站、论坛等)
2、教育孩子的技巧(案例分析、论坛等)
3、与孩子发生矛盾时渴望解决的需求(论坛求助、专家求助)
4、与其他有过成功教育孩子的家长的交流需求(各类交流平台)

学校:
1、提高学校知名度的需求(官网)
2、提高学校师资的需求(交流、比赛、招聘)
3、提高学校教师工作效率的需求(应用类网站)





作者:heyangbin 发表于2014-6-3 11:28:33 原文链接
阅读:0 评论:0 查看评论

五大常用算法:分治、动态规划、贪心、回溯和分支界定

$
0
0

分治算法

一、基本概念

   在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……

    任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。


二、基本思想及策略

   分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

   分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。

   如果原问题可分割成k个子问题,1<k≤n,且这些子问题都可解并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。


三、分治法适用的情况

    分治法所能解决的问题一般具有以下几个特征:

    1) 该问题的规模缩小到一定的程度就可以容易地解决

    2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。

    3) 利用该问题分解出的子问题的解可以合并为该问题的解;

    4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。

第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;

第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;、

第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果 具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法

第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但 一般用动态规划法较好


四、分治法的基本步骤

分治法在每一层递归上都有三个步骤:

    step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;

    step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题

    step3 合并:将各个子问题的解合并为原问题的解。

它的一般的算法设计模式如下:

    Divide-and-Conquer(P)

    1. if |P|≤n0

    2. then return(ADHOC(P))

    3. 将P分解为较小的子问题 P1 ,P2 ,...,Pk

    4. for i←1 to k

    5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi

    6. T ← MERGE(y1,y2,...,yk) △ 合并子问题

    7. return(T)

    其中|P|表示问题P的规模;n0为一阈值,表示当问题P的规模不超过n0时,问题已容易直接解出,不必再继续分解。ADHOC(P)是该分治法中的基本子算法,用于直接解小规模的问题P。因此,当P的规模不超过n0时直接用算法ADHOC(P)求解。算法MERGE(y1,y2,...,yk)是该分治法中的合并子算法,用于将P的子问题P1 ,P2 ,...,Pk的相应的解y1,y2,...,yk合并为P的解。


五、分治法的复杂性分析

    一个分治法将规模为n的问题分成k个规模为n/m的子问题去解。设分解阀值n0=1,且adhoc解规模为1的问题耗费1个单位时间。再设将原问题分解为k个子问题以及用merge将k个子问题的解合并为原问题的解需用f(n)个单位时间。用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:

 T(n)= k T(n/m)+f(n)

    通过迭代法求得方程的解:

    递归方程及其解只给出n等于m的方幂时T(n)的值,但是如果认为T(n)足够平滑,那么由n等于m的方幂时T(n)的值可以估计T(n)的增长速度。通常假定T(n)是单调上升的,从而当                  mi≤n<mi+1时,T(mi)≤T(n)<T(mi+1)。 


六、可使用分治法求解的一些经典问题

 (1)二分搜索
(2)大整数乘法
 (3)Strassen矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择

(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔

七、依据分治法设计程序时的思维过程

    实际上就是类似于数学归纳法,找到解决本问题的求解方程公式,然后根据方程公式设计递归程序。
1、一定是先找到最小问题规模时的求解方法
2、然后考虑随着问题规模增大时的求解方法
3、找到求解的递归函数式后(各种规模或因子),设计递归程序即可。

五大常用算法之二:动态规划算法

一、基本概念

    动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。

二、基本思想与策略

    基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。

    由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一个二维数组中。

    与分治法最大的差别是:适合于用动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)。

 


三、适用的情况

能采用动态规划求解的问题的一般要具有3个性质:

    (1) 最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。

    (2) 无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。

   (3)有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势)

 


四、求解的基本步骤

     动态规划所处理的问题是一个多阶段决策问题,一般由初始状态开始,通过对中间阶段决策的选择,达到结束状态。这些决策形成了一个决策序列,同时确定了完成整个过程的一条活动路线(通常是求最优的活动路线)。如图所示。动态规划的设计都有着一定的模式,一般要经历以下几个步骤。

    初始状态→│决策1│→│决策2│→…→│决策n│→结束状态

                      图1 动态规划决策过程示意图

    (1) 划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。在划分阶段时,注意划分后的阶段一定要是有序的或者是可排序的,否则问题就无法求解。

    (2) 确定状态和状态变量:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。当然,状态的选择要满足无后效性。

    (3) 确定决策并写出状态转移方程:因为决策和状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。所以如果确定了决策,状态转移方程也就可写出。但事实上常常是反过来做,根据相邻两个阶段的状态之间的关系来确定决策方法和状态转移方程。

    (4) 寻找边界条件:给出的状态转移方程是一个递推式,需要一个递推的终止条件或边界条件。

    一般,只要解决问题的阶段、状态和状态转移决策确定了,就可以写出状态转移方程(包括边界条件)。

实际应用中可以按以下几个简化的步骤进行设计:

    (1)分析最优解的性质,并刻画其结构特征。

    (2)递归的定义最优解。

    (3)以自底向上或自顶向下的记忆化方式(备忘录法)计算出最优值

    (4)根据计算最优值时得到的信息,构造问题的最优解

 


五、算法实现的说明

    动态规划的主要难点在于理论上的设计,也就是上面4个步骤的确定,一旦设计完成,实现部分就会非常简单。

     使用动态规划求解问题,最重要的就是确定动态规划三要素:

    (1)问题的阶段 (2)每个阶段的状态

    (3)从前一个阶段转化到后一个阶段之间的递推关系。

     递推关系必须是从次小的问题开始到较大的问题之间的转化,从这个角度来说,动态规划往往可以用递归程序来实现,不过因为递推可以充分利用前面保存的子问题的解来减少重复计算,所以对于大规模问题来说,有递归不可比拟的优势,这也是动态规划算法的核心之处。

    确定了动态规划的这三要素,整个求解过程就可以用一个最优决策表来描述,最优决策表是一个二维表,其中行表示决策的阶段,列表示问题状态,表格需要填写的数据一般对应此问题的在某个阶段某个状态下的最优值(如最短路径,最长公共子序列,最大价值等),填表的过程就是根据递推关系,从1行1列开始,以行或者列优先的顺序,依次填写表格,最后根据整个表格的数据通过简单的取舍或者运算求得问题的最优解。

           f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}

 


六、动态规划算法基本框架
复制代码
代码
1 for(j=1; j<=m; j=j+1) // 第一个阶段 2   xn[j] = 初始值; 3 4  for(i=n-1; i>=1; i=i-1)// 其他n-1个阶段 5   for(j=1; j>=f(i); j=j+1)//f(i)与i有关的表达式 6 xi[j]=j=max(或min){g(xi-1[j1:j2]), ......, g(xi-1[jk:jk+1])}; 8 9 t = g(x1[j1:j2]); // 由子问题的最优解求解整个问题的最优解的方案 10 11 print(x1[j1]); 12 13 for(i=2; i<=n-1; i=i+1) 15 { 17 t = t-xi-1[ji]; 18 19 for(j=1; j>=f(i); j=j+1) 21 if(t=xi[ji]) 23 break; 25 }
复制代码

五大常用算法之三:贪心算法

贪心算法

一、基本概念:
 
     所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。
     贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
    所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。

二、贪心算法的基本思路:
    1.建立数学模型来描述问题。
    2.把求解的问题分成若干个子问题。
    3.对每一子问题求解,得到子问题的局部最优解。
    4.把子问题的解局部最优解合成原来解问题的一个解。

三、贪心算法适用的问题
      贪心策略适用的前提是:局部最优策略能导致产生全局最优解。
    实际上,贪心算法适用的情况很少。一般,对一个问题分析是否适用于贪心算法,可以先选择该问题下的几个实际数据进行分析,就可做出判断。
 
四、贪心算法的实现框架
    从问题的某一初始解出发;
    while (能朝给定总目标前进一步)
    { 
          利用可行的决策,求出可行解的一个解元素;
    }
    由所有解元素组合成问题的一个可行解;
  
五、贪心策略的选择
     因为用贪心算法只能通过解局部最优解的策略来达到全局最优解,因此,一定要注意判断问题是否适合采用贪心算法策略,找到的解是否一定是问题的最优解。
 
六、例题分析
    下面是一个可以试用贪心算法解的题目,贪心解的确不错,可惜不是最优解。
    [背包问题]有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。
    要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。
    物品 A B C D E F G
    重量 35 30 60 50 40 10 25
    价值 10 40 30 50 35 40 30
    分析:
    目标函数: ∑pi最大
    约束条件是装入的物品总重量不超过背包容量:∑wi<=M( M=150)
    (1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?
    (2)每次挑选所占重量最小的物品装入是否能得到最优解?
    (3)每次选取单位重量价值最大的物品,成为解本题的策略。
    值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。
    贪心算法还是很常见的算法之一,这是由于它简单易行,构造贪心策略不是很困难。
    可惜的是,它需要证明后才能真正运用到题目的算法中。
    一般来说,贪心算法的证明围绕着:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。
    对于例题中的3种贪心策略,都是无法成立(无法被证明)的,解释如下:
    (1)贪心策略:选取价值最大者。反例:
    W=30
    物品:A B C
    重量:28 12 12
    价值:30 20 20
    根据策略,首先选取物品A,接下来就无法再选取了,可是,选取B、C则更好。
    (2)贪心策略:选取重量最小。它的反例与第一种策略的反例差不多。
    (3)贪心策略:选取单位重量价值最大的物品。反例:
    W=30
    物品:A B C
    重量:28 20 10
    价值:28 20 10
    根据策略,三种物品单位重量价值一样,程序无法依据现有策略作出判断,如果选择A,则答案错误。

 

五大常用算法之四:回溯法

1、概念

      回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。

   回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

     许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。

2、基本思想

   在包含问题的所有解的解空间树中,按照 深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。

       若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。

       而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。

3、用回溯法解题的一般步骤:

    (1)针对所给问题,确定问题的解空间:

            首先应明确定义问题的解空间,问题的解空间应至少包含问题的一个(最优)解。

    (2)确定结点的扩展搜索规则

    (3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

4、算法框架

     (1)问题框架

      设问题的解是一个n维向量(a1,a2,………,an),约束条件是ai(i=1,2,3,…..,n)之间满足某种条件,记为f(ai)。

     (2)非递归回溯框架

1: int a[n],i;
   2: 初始化数组a[];
   3: i = 1;
   4: while (i>0(有路可走)   and  (未达到目标))  // 还未回溯到头
   5: {
   6:     if(i > n)                                              // 搜索到叶结点
   7:     {   
   8:           搜索到一个解,输出;
   9:     }
  10:     else                                                   // 处理第i个元素
  11:     { 
  12:           a[i]第一个可能的值;
  13:           while(a[i]在不满足约束条件且在搜索空间内)
  14:           {
  15:               a[i]下一个可能的值;
  16:           }
  17:           if(a[i]在搜索空间内)
  18:          {
  19:               标识占用的资源;
  20:               i = i+1;                              // 扩展下一个结点
  21:          }
  22:          else 
  23:         {
  24:               清理所占的状态空间;            // 回溯
  25:               i = i –1; 
  26:          }
  27: }

(3)递归的算法框架

         回溯法是对解空间的深度优先搜索,在一般情况下使用递归函数来实现回溯法比较简单,其中i为搜索的深度,框架如下:

 1: int a[n];
   2: try(int i)
   3: {
   4:     if(i>n)
   5:        输出结果;
   6:      else
   7:     {
   8:        for(j = 下界; j <= 上界; j=j+1)  // 枚举i所有可能的路径
   9:        {
  10:            if(fun(j))                 // 满足限界函数和约束条件
  11:              {
  12:                 a[i] = j;
  13:               ...                         // 其他操作
  14:                 try(i+1);
  15:               回溯前的清理工作(如a[i]置空值等);
  16:               }
  17:          }
  18:      }
  19: }

五大常用算法之五:分支限界法

分支限界法

一、基本描述

    类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法。但在一般情况下,分支限界法与回溯法的求解目标不同。 回溯法的求解目标是找出T中满足约束条件的所有解,而 分支限界法的求解目标则是找出 满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到 极大或极小的解,即在某种意义下的 最优解

   (1)分支搜索算法

    所谓“分支”就是采用广度优先的策略,依次搜索E-结点的所有分支,也就是所有相邻结点,抛弃不满足约束条件的结点,其余结点加入活结点表。然后从表中选择一个结点作为下一个E-结点,继续搜索。

     选择下一个E-结点的方式不同,则会有几种不同的分支搜索方式。

   1)FIFO搜索

   2)LIFO搜索

   3)优先队列式搜索

(2)分支限界搜索算法 

二、分支限界法的一般过程

    由于求解目标不同,导致分支限界法与回溯法在解空间树T上的搜索方式也不相同。 回溯法以深度优先的方式搜索解空间树T,而 分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树T

    分支限界法的 搜索策略是:在扩展结点处,先生成其所有的儿子结点(分支),然后再从当前的活结点表中选择下一个扩展对点。为了有效地选择下一扩展结点,以加速搜索的进程,在每一活结点处,计算一个函数值(限界),并根据这些已计算出的函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。

    分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。问题的 解空间树是表示问题解空间的一棵有序树,常见的有子集树和排列树。在搜索问题的解空间树时,分支限界法与回溯法对当前扩展结点所使用的扩展方式不同。在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,那些导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被子加入活结点表中。此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所求的解或活结点表为空时为止。

三、回溯法和分支限界法的一些区别

    有一些问题其实无论用回溯法还是分支限界法都可以得到很好的解决,但是另外一些则不然。也许我们需要具体一些的分析——到底何时使用分支限界而何时使用回溯呢?

回溯法和分支限界法的一些区别:

   方法对解空间树的搜索方式        存储结点的常用数据结构      结点 存储特性常用应用

  回溯法深度优先搜索堆栈活结点的所有可行子结点被遍历后才被从栈中弹出找出满足约束条件的所有解

  分支限界法广度优先或最小消耗优先搜索队列、优先队列每个结点只有一次成为活结点的机会找出满足约束条件的一个解或特定意义下的最优解


作者:yapian8 发表于2014-6-3 11:23:27 原文链接
阅读:0 评论:0 查看评论

WebGL on iOS8 终于等到了这一天

$
0
0


WWDC2014刚结束,这次的大会是名符其实的开发者大会,更贴切的应该说的确是一次软件开发者的大会,对于OSX和iOS的更多功能特性让人兴奋,Swift新语言促成了如上图片

但我更感兴趣的是WebGL终于官方的在OSX和iOS上得到了支持,这篇《 A first look at what iOS8 means for Phaser and Pixi.js》分享了在iOS下运行WebGL例子的图片:

以后分享 HT for Web的移动终端例子《 透过WebGL 3D看动画Easing函数本质》终于有了iOS设备的选择,感谢苹果!


作者:u013161495 发表于2014-6-3 10:02:49 原文链接
阅读:75 评论:0 查看评论

ORACLE SQL Performance Analyzer的使用

$
0
0


通过 SPA,您可以根据各种更改类型(如初始化参数更改、优化器统计刷新和数据库升级)播放特定的
SQL 或整个 SQL 负载,然后生成比较报告,帮助您评估它们的影响.


在 Oracle Database 11g 之前的版本中,我必须捕获所有 SQL 语句,通过跟踪运行这些语句,
然后得到执行计划 — 这是一项极其耗时又极易出错的任务。新版本中,我们不需要再那样做了,
我改用非常简单而有效的 SQL Performance Analyzer。

---使用场景

1.数据库升级
2.实施优化建议
3.更改方案
4.收集统计信息
5.更改数据库参数
6.更改操作系统和硬件

 

create tablespace test
datafile 'E:\APP\ADMINISTRATOR\ORADATA\ORCL\test01.DBF'
size 5000m
autoextend on
next 100m maxsize unlimited
extent management local autoallocate
segment   space management auto;

 

create table t1
(
sid int not null ,
sname varchar2(10)
)
tablespace test;

 

 

-2.-循环导入数据
declare
        maxrecords constant int:=1000000;
        i int :=1;
    begin
        for i in 1..maxrecords loop
          insert into t1 values(i,'ocpyang');
        end loop;
    dbms_output.put_line(' 成功录入数据! ');
    commit;
    end;
/


update t1 set sname='苏州' where sid=500001;

update t1 set sname='南京' where sid=600001;


---3.收集统计信息

exec dbms_stats.gather_table_stats(USER,'T1',CASCADE=>TRUE)


alter system flush shared_pool;

---4.执行查询

select count(*) from t1 where sid<=100;


select count(*) from t1 where sid<=500;


select count(*) from t1 where sid>50000;


---5.新建STS

BEGIN
  DBMS_SQLTUNE.DROP_SQLSET(
    sqlset_name => 'OCPYANG_STS'
    );
END;
/

BEGIN
  DBMS_SQLTUNE.CREATE_SQLSET(
    sqlset_name => 'OCPYANG_STS',
    sqlset_owner => 'SYS',
    description  => 'ocpyangtest');
END;
/


---6.加载sql优化集

set serveroutput on
DECLARE
cur01 dbms_sqltune.sqlset_cursor;
BEGIN
open cur01 for select value(a) from table(dbms_sqltune.select_cursor_cache
(
basic_filter => 'sql_text like ''%T1%'' and parsing_schema_name =''SYS''',
attribute_list => 'ALL'
)
) a;
dbms_sqltune.load_sqlset(
sqlset_name => 'OCPYANG_STS',
populate_cursor => cur01);
close cur01;
END;
/

/*********有两个参数值得特别说明:

1)SELECT_CURSOR_CACHE的第一个参数是basic_filter ,它可以取的值有:

  sql_id                   VARCHAR(13),
  force_matching_signature NUMBER,
  sql_text                 CLOB,
  object_list              sql_objects,
  bind_data                RAW(2000),
  parsing_schema_name      VARCHAR2(30),
  module                   VARCHAR2(48),
  action                   VARCHAR2(32),
  elapsed_time             NUMBER,
  cpu_time                 NUMBER,
  buffer_gets              NUMBER,
  disk_reads               NUMBER,
  direct_writes            NUMBER,
  rows_processed           NUMBER,
  fetches                  NUMBER,
  executions               NUMBER,
  end_of_fetch_count       NUMBER,
  optimizer_cost           NUMBER,
  optimizer_env            RAW(1000),
  priority                 NUMBER,
  command_type             NUMBER,
  first_load_time          VARCHAR2(19),
  stat_period              NUMBER,
  active_stat_period       NUMBER,
  other                    CLOB,
  plan_hash_value          NUMBER,
  sql_plan                 sql_plan_table_type,
  bind_list                sql_binds

2)SELECT_CURSOR_CACHE的最后一个参数是attribute_list

BASIC (default) -all attributes (such as execution statistics and binds) are returned except the plans The execution context is always part of the result.

TYPICAL - BASIC + SQL plan (without row source statistics) and without object reference list

ALL - return all attributes

Comma separated list of attribute names this allows to return only a subset of SQL attributes: EXECUTION_STATISTICS, BIND_LIST, OBJECT_LIST, SQL_PLAN,SQL_PLAN_STATISTICS: similar to SQL_PLAN + row source statistics

*********/


---7.查询sql优化集

select sql_id,sql_text from dba_sqlset_statements
where sqlset_name='OCPYANG_STS' and sql_text like '% from t1%';

 

 

 

---8.新建SPA

var v_task varchar2(64);
begin
:v_task:=dbms_sqlpa.create_analysis_task(
sqlset_name => 'OCPYANG_STS',
task_name => 'SPA01'
);
end;
/

 

 

 


/**********语法


Syntax

SQL text format. This form of the function is called to prepare the analysis of a single statement given its text.

DBMS_SQLPA.CREATE_ANALYSIS_TASK(
  sql_text         IN CLOB,
  bind_list        IN sql_binds := NULL,
  parsing_schema   IN VARCHAR2  := NULL,
  task_name        IN VARCHAR2  := NULL,
  description      IN VARCHAR2  := NULL)
RETURN VARCHAR2;
SQL ID format. This form of the function is called to prepare the analysis of a single statement from the cursor cache given its identifier.

DBMS_SQLPA.CREATE_ANALYSIS_TASK(
  sql_id           IN VARCHAR2,
  plan_hash_value  IN NUMBER    := NULL,
  task_name        IN VARCHAR2  := NULL,
  description      IN VARCHAR2  := NULL)
RETURN VARCHAR2;
Workload Repository format. This form of the function is called to prepare the analysis of a single statement from the workload repository given a range of snapshot identifiers.

DBMS_SQLPA.CREATE_ANALYSIS_TASK(
  begin_snap       IN NUMBER,
  end_snap         IN NUMBER,
  sql_id           IN VARCHAR2,
  plan_hash_value  IN NUMBER    := NULL,
  task_name        IN VARCHAR2  := NULL,
  description      IN VARCHAR2  := NULL)
RETURN VARCHAR2;


SQLSET format. This form of the function is called to prepare the analysis of a SQL tuning set.

DBMS_SQLPA.CREATE_ANALYSIS_TASK(
  sqlset_name       IN VARCHAR2,
  basic_filter      IN VARCHAR2 :=  NULL,
  order_by          IN VARCHAR2 :=  NULL,
  top_sql           IN VARCHAR2 :=  NULL,
  task_name         IN VARCHAR2 :=  NULL,
  description       IN VARCHAR2 :=  NULL
  sqlset_owner      IN VARCHAR2 :=  NULL)
RETURN VARCHAR2;


**********/

 

---9.执行SPA

begin
dbms_sqlpa.execute_analysis_task
(
task_name => 'SPA01',
execution_type => 'test execute',
execution_name => 'before_change'
);
end;
/

 

 

/*********语法

DBMS_SQLPA.EXECUTE_ANALYSIS_TASK(
   task_name         IN VARCHAR2,
   execution_type    IN VARCHAR2               := 'test execute',
   execution_name    IN VARCHAR2               := NULL,
   execution_params  IN dbms_advisor.argList   := NULL,
   execution_desc    IN VARCHAR2               := NULL)
 RETURN VARCHAR2;


DBMS_SQLPA.EXECUTE_ANALYSIS_TASK(
   task_name         IN VARCHAR2,
   execution_type    IN VARCHAR2               := 'test execute',
   execution_name    IN VARCHAR2               := NULL,
   execution_params  IN dbms_advisor.argList   := NULL,
   execution_desc    IN VARCHAR2               := NULL);

*********/


---10.改变


create index index_01 on t1(sid,sname)
tablespace test;


exec dbms_stats.gather_table_stats(USER,'T1',CASCADE=>TRUE)

---11.改变后执行

begin
dbms_sqlpa.execute_analysis_task
(
task_name => 'SPA01',
execution_type => 'test execute',
execution_name => 'after_change'
);
end;
/

 


col TASK_NAME format a30
col EXECUTION_NAME for a30
select execution_name,
status,
execution_end
from DBA_ADVISOR_EXECUTIONS
where task_name='SPA01'
order by execution_end
/

EXECUTION_NAME                 STATUS      EXECUTION_END
------------------------------ ----------- -------------------
before_change                  COMPLETED   2014-05-28 15:43:58
after_change                   COMPLETED   2014-05-28 15:44:58

 

---12.执行任务比较

begin
dbms_sqlpa.EXECUTE_ANALYSIS_TASK(
task_name        => 'SPA01',
execution_type   => 'compare performance',
execution_params => dbms_advisor.arglist(
'execution_name1',
'before_change',
'execution_name2',
'after_change'));
end;
/

 


---13.生产报告

set serveroutput on size 999999
set long 100000000
set pagesize 0
set linesize 200
set longchunksize 200
set trimspool on
spool e:\report.txt

select DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA01') from dual;

spool off;

 

作者:yangzhawen 发表于2014-6-3 9:46:51 原文链接
阅读:77 评论:0 查看评论

java带图片的邮件发送方法实现

$
0
0
package sendEmail;

import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class AttchImgMail {
	// JavaMail需要Properties来创建一个session对象。它将寻找字符串"mail.smtp.host",属性值就是发送邮件的主机.
	public static void main(String[] args) throws Exception {
		Properties properties = new Properties();
		// properties.put("mail.smtp.host", "mailcas.chinapnr.com");// 设置smtp主机
		properties.put("mail.smtp.host", "smtp.163.com");// 设置smtp主机
		properties.put("mail.smtp.auth", "true");// 使用smtp身份验证
		/*
		 * 在 JavaMail 中,可以通过 extends Authenticator 抽象类,在子类中覆盖父类中的
		 * getPasswordAuthentication() 方法,就可以实现以不同的方式来进行登录邮箱时的用户身份认证。JavaMail
		 * 中的这种设计是使用了策略模式(Strategy
		 */
		MimeMessage message = new MimeMessage(Session.getInstance(properties,
				new Authenticator() {
					public PasswordAuthentication getPasswordAuthentication() {
						return new PasswordAuthentication(//设置发送帐号密码
								"帐号", "密码");
					}
				}));
		// 设置邮件的属性
		// 设置邮件的发件人
		message.setFrom(new InternetAddress("发件人"));
		// 设置邮件的收件人 cc表示抄送 bcc 表示暗送
		message.setRecipient(Message.RecipientType.TO, new InternetAddress(
				"收件人"));
		// 设置邮件的主题
		message.setSubject("系统自动发送邮件");
		// 创建邮件的正文
		MimeBodyPart text = new MimeBodyPart();
		// setContent(“邮件的正文内容”,”设置邮件内容的编码方式”)
		text.setContent("此邮件为系统自动发送<img src='cid:a'><img src='cid:b'>","text/html;charset=gb2312");

		// 点到点的发送
		// 一对多发送只要改一个地方如下:
		
		// // 构建一个群发地址数组
		// InternetAddress[] adr=new InternetAddress[toMore.length];
		// for(int i=0;i<toMore.length;i++){ adr[i]=new
		// InternetAddress(toMore[i]); }
		// // Message的setRecipients方法支持群发。。注意:setRecipients方法是复数和点 到点不一样
		// message.setRecipients(Message.RecipientType.TO,adr);
		 

		// 创建图片
		MimeBodyPart img = new MimeBodyPart();
		/*
		 * JavaMail API不限制信息只为文本,任何形式的信息都可能作茧自缚MimeMessage的一部分.
		 * 除了文本信息,作为文件附件包含在电子邮件信息的一部分是很普遍的. JavaMail
		 * API通过使用DataHandler对象,提供一个允许我们包含非文本BodyPart对象的简便方法.
		 */
		DataHandler dh = new DataHandler(new FileDataSource("src//a.jpg"));//图片路径
		img.setDataHandler(dh);
		// 创建图片的一个表示用于显示在邮件中显示
		img.setContentID("a");

		MimeBodyPart img2 = new MimeBodyPart();
		DataHandler dh2 = new DataHandler(new FileDataSource("src//b.jpg"));//第二张图片路径
		img2.setDataHandler(dh2);
		img2.setContentID("b");
		// 创建附件
		// MimeBodyPart attch = new MimeBodyPart();
		// DataHandler dh1 = new DataHandler(new FileDataSource("src//b.jpg"));
		// attch.setDataHandler(dh1);
		// String filename1 = dh1.getName();
		// MimeUtility 是一个工具类,encodeText()用于处理附件字,防止中文乱码问题
		// attch.setFileName(MimeUtility.encodeText(filename1));
		// 关系 正文和图片的
		MimeMultipart mm = new MimeMultipart();
		mm.addBodyPart(text);
		mm.addBodyPart(img);
		mm.setSubType("related");// 设置正文与图片之间的关系
		// 图班与正文的 body
		MimeBodyPart all = new MimeBodyPart();
		all.setContent(mm);
		// 附件与正文(text 和 img)的关系
		MimeMultipart mm2 = new MimeMultipart();
		mm2.addBodyPart(all);
		mm2.addBodyPart(img2);
		mm2.setSubType("mixed");// 设置正文与附件之间的关系

		message.setContent(mm2);
		message.saveChanges(); // 保存修改

		Transport.send(message);// 发送邮件
		System.out.println("邮件发送成功");

	}
}

Java发送带图片的邮件,代码为发生2张图片的邮件关联方式,注释中有发送带附件、带多人发生解析的代码,可以自行调整

作者:mm7591383 发表于2014-6-3 9:46:24 原文链接
阅读:78 评论:0 查看评论

SEO中常见的七个错误

$
0
0

SEO作为一个战略营销服务多年来它的效果一直都是非常不错的。许多营销人员用过了都说好。他们通过给网站进行深度优化从而使网站流量得到了质的提升。SEO的主要优势在于:

  • 转化率的显著提升
  • 给客户的最大的投资回报
  • 更好的站点管理
  • 客户群更多元化
  • 品牌的曝光度和知名度的提升

这些理由足以让营销人员将SEO作为主要的在线营销策略了。然而,需要仔细调整SEO来适应客户企业以及目标用户的分布特征。否则,无法达到预期的效果。许多SEO服务提供商在替客户取得满意的效果前都经历了许多常见的错误的方法。还有一部分人使用的是现成的解决方案,他们坚信能”一招吃遍天下“。

不管使用何种方式,任何公司在制定他们的SEO策略时有些东西是应当绝对避免的。下面我们列出了SEO提供商应当坚决避免的七个常见的SEO错误。

  1. 不要优化用户搜索你的产品或者服务所使用的关键词 当客户想搜索平底锅煎披萨时,他们可能会搜索”如何制作平底锅煎披萨“或者”订一份平底锅煎披萨送到<目的地>”。这两种情况中,使用“平底锅披萨”作为你的网站的关键词并不会让你的网站在搜索结果中的排名靠前,它和你的潜在用户并没有关系。

解决方案——为了确定你的网站能被正确的用户看到,你有一些工具可以使用——比如Google的Adwords关键字工具以及Google的搜索。它们会告诉你你的关键字在搜索中出现的时间和频率。这能让你决定到底是使用那些关键字还是用户常用的一些用语 。更棒的一点是,它们两个都 是免费的。

  1. 不要阻止搜索引擎抓取你的网站 许多网站的开发人员在开发或者测试的阶段喜欢拿网页和搜索引擎玩躲猫猫。要么是使用一个叫"robots.txt"的文件,要么是在某些页面中使用"rotots"元标签。如果开发人员后面忘了删除这个标签的话,你整个网站的可搜索性就会受到牵连,因为搜索引擎将无法索引到它。

解决方案——检查网页中有没有robot标签,如果当前上下文中已经不需要了,有的话删掉它。这个robots标签看真来是这样的”

<meta name=”robots” content= “noindex”>
Secondly, check if the link “www<sitename>.com/robots.txt” opens a page with the content below:
User-agent: * 
Disallow:/

这个命令说明这个网站的所有URL都不允许Google或者其它的搜索引擎抓取,索引或者排名,因此删掉它是很有必要的。这确保你的网站能被搜索引擎发现,这能提高它的排名。关于robots.txt的分析可以读下Matt Cutts的 这篇文章

  1. 不必要的外链建设 如果你过于关注外链,多于改善内容或者其它营销策略的话,那你就搞错方向了。外链建设是使网站出现在别的网站中的一个很好的方式,这有助于提高你网站的排名。然而,你不能只关注这一个点。网站的开发及运营人员需要明白,这只是提高网站的曝光率的众多方法中的一个而已。

解决方案——不要只关注搜索引擎,应该平衡用户和搜索引擎的关注点。其它SEO需要关注的方面包括:

  • 多创建些吸引人的,有说服力的内容
  • 给你的网站做营销,使得它成为你的目标用户的一个宝贵的资源
  1. 没有明确和肯定的动作指引 尽管你的网站能被搜索到,访客也被你的内容所吸引了,但这还不够。除非你很明确地告诉他们怎么做才能获取 到你提供的服务或者产品,不然他们看完网页也就走了。

解决方案——要时刻记住,最终目标并不是要让用户访问你的网站。而是要把这些访客转化成你的客户。比如说,如果你有一个实体店,那你应该告诉用户你的营业时间以及一个容易找到的地址,这样附近的用户才能很容易地找到你的店。如果你的网站提供 的是服务或者产品,那么你应该增加一个客户评价页以及产品介绍页,这样才能让你的访客相信,你就是他们项目所需要的人。

  1. 没有给Google提供足够的抓取和索引的文本 包含了太多的图片和Flash或者脚本的网站通常给无法给Google提供足够的能抓取出有用信息的“肉”。结果则是网站后续的索引和排名的提升就成为一句空话了。

解决方案:保证你的网站文本中夹杂的图片维持在最低限度。这样的话更多的网页空间就可以用于显示HTML的文本内容了,Google才可以用它来进行解析和索引。这还有助于那些处理资源有限的设备(比如手机或者平板)可以更快地加载页面,从而提升整体的用户体验。

  1. 分享到社交媒体

过去十年来,社交媒体分享成为许多产品成功的关键因素。在这个背景下,如果没在网站中充分使用社交媒体分享的功能是一个非常大的错误。分享到社交媒体中既可以 提高你的品牌覆盖率又可以让你的网站得到更好的 排名。

解决方案——确保采用以下步骤来使得你的网站可以很容易地进行分享:

  • 确保每个页面的URL地址都是唯一的,描述性的。
  • 网页中不应该出现不含URL的弹出窗口
  • 当分享视频或者图片的时候,确保能够链接到一个嵌入视频的页面而不只是一个网站的视频文件。
  1. 内链的锚点文本描述性不足 内链的文本描述有助于搜索引擎明白这个网站或者页面是做什么的。Adobe的网站也曾犯过类似的错误。它们所有内链的按钮都是同样的文本,"点击这里(Click here)”。结果就是——如果有人搜索"点击这里"的时候,Adobe的网站会出现在结果排名的前列。很明显,这么做并没有用,违背了SEO的初衷,还显得有点愚蠢。不要犯类似的错误。

解决方案——在Adobe这个例子中,如果相关的链接使有类似“下载Adobe Reader”的标题的话会好很多。这样用户搜索“下载Adobe Reader"的时候,就会引导到这个链接上来,这才是他们想要的结果。

每个市场营销人员都希望自己的网站都尽可能多地覆盖自己的目标用户群体。上面我们提到的是你在进行SEO时可能会伤害到你的网站的一些常见错误。

原创文章转载请注明出处: SEO中常见的七个错误

英文原文链接

Swift 横空出世

$
0
0

Apple Releases iOS 8 SDK With Over 4,000 New APIs

        苹果2014-6-2日的WWDC开发者大会,是名符其实的“开发者大会”,发布新的操作系统,IOS8,4000+的新api,这已经让我们这些程序员够吐槽的了。不过苹果的技术大拿们似乎不满足于此,推出了新的开发语言--Swift。我要吐血啦,那些苹果顾的水军编辑们,竟然起哄,“coder们要喜大普奔”啊,艹,明显站着说话不腰疼啊!

        吐槽归吐槽,Swift就这样横空出世了,以后会不会成为武林高手呢,咱拭目以待。不过对于咱这样的开发者,还是赶紧啃吧。

       快速浏览了Swift语言之后,发现原来swift语言没有那么难,甚至能让一大部分开发者轻易的转战ios开发,这个语言的风格很大程度类似脚本js和python之类。嘿嘿,多少人在偷着乐啊。

       Swift语言到底是何方神圣呢?咱看看苹果官方怎么说:

       Swift is a new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility. Swift adopts safe programming patterns and adds modern features to make programming easier, more flexible, and more fun. Swift’s clean slate, backed by the mature and much-loved Cocoa and Cocoa Touch frameworks, is an opportunity to reimagine how software development works.

        看样子,苹果是要大力推动Swfit语言了,Swift可以用来在MAC和IOS上开发,兼容目前的Cocoa和Cocoa touch Framework,Swift吸收了安全编程模式的特点,同时摆脱了C语言的一些束缚,变的更加好用,易扩展,更有趣。(玩玩才知道)

        Swift是如何摆脱C语言的一些束缚呢?还记得那个"hello world!"吗?

        

  • println("Hello, world")

    

        这可不是一句表达式,这是一个完整的程序,是不是少点了很多的include,函数框架也没有了,特码的连main都不用,就是一句脚本,执行就ok了。凋爆了。

         Swift的变量和语句很简单,两个关键词,var和let就可以搞定了:

         

  • var myVariable = 42
  • myVariable = 50
  • let myConstant = 42

          强制要求初始化,初始值决定类型,想要制定类型怎么办,很简单:

          

  • let implicitInteger = 70
  • let implicitDouble = 70.0
  • let explicitDouble: Double = 70

 

           类型转换不支持隐式,必须强转:

                

  • let label = "The width is "
  • let width = 94
  • let widthLabel = label + String(width)

           猜猜这个“  \()”是干嘛用的,哈哈!强转为字符串的利器:

                     

  • let apples = 3
  • let oranges = 5
  • let appleSummary = "I have \(apples) apples."
  • let fruitSummary = "I have \(apples + oranges) pieces of fruit."

                数组,字典之类的比较中规中矩,没有什么好讲的,直接看效果:

                        

  • var shoppingList = ["catfish", "water", "tulips", "blue paint"]
  • shoppingList[1] = "bottle of water"
  • var occupations = [
  • "Malcolm": "Captain",
  • "Kaylee": "Mechanic",
  • ]
  • occupations["Jayne"] = "Public Relations"

               

                 数组,字典的初始化,更加自由了,感觉像Java啦:

                       

  • let emptyArray = String[]()
  • let emptyDictionary = Dictionary<String, Float>()

                数组和字典在作为参数时,可以简写为[]和[:] .

                程序流程控制方面,新特性比较多,常规的if,switch, for-in, for, while, do-while的用法都支持,不过在使用条件语句的时候,有了新的变化,比如if语句的==判断,语法是这样的:

                 

  • var optionalString: String? = "Hello"
  • optionalString == nil
  • var optionalName: String? = "John Appleseed"
  • var greeting = "Hello!"
  • if let name = optionalName {
  • greeting = "Hello, \(name)"
  • }

               

             注意到了上面的String类型之后的?了吗,这个是一个标注,表示这个值是可选的,就是可以给空值nil,还有一点,布尔值不在等同于0和其他int值了,必须用显性的bool值。

            switch语句有个很大特色,条件支持任意类型了,看看下面的语句,我就觉得爽:

                   

  • let vegetable = "red pepper"
  • switch vegetable {
  • case "celery":
  • let vegetableComment = "Add some raisins and make ants on a log."
  • case "cucumber", "watercress":
  • let vegetableComment = "That would make a good tea sandwich."
  • case let x where x.hasSuffix("pepper"):
  • let vegetableComment = "Is it a spicy \(x)?"
  • default:
  • let vegetableComment = "Everything tastes good in soup."
  • }

               靠,没有break语句怎么跳出来啊?没有关系,Swift摒弃这个语法陋习。是不是减少了很多发错的机会。哈哈

 

               待续:

 

 

 

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




HTTPS那些事儿(一)

$
0
0

HTTPS那些事儿(一)

最近看了《http权威指南》的几个章节,对HTTPS有了部分了解,同时在网上查阅了一些资料,遂打算记录一下心得,写的仓促,肯定有很多错误的地方,欢迎大家指正。

1.HTTP是什么

那么在介绍https之前,有必要先解释下http。http是一个非常简单又非常复杂的协议,说其简单,是我们每天都在用它,而且又浑然不觉,貌似很简单的样子。但是真正能够把http完全了解清楚,并不是很容易的事情。《http权威指南》诺厚的一本书,都是http相关内容,可知有多么复杂了。

  • 简单来说,HTTP协议是超文本传输协议,是一种可靠的数据传输协议。像我们每天都在使用的web浏览器就是一种http客户端,提供内容的web服务器就是服务器端。http客户端和服务器端构成了万维网的基本组件。web服务器是web资源的宿主,web资源是web内容的源头,最简单的web资源就是web服务器文件系统中的静态文件,如文本文件,html文件,图片,word文件以及mp3,avi等影音文件等;除了静态文件,web资源还可能是根据需要生产内容的软件程序,这些可以看做是动态文件。
  • 一个简单的http请求是从我们打开浏览器,输入url地址访问指定网站开始的。一条请求命令和一个响应结果构成了一个HTTP事务。而几乎世界上所有的HTTP通信都是由TCP/IP协议承载的,这就是我们熟悉的网络ISO七层结构和TCP/IP4层结构,在大部分的情况我们只讨论TCP/IP分层结构。那么具体的访问过程是怎么样的呢?比如我们访问 http://movie.douban.com/subject/10485647/?from=showing这个链接地址,那么具体包括如下几个过程:
    • 1.浏览器解析初主机名。(主机名是movie.douban.com)
    • 2.浏览器查询DNS服务器查到该主机名对应的ip地址。比如211.147.4.32。如果之前有访问过该站点,则由于DNS记录会被操作系统缓存,就不需要再次解析。此外,如果访问的web服务器使用了DNS轮转的话,则可能不同的时候查到的ip地址是不同的。
    • 3.浏览器获得端口号。这里默认是80.
    • 4.浏览器发起到211.147.4.32端口80的连接。
    • 5.浏览器向服务器发起一条HTTP GET的报文。
    • 6.浏览器从服务器读取一条HTTP响应报文。
    • 7.浏览器关闭连接。
  • 更加详细的过程可以参加《HTTP权威指南》,里面有讲到为了提高性能的并发连接、持久连接以及连接管道化等。此外,这里还有篇文章详细介绍了一个HTTP事务的过程,请参见 从输入URL到页面加载完成发生了什么事情

2.从HTTP到HTTPS

基本的HTTP在web事务中是不够安全的,这也就催生了HTTPS的诞生。HTTPS是在HTTP和TCP之间加了一层传输层的密码安全层-SSL或者后来普遍使用的TLS。HTTPS协议会对web通信过程中的数据加密,杜绝了数据被窃取,总体来说还是很安全的。虽然前不久openssl爆出了一个heartbleed漏洞,不过现在已经修复了。HTTPS在URL中的前缀是HTTPS,默认端口是443,HTTP默认端口80。

2.1基本过程

    由于SSL安全层的存在,HTTPS建立安全传输的过程会略微复杂一些。HTTP客户端(最常用的就是浏览器了)打开一条到web服务器端口443的连接。一旦建立了TCP连接,客户端和服务器端就会初始化SSL层,对加密参数进行沟通并交换密钥。握手完成后,SSL也就初始化完成了,客户端就可以把请求报文发送给安全层了。 当然,这些报文发送给TCP之前,会被加密。

2.2 SSL握手

  • SSL握手是最为复杂的一步了,具体过程如下:
  • 1.客户端(通常就是web浏览器)向服务器发送自己支持的加密规则并请求证书。
  • 2.服务器选择一组加密算法和HASH算法,以及服务器证书发送给浏览器。(SSL支持双向认证,web服务器将服务器证书发送给客户端,然后再将客户端的证书回送给服务器。但是实际应用中很多用户都没有自己的客户端证书,因此服务器也很少会要求客户端证书)
  • 3.浏览器获取服务器证书之后需要验证证书的合法性。具体有以下几个步骤: 服务器证书一般包括如下信息:证书序列号,证书过期时间,站点组织名,站点DNS主机名,站点的公开密钥,证书颁发者名称,证书颁发者的签名。网景公司提出了一种web服务器证书有效性算法是大部分浏览器有效验证服务器证书的基础。主要验证步骤如下:
    • 3.1 日期检测。
      检查证书的起始时间和结束时间,以确保证书仍然有效。如果证书过期了或者还没有被激活,则证书有效性验证失败,浏览器提示错误信息。
    • 3.2 证书颁发者可信度检测。
      每个证书都是由某些证书颁发机构(CA)签发的,它们负责为服务器担保。证书有不同等级,每种证书都需要不同级别的背景验证。 任何人都可以生成证书,但是有些CA是非常著名的组织,它们可以通过非常清晰的流程来验证证书申请人的身份以及商业行为的合法性。因此,浏览器通常会附带一个签名颁发机构的受信列表。如果是未知机构颁发的证书,则浏览器会显示警告信息。
    • 3.3 签名检测。 一旦判定证书颁发者可信,浏览器就需要使用证书颁发者的公钥对信息进行签名,并将其与证书中的签名进行比对,如果两者不同,则信息可能被修改过,不能通过验证。
    • 3.4 站点身份认证
      为防止服务器复制其他人的证书,或拦截其他人的流量,大部分浏览器都会试着去验证证书中包含的DNS主机名是否与正在对话的主机名是否匹配。如果不匹配,则要么是浏览器警告用户,要么就是直接终止连接。 对于虚拟主机(一台服务器有多个主机名)站点上的安全流量处理是比较棘手的,有些流行的web服务器程序只支持一个证书,如果用户请求虚拟主机名,则与证书中的主机名不匹配,这样浏览器会发出警告。一个处理办法是在开始安全事务前,将虚拟主机域名重定向至服务器证书中的官方主机名。(服务器证书中通常只包含一个主机名,但有些CA会为一组服务器创建一些包含了服务器名称列表或者通配域名的证书)
  • 4.如果服务器证书验证通过,则浏览器会生成一串随机的数字作为密码,并用服务器证书中的公钥进行加密。 此外,浏览器使用第2步中商量好的HASH算法对握手消息进行加密,采用的密码就是刚刚生成的那串随机数字。最后将这些信息( 用公钥加密的随机数密码,握手消息,采用HASH算法、随机数密码加密的握手消息签名)发送给服务器。
  • 5.服务器接收浏览器信息,需要进行如下处理:
    • 5.1 用私钥解密获取随机数密码。
    • 5.2 用HASH算法根据该随机数密码对握手消息进行签名,比对浏览器发来的签名和该计算得到的签名是否一致。
    • 5.3 如果签名验证通过,则使用该随机数密码加密一段握手消息,发送给浏览器。
  • 6.浏览器接收握手消息并使用随机数密码以及之前的HASH算法计算握手消息的HASH值。如果与发来的HASH值一致, 此时握手结束,后续的消息都会通过随机数密码来进行加密和解密,使用的加密方法是对称加密。要注意之前的公钥加密和私钥解密使用的是非对称加密算法。

3.HTTPS中用到的算法

HTTPS一般使用的加密与HASH算法如下:   

非对称加密算法:RSA,DSA/DSS

对称加密算法:AES,RC4,3DES

HASH算法:MD5,SHA1,SHA256

非对称加密算法用于之前在传递随机数密码的时候用到。对称加密算法是安全连接建立后用到,用于加快加密解密的速度。HASH算法是用于验证数据完整性。SSL握手过程中如果有任何错误,都会使连接断开,从而阻止了隐私信息的传输。由于HTTPS非常安全,攻击者很难找到下手的地方,于是更多的是采用了假证书的手法来欺骗客户端,这些假证书的识别方法后续再谈。

4.参考资料

作者:ssjhust123 发表于2014-6-3 0:37:40 原文链接
阅读:227 评论:0 查看评论

【WWDC观察】WWDC2014 总汇:扁平的 Yosemite、超级整合王 iOS 8 以及苹果发明新语言 Swift

$
0
0

作者头像
作者: hsy505/产品观察家
Digital Jockey
[核心提示]今天还得上班,昨晚错过了 WWDC2014 现场直播?极客公园为你带来了 WWDC2014 详情总汇。

北京时间 6 月 3 日凌晨 1 点,苹果公司在美国旧金山召开 2014 年度全球开发者大会(WWDC2014)。本次大会发布了全新的操作系统 Mac OS 10.10(Yosemite),新一代操作系统 iOS 8,以及一系列针对开发者的新服务,众人期待的新硬件产品并没有发布,转而发布了全新的编程语言 Swift。

Mac OS 10.10

苹果再次改变了以大型猫科动物为 Mac OS 命名的惯例(当然,主要是名字都被他们用完了),Mac OS 10.9 首次选用位于加州北部的沙滩 Mavericks 为系统命名。Mac OS 10.10 被命名为 Yosemite,这是位于美国加州的第一个州立公园。

扁平化风格

 

全新的 Mac 系统重绘了系统图标,趋近 iOS 的扁平化风格。并且重新设计了顶部工具栏、Dock、通知中心以及窗口风格,采用半透明的毛玻璃风格,去除了以往窗口标志性的关闭、最小化、最大化按钮的阴影效果,色彩也更鲜亮。

更丰富的通知中心以及自定义控件

此次 Yosemite 通知中心的设计思路再次向 Andriod 取经。共有两个标签页,包括「今天」和「通知」,这里可以显示包括日历、提醒、天气以及第三方的应用通知。应用开发者可以设计控件,让用户添加到 Mac 的通知中心,苹果也支持将计算器等应用通过拖拽添加到通知中心里。

类 Afred 的新 Soptlight

曾经占据桌面右上角的 Spotlight 搜索栏被放置到正中间,Spotlight 搜索结果可以直接显示于下方。不免让人联想到了 Mac 中广受好评的第三方全局搜索应用 Afred,新搜索框的搜索结果将不局限于文件,而且包括网络搜索结果,以及苹果日历和地图应用程序的集成。另外搜索栏还可以处理数值转换和高级数学公式。

Safari

新的 Safari 提升了节能性,非常简洁,新增隐私浏览窗口,用户还可直接在 Safari 当中对图片进行编辑,新的分享菜单可查看 RSS 源,以及最近联系过的人,以便快速分享内容。

iCloud Drive

文档云同步功能完全整合至 Finder 中,用户可以直接在 Finder 中编辑操作文档并实时同步。通过该功能用户可以跨设备同步文稿,iCloud Drive 也将兼容 Windows 系统。iCloud Drive 是将此前的 iWork 云同步功能整合至系统本身,相比不在一个重量级的 Office,将自家应用和设备整合在一起,是一个不错的方式。

邮件

引入大附件功能,可以将大附件上传后直接转化为安全链接进而分享,QQ 笑而不语,超大附件不早就有了么?

Yosemite 从今日起提供开发者下载,秋季正式上市,依旧免费。

iOS 8

通知栏的新交互

iOS 8 系统中的顶部通知栏增强了互动性。用户在收到一条短信时,可以直接在通知栏里进行回复,而不用再进入短信应用界面。其他应用也是类似。

将「微信」整合来的短信

逐步崛起的 IM 聊天工具让苹果看到了威胁,苹果在 iOS 8 的短信功能演示上花费了大量口舌。用户可以使用短信分享地址,输入语音短信,还可发送语音和视频,群发短信的体验也得到了提升,简单来说,短信功能聚合了现在「微信」的基础功能。

iOS 8 的信息引入「群」的概念,可以直接「拉」多名好友一起对话,或是将某人移除,还可以为对话命名,或是退出群聊

支持地理位置分享,可实现多人实时位置共享,还可为地址位置分享限制有效时间,并可与共享好友直接电话或 Facetime。

输入法

iOS 8 的全新输入功能名为 QuickType,系统会在用户输入时给予「预测性建议」。比如,朋友发短信问你今晚一起吃饭还是看电影?QuickType 功能就会在输入法中显示「吃饭」或「看电影」,让你完成快捷回复。从现在开始 iOS8 可以安装第三方输入法了。

增强的 Spotlight

iOS 8 系统中的 Spotlight 不再只是本地搜索,可以联网找 App,找新闻、餐厅、歌曲、电影等。

家庭分享功能

新 iOS 系统新增了家庭分享 (Family Sharing) 功能。用户在 iTunes 购买一首歌,就可以利用这个功能分享给最多 6 个家庭成员。

照片智能编辑

用户可以对图片进行「智能编辑」,调整图片的多个参数,比如曝光度、对比度、亮度等。

Siri 升级

语音助手 Siri 也进行了升级,得益于 Shazam 的帮助,新版 Siri 将可以直接根据用户提供的旋律来辨识歌曲。除此之外,你还可以用其来进行 iTunes 内容消费,并增加支持中国农历等功能。

Health

iOS 8 移动操作系统新增 Health 健康管理软件,它可以整合其他第三方健康应用数据,也就说可以在 Health 中统一浏览其他应用监测的数据。同时,它也将与梅奥诊所和其他医疗机构合作,允许医疗机构接受或传输你的数据。

苹果公司方面表示,将会有严格的隐私保护措施,以防止敏感数据外泄。这些软件合作伙伴包括耐克、Fitbit、Jawbone、Runkeeper 等,用户可以在 Health 中看到自己每天消耗多少卡路里、睡了多长时间、跑了多少公里等数据。

今天起 iOS 8 Beta 版开放给开发者,而按照惯例,秋天正式版会进行更新。

目前支持 iOS 8 的设备有:iPhone 4s、iPhone 5、iPhone 5c、iPhone 5s、iPod touch 5th generation、iPad 2、iPad with Retina display、iPad with Retina display、iPad Air、iPad mini 以及 iPad mini with Retina display。

延续性

Handoff 多终端将数据及时同步

用户可以直接传送正在编辑的 Pages 文稿到 iPhone 或 iPad 之上,这款应用不仅可以让用户在移动设备和计算机之间共享文档。还可以同步 iOS 和 OS X 操作系统之间的通信,允许用户同步关闭文件、邮件、甚至是拒接来电。

可连接 Mac 和 iOS 设备的 AirDrop

老版的 AirDrop 只支持 iOS 设备之间或者 Mac 之间独立信息传输,而此次更新后,iOS 设备终于可以和 Mac 进行数据传输了。

快速建立热点

Yosemite 还可通过位置感应功能,最快从 Mac 建立一个移动热点,而不用操作 iPhone。

Mac 上接听来电

Handoff 应用从本质上讲,把用户的电脑变成了另一部电话。现在利用桌面服务用户可以发送短信,短信的传输通过用户的 iPhone。它甚至可以让用户在 Mac 上接听或拨打电话。很明显这个新工具是苹果移动和桌面操作系统融合过程的重要组成部分。

 

开发者的福利

包含了 4000 个新 API 接口的 SDK

新版 SDK 新增了 4000 个 API,开发者可以借此开发功能更为丰富的应用,去年推出的指纹识别功能 Touch ID 将被开放给开发者。同时,开发者还将拥有更多的摄像头 API。

新语言 Swift

苹果除了开放给开发者更多 API 接口之外,还发布了全新的开发者编程语言——Swift,与现有的开发语言 C 语言和 Python 相比,Swift 更具优势,编程更快速,更好地实现所想要的效果。

智能家居探路棋 HomeKit

为了提前进入智能家居领域,苹果推出了 HomeKit 功能,希望让 iPhone 成为家里智能设备的遥控器。目前,很多智能设备厂商都在支持 HomeKit,中国厂商海尔名列合作厂商名单之中。HomeKit 实际上就是开放的 API,它可以整合 Siri 的功能,来自动控制门窗的锁、调整光线,可以实现对门窗、灯光等设备的控制。

Metal

新的 Metal 能够减少 OpenGL 的负载,让开发者更好地利用设备的芯片性能, 从而大幅提升图形和游戏能力,让之前无法在平板电脑上实现的情景成为了可能。

SpriteKit

SpriteKit 是专门针对休闲游戏以及 3D 游戏的一个优化,SpriteKit 是一个 3D 场景渲染器,并且拥有更强的物理效果模拟能力,同时还能够有效减少资源占用。

Xcode

全新 XCode 将引入 Swift, 语句将更加简洁高效,不再使用以往的 Object C。新的 Swift 语言将比 Obejective-C 和 Python 还要快,看来不久后的编程语言排行榜将会出现新的榜首。

极客观察均为极客公园原创报道,转载请注明原文链接。

原文地址: http://www.geekpark.net/read/view/205735

关注极客公园,即时获得最新内容: Twitter | 微信:极客公园 | 新浪微博 | 花瓣网 | 人人小站 | Google+ | 点点

iOS 8 新改进(二):信息

$
0
0

hero_image

用上 iPhone 之后,我们几乎已经习惯发短信不要钱了(虽然必须要求双方都是 Apple 设备且必须启用 iMessage)。

实际上,这个功能本身并没有什么值得说的,QQ、微信或者几乎任何一个即时通软件都是发信息不要钱,还能跨平台。而 Apple 最厉害的地方在于他们直接将”即时通软件”和”信息”整合在一起,且你的手机号就是你的”即时通”号码,甚至连登陆、启动程序的过程都省掉了。

而在 iOS 8 中,Apple 将再一次对“信息”进行革命性的改进。最明显的就是支持发送语音和视频短信。

需要注意的是,发送语音短信并不同于发送语音文件和视频,而是像微信那样,直接在需要发送语音短信的时候,按住麦克风图标,对着手机讲话,然后上划即可发送出去。发视频短信也是类似的。这一功能被介绍之后,微博上立刻有很多果迷表示微信可以卸载了。

iMessage 群聊也有了新功能。如果说以前的群聊还多少有点类似于”短信群发”功能的话,现在的 iMessage 群聊则更像是 QQ 的”讨论组”,而且功能更加强大。比如你可以给”讨论组”命名、可以从”讨论”组里删除掉某人,也可以在讨论组中分享自己的位置(包括当前位置)等等。

iOS 8 新改进(一):相机与照片

$
0
0

hero_2x

对于很喜欢用 iPhone 拍照,并且有大量照片保存的果迷来说,iOS 8 中的相机与照片改进可以说是非常值得一提的。

首先,iOS 8 的相机加入了延时摄影(Time-lapse)功能,这应该是继 Apple 加入“全景图拍摄”功能之后有一个炫酷且实用的功能。简单的说,延时摄影就是隔一段时间拍摄一张照片,最后合并成一个快速播放的视频。比如,你可以用演示摄影拍摄星斗转移、拍摄植物生长的过程、拍摄城市中熙熙攘攘的人群等等。

12322

其次,iOS 8 中存储的照片和 iCloud 存储进行了完美整合。你用 iPhone 拍摄的任何一张照片,都会立刻自动同步到你的其他 Apple 设备中,比如 Mac、iPad,甚至网络相册中。

iCloud 照片库远不仅仅是帮你存储/同步那么简单,而且它还会自动将全尺寸的源文件存放于 iCloud 照片库中(甚至 RAW 格式的源文件),而在你设备上显示的其实是适合你屏幕分辨率的轻量级照片,这样一来不仅会让本机照片库中的照片加载的更加流畅,而且也能节约你本机的空间。

library_gallery2

当然,这样一来 iCloud 的存储空间就会费得很快,这应该是 Apple 故意这样的,要不怎么卖 iCloud 存储呢?用户存放在 iCloud 中的所有文件如果不超过5GB则免费,想要存放更多就需要付费了。Apple 宣布的两档套餐分别是:

  • 20GB,0.99美元/月
  • 100GB,3.99美元/月

第三,照片加入搜索功能,找照片更加容易。搜索可以根据拍摄的时间(包括大概时间)、地点、相册名等等作为关键词进行搜索。比如,你只记得之前在纽约拍摄了一张照片,有了搜索功能之后,就可以直接在搜索框中输入“纽约”,就可以筛选出所有你在纽约拍摄的照片,定位速度大大提高。

find_2x

第四,智能编辑。这一点主要包含两个部分,一方面是智能调整,主要用于调整照片的亮度、颜色,并且还能进行对比度、曝光、阴影等多方面进行调整;另一方面是智能构图,比如当你拍摄了一张照片,但是由于持握手机的时候没有水平,导致找出的照片有点倾斜,拍摄之后程序可以自动帮你用旋转+裁切的方式修正。

capture_composition

第五,滤镜。目前在使用 iOS 7 的用户应该知道 Apple 已经有一些内置照片滤镜,但如果你对 Apple 的这些滤镜不满意的话,在 iOS 8 中甚至可以直接调用第三方 App 的滤镜。要使用这一功能,需要第三方 App 开发者允许他们的滤镜被 Apple 官方的”照片”应用访问。

苹果 WWDC 2014 新品发布会 iOS 8、OS X Yosemite 系统 5 分钟无废话版介绍

$
0
0
今天凌晨,苹果在 WWDC 2014 的新品发布会环节展示了新一代的 iOS 8 和 OS X Yosemite 操作系统,还有新的编程语言 Swift 等一堆硬货。今天一上网被铺天盖地的媒体报道和专家分析烦得不得了是吧?苹果fans 博客照例只写一篇 5 分钟无废话版简介。

OS X Yosemite

新一代的苹果电脑操作系统继续以风景区命名,而且这次的进化幅度要比去年 OS X Maverick 大得多(iOS 8 也是):

  • 扁平化+毛玻璃特效,这个不意外对吧。而且从演示效果来看,比去年 iOS 7 刚拍扁时顺眼多了。
  • Spotlight 搜索功能大升级,除了文件搜索还能直接找餐馆、看地图、查维基百科什么的了。搜索框和结果也从右上角搬到了屏幕中心(Alfred 哭死)
  • 通知中心支持 Widget 扩展,是不是把 Dashboard 挪那去了?
  • 内置 iCloud Drive 网盘功能(也有 Windows 版),这个太方便了。邮件也可以发送超大附件了。
  • MarkUp 标注识别功能,简单说就是你在图片上用鼠标简单画个箭头或文字气泡什么的,Mac 会识别过来并转换成正规的箭头和气泡。给图片或 PDF 文档添加标注时超方便。
  • Mac 和 iPhone 蓝牙连接后,直接在电脑上接打电话和收发短信。打个比方,iPhone 变成 Mac 的手机卡插槽。而且还有更多的同步融合功能,比如电脑上打开邮件应用,可以自动显示手机上写到一半的邮件接着写;Mac 上文档做到一半,出门打开 iPad 继续做 …… 苹果的平台整合大法发力后真是太方便了。
  • Safari 浏览器做了很多改进,比如选中地址栏但还没输入网址时,自动弹出书签;还有标签滚动显示等等。

更多介绍,看苹果官网吧 http://www.apple.com/osx/preview/。强烈建议大家看发布会的演示视频,尤其是 Mac 和 iPhone 协同那一段。

OS X Yosemite 系统今年秋天出正式版,免费。心急的话现在就可以下载 Beta 版试用,面向全体用户开放的,不是开发者也没问题。

iOS 8

  • 可以从通知中心和锁屏界面直接回复短信或社交应用推送来的信息了。通知中心里还能安装 Widget 扩展功能。
  • 短信应用大升级,支持群聊,支持按下直接录微信那样的语音 iMessage,甚至可以发视频和地理位置。
  • 输入法增加 QuickType 功能,自动推测你下面要输入什么内容,显示在候选栏里,点一下就行不用打字了(支持中文)。
  • 可以有第三方输入法了(这恐怕是越狱的最大动力了吧),指纹识别也可以让第三方应用调用了(支付宝什么的刷指纹而不是输密码)
  • AirDrop 终于支持 Mac 和 iOS 设备之间传输
  • 一家人可以共享照片、日历等项目,熊孩子乱按乱买 App 的话,家长的手机上会提示输入密码。

还有 支持应用之间数据互通,Spotlight 搜索增强(见上一段 Mac 那部分),Siri 支持听声音识别歌名,更多的照片美化功能,更强的游戏画面渲染功能,HomeKit 智能家居方案+CloudKit 云存储方案+Health 健康与运动数据方案(都是面向开发者的)…… 等等等等功能。看苹果官网介绍吧 http://www.apple.com/ios/ios8/

iOS 8 系统也是今年秋天正式发布,现在的 Beta 版只有苹果开发者可以下载。坏消息是:iPhone 4 被踢出可升级机型列表了。

最后,苹果还发布了新的编程语言:Swift。看起来比 Objective-C 简单得多。


苹果中国官网还没更新,所以放的是美国官网的英文页面地址。发布会视频也没贴出来。过几小时发布会视频和中文版网页上线,我会更新本文。


Tags - ,

Google https被屏蔽

$
0
0

  根据Google透明度报告 显示,从上周(5月27日)开始,Google的部分服务开始被屏蔽,其中最主要的是HTTPS搜索服务和Google登录服务,所有版本的Google都受到影响,包括Google.hk和Google.com等。

  此次屏蔽的方法主要屏蔽Google部分IP地址的443端口,包括google.com.hk,accounts.google.com的部分IP的443端口被封,导致部分中国用户无法访问Google搜索和Gmail,由于Google的IP地址非常多,而被屏蔽的只是其中部分IP,因此只有部分用户受到了影响。

  解决的方法很简单,只要找一个未被屏蔽443端口的IP地址替代原有IP即可,设置的方法是,在hosts中设置www.google.com、www.google.com.hk、accounts.google.com这几个域名的IP为可用的美国Google官方IP即可。这个IP的寻找方法是,找一个PING工具,从世界各地PING目标域名,然后从里面的IP地址寻找可用IP地址即可。

  随着Google在中国市场份额的逐步下降,“全面屏蔽Google”已经变得越来越有可能,Google无法访问的时间也将变得越来越长,直到未来永久无法访问。

评论《Google https被屏蔽》的内容...

找不到相关文章,请发表留言


微博: 新浪微博 - 微信公众号:williamlonginfo
月光博客投稿信箱:williamlong.info(at)gmail.com
Created by William Long www.williamlong.info

苹果的新编程语言 Swift 简介

$
0
0

原文出处:  Lucia(@peng_gong)欢迎加入 iOS小组

关于

这篇文章简要介绍了苹果于 WWDC 2014发布的编程语言——Swift。

前言

在这里我认为有必要提一下 Brec VictorInventing on Principle,Swift编程环境的大部分概念都源自于 Brec这个演讲。

接下来进入正题。

 

Swift是什么?

Swift是苹果于WWDC 2014发布的编程语言,这里引用 The Swift Programming Language的原话:

Swift is a new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility. Swift adopts safe programming patterns and adds modern features to make programming easier, more flexible and more fun. Swift’s clean slate, backed by the mature and much-loved Cocoa and Cocoa Touch frameworks, is an opportunity to imagine how software development works. Swift is the first industrial-quality systems programming language that is as expressive and enjoyable as a scripting language.

简单的说:

  1. Swift用来写iOS和OS X程序。(估计也不会支持其它屌丝系统)
  2. Swift吸取了C和Objective-C的优点,且更加强大易用。
  3. Swift可以使用现有的Cocoa和Cocoa Touch框架。
  4. Swift兼具编译语言的高性能(Performance)和脚本语言的交互性(Interactive)。

Swift语言概览

基本概念

注:这一节的代码源自 The Swift Programming Language中的 A Swift Tour

Hello, world

类似于脚本语言,下面的代码即是一个完整的Swift程序。

1
println("Hello, world")

变量与常量

Swift使用 var声明变量, let声明常量

1
2
3
var myVariable = 42
myVariable = 50
let myConstant = 42

类型推导

Swift支持类型推导(Type Inference),所以上面的代码不需指定类型,如果需要指定类型:

1
let explicitDouble : Double = 70

Swift不支持隐式类型转换(Implicitly casting),所以下面的代码需要显式类型转换(Explicitly casting):

1
2
3
let label = "The width is "
let width = 94
let width = label + String(width)

字符串格式化

Swift使用 \(item)的形式进行字符串格式化:

1
2
3
4
let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let appleSummary = "I have \(apples + oranges) pieces of fruit."

数组和字典

Swift使用 []操作符声明数组(array)和字典(dictionary):

1
2
3
4
5
6
7
8
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"

一般使用初始化器(initializer)语法创建空数组和空字典:

1
2
let emptyArray = String[]()
let emptyDictionary = Dictionary<String, Float>()

如果类型信息已知,则可以使用 []声明空数组,使用 [:]声明空字典。

控制流

概览

Swift的条件语句包含 ifswitch,循环语句包含 for-inforwhiledo-while,循环/判断条件不需要括号,但循环/判断体(body)必需括号:

1
2
3
4
5
6
7
8
9
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
forscore in individualScores {
ifscore > 50 {
teamScore += 3
} else{
teamScore += 1
}
}

可空类型

结合 iflet,可以方便的处理可空变量(nullable variable)。对于空值,需要在类型声明后添加 ?显式标明该类型可空。

1
2
3
4
5
6
7
8
var optionalString: String? = "Hello"
optionalString == nil
var optionalName: String? = "John Appleseed"
var gretting = "Hello!"
iflet name = optionalName {
gretting = "Hello, \(name)"
}

灵活的switch

Swift中的 switch支持各种各样的比较操作:

1
2
3
4
5
6
7
8
9
10
11
let vegetable = "red pepper"
switchvegetable {
case"celery":
let vegetableComment = "Add some raisins and make ants on a log."
case"cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich."
caselet x where x.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(x)?"
default:
let vegetableComment = "Everything tastes good in soup."
}

 

其它循环

for-in除了遍历数组也可以用来遍历字典:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
varlargest = 0
for(kind, numbers) ininterestingNumbers {
fornumber innumbers {
ifnumber > largest {
largest = number
}
}
}
largest

while循环和 do-while循环:

1
2
3
4
5
6
7
8
9
10
11
var n = 2
whilen < 100 {
n = n * 2
}
n
var m = 2
do{
m = m * 2
} whilem < 100
m

Swift支持传统的 for循环,此外也可以通过结合 ..(生成一个区间)和 for-in实现同样的逻辑。

1
2
3
4
5
6
7
8
9
10
11
var firstForLoop = 0
fori in 0..3 {
firstForLoop += i
}
firstForLoop
var secondForLoop = 0
forvar i = 0; i < 3; ++i {
secondForLoop += 1
}
secondForLoop

注意:Swift除了 ..还有 .....生成前闭后开的区间,而 ...生成前闭后闭的区间。

函数和闭包

函数

Swift使用 func关键字声明函数:

1
2
3
4
func greet(name: String, day: String) -> String {
return"Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")

通过元组(Tuple)返回多个值:

1
2
3
4
func getGasPrices() -> (Double, Double, Double) {
return(3.59, 3.69, 3.79)
}
getGasPrices()

支持带有变长参数的函数:

1
2
3
4
5
6
7
8
9
func sumOf(numbers: Int...) -> Int {
var sum = 0
fornumber in numbers {
sum += number
}
returnsum
}
sumOf()
sumOf(42, 597, 12)

函数也可以嵌套函数:

1
2
3
4
5
6
7
8
9
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
returny
}
returnFifteen()

作为头等对象,函数既可以作为返回值,也可以作为参数传递:

1
2
3
4
5
6
7
8
func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return1 + number
}
returnaddOne
}
var increment = makeIncrementer()
increment(7)
1
2
3
4
5
6
7
8
9
10
11
12
13
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
foritem in list {
ifcondition(item) {
returntrue
}
}
returnfalse
}
func lessThanTen(number: Int) -> Bool {
returnnumber < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, lessThanTen)

闭包

本质来说,函数是特殊的闭包,Swift中可以利用 {}声明匿名闭包:

1
2
3
4
5
numbers.map({
(number: Int) -> Int in
let result = 3 * number
returnresult
})

当闭包的类型已知时,可以使用下面的简化写法:

1
numbers.map({ number in 3 * number })

此外还可以通过参数的位置来使用参数,当函数最后一个参数是闭包时,可以使用下面的语法:

1
sort([1, 5, 3, 12, 2]) { $0 > $1 }

类和对象

创建和使用类

Swift使用 class创建一个类,类可以包含字段和方法:

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

创建 Shape类的实例,并调用其字段和方法。

1
2
3
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

通过 init构建对象,既可以使用 self显式引用成员字段( name),也可以隐式引用( numberOfSides)。

1
2
3
4
5
6
7
8
9
10
11
12
classNamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return"A shape with \(numberOfSides) sides."
}
}

使用 deinit进行清理工作。

继承和多态

Swift支持继承和多态( override父类方法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
classSquare: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 4
}
func area() -> Double {
returnsideLength * sideLength
}
override func simpleDescription() -> String {
return"A square with sides of length \(sideLength)."
}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

注意:如果这里的 simpleDescription方法没有被标识为 override,则会引发编译错误。

属性

为了简化代码,Swift引入了属性(property),见下面的 perimeter字段:

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
classEquilateralTriangle: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return"An equilateral triagle with sides of length \(sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength

注意:赋值器(setter)中,接收的值被自动命名为 newValue

willSet和didSet

EquilateralTriangle的构造器进行了如下操作:

  1. 为子类型的属性赋值。
  2. 调用父类型的构造器。
  3. 修改父类型的属性。

如果不需要计算属性的值,但需要在赋值前后进行一些操作的话,使用 willSetdidSet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
classTriangleAndSquare {
var triangle: EquilateralTriangle {
willSet {
square.sideLength = newValue.sideLength
}
}
var square: Square {
willSet {
triangle.sideLength = newValue.sideLength
}
}
init(size: Double, name: String) {
square = Square(sideLength: size, name: name)
triangle = EquilateralTriangle(sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
triangleAndSquare.square.sideLength
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
triangleAndSquare.triangle.sideLength

从而保证 trianglesquare拥有相等的 sideLength

调用方法

Swift中,函数的参数名称只能在函数内部使用,但方法的参数名称除了在内部使用外还可以在外部使用(第一个参数除外),例如:

1
2
3
4
5
6
7
8
classCounter {
var count: Int = 0
func incrementBy(amount: Int, numberOfTimes times: Int) {
count += amount * times
}
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)

注意Swift支持为方法参数取别名:在上面的代码里, numberOfTimes面向外部, times面向内部。

?的另一种用途

使用可空值时, ?可以出现在方法、属性或下标前面。如果 ?前的值为 nil,那么 ?后面的表达式会被忽略,而原表达式直接返回 nil,例如:

1
2
3
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional
square")
let sideLength = optionalSquare?.sideLength

optionalSquarenil时, sideLength属性调用会被忽略。

枚举和结构

枚举

使用 enum创建枚举——注意Swift的枚举可以关联方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enumRank: Int {
caseAce = 1
caseTwo, Three, Four, Five, Six, Seven, Eight, Nine, Ten
caseJack, Queen, King
func simpleDescription() -> String {
switchself {
case.Ace:
return"ace"
case.Jack:
return"jack"
case.Queen:
return"queen"
case.King:
return"king"
default:
returnString(self.toRaw())
}
}
}
let ace = Rank.Ace
let aceRawValue = ace.toRaw()

使用 toRawfromRaw在原始(raw)数值和枚举值之间进行转换:

1
2
3
iflet convertedRank = Rank.fromRaw(3) {
let threeDescription = convertedRank.simpleDescription()
}

注意枚举中的成员值(member value)是实际的值(actual value),和原始值(raw value)没有必然关联。

一些情况下枚举不存在有意义的原始值,这时可以直接忽略原始值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
enumSuit {
caseSpades, Hearts, Diamonds, Clubs
func simpleDescription() -> String {
switchself {
case.Spades:
return"spades"
case.Hearts:
return"hearts"
case.Diamonds:
return"diamonds"
case.Clubs:
return"clubs"
}
}
}
let hearts = Suit.Hearts
let heartsDescription = hearts.simpleDescription()

除了可以关联方法,枚举还支持在其成员上关联值,同一枚举的不同成员可以有不同的关联的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
enumServerResponse {
caseResult(String, String)
caseError(String)
}
let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Error("Out of cheese.")
switchsuccess {
caselet .Result(sunrise, sunset):
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
caselet .Error(error):
let serverResponse = "Failure... \(error)"
}

结构

Swift使用 struct关键字创建结构。结构支持构造器和方法这些类的特性。结构和类的最大区别在于:结构的实例按值传递(passed by value),而类的实例按引用传递(passed by reference)。

1
2
3
4
5
6
7
8
9
structCard {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return"The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

协议(protocol)和扩展(extension)

协议

Swift使用 protocol定义协议:

1
2
3
4
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}

类型、枚举和结构都可以实现(adopt)协议:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
classSimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {
simpleDescription += " Now 100% adjusted."
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
structSimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

扩展

扩展用于在已有的类型上增加新的功能(比如新的方法或属性),Swift使用 extension声明扩展:

1
2
3
4
5
6
7
8
9
extension Int: ExampleProtocol {
var simpleDescription: String {
return"The number \(self)"
}
mutating func adjust() {
self += 42
}
}
7.simpleDescription

泛型(generics)

Swift使用 <>来声明泛型函数或泛型类型:

1
2
3
4
5
6
7
8
func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] {
var result = ItemType[]()
fori in 0..times {
result += item
}
returnresult
}
repeat("knock", 4)

Swift也支持在类、枚举和结构中使用泛型:

1
2
3
4
5
6
7
// Reimplement the Swift standard library's optional type
enumOptionalValue<T> {
caseNone
caseSome(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)

有时需要对泛型做一些需求(requirements),比如需求某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift通过 where描述这些需求:

1
2
3
4
5
6
7
8
9
10
11
func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {
forlhsItem in lhs {
forrhsItem in rhs {
iflhsItem == rhsItem {
returntrue
}
}
}
returnfalse
}
anyCommonElements([1, 2, 3], [3])

Swift语言概览就到这里,有兴趣的朋友请进一步阅读 The Swift Programming Language

接下来聊聊个人对Swift的一些感受。

个人感受

注意:下面的感受纯属个人意见,仅供参考。

大杂烩

尽管我接触Swift不足两小时,但很容易看出Swift吸收了大量其它编程语言中的元素,这些元素包括但不限于:

  1. 属性(Property)、可空值(Nullable type)语法和泛型(Generic Type)语法源自C#。
  2. 格式风格与Go相仿(没有句末的分号,判断条件不需要括号)。
  3. Python风格的当前实例引用语法(使用 self)和列表字典声明语法。
  4. Haskell风格的区间声明语法(比如 1..31...3)。
  5. 协议和扩展源自Objective-C(自家产品随便用)。
  6. 枚举类型很像Java(可以拥有成员或方法)。
  7. classstruct的概念和C#极其相似。

注意这里不是说Swift是抄袭——实际上编程语言能玩的花样基本就这些,况且Swift选的都是在我看来相当不错的特性。

而且,这个大杂烩有一个好处——就是任何其它编程语言的开发者都不会觉得Swift很陌生——这一点很重要。

拒绝隐式(Refuse implicity)

Swift去除了一些隐式操作,比如隐式类型转换和隐式方法重载这两个坑,干的漂亮。

Swift的应用方向

我认为Swift主要有下面这两个应用方向:

教育

我指的是编程教育。现有编程语言最大的问题就是交互性奇差,从而导致学习曲线陡峭。相信Swift及其交互性极强的编程环境能够打破这个局面,让更多的人——尤其是青少年,学会编程。

这里有必要再次提到 Brec VictorInventing on Principle,看了这个视频你就会明白一个交互性强的编程环境能够带来什么。

应用开发

现有的iOS和OS X应用开发均使用Objective-C,而Objective-C是一门及其繁琐(verbose)且学习曲线比较陡峭的语言,如果Swift能够提供一个同现有Obj-C框架的简易互操作接口,我相信会有大量的程序员转投Swift;与此同时,Swift简易的语法也会带来相当数量的其它平台开发者。

总之,上一次某家大公司大张旗鼓的推出一门编程语言及其编程平台还是在2000年(微软推出C#),将近15年之后,苹果推出Swift——作为开发者,我很高兴能够见证一门编程语言的诞生。

 


© 推荐 for 互联网的那点事. | 猛击下载: iPhone客户端猛击下载: Android客户端


iMessage 整合了语音、视频和地址分享功能,微信是否会受到影响?

$
0
0

答案是不会

微信已经不仅仅是一个语音、视频、地址分享的聊天软件了。
那些聊天的东西,是微信的本源,但是他们现在已经被化为了一种符号、象征性的东西,虽然还具备功能,但是已经和微信本身划不上等号了。
我们用微信,实际上只是觉得自己的需求是聊天,而实际上,我们已经被微信团队一点点的引导到微信建立的平台上。
从公共账号到朋友圈、到游戏、再到现在的购物,微信已经是一个庞大的平台,他从聊天这个功能为起点,发展成了一个生活聚合的面。

不仅微信如此,Line、来往也是如此,甚至连移动的飞信也在如此变化。

iMessage不一样,iMessage是苹果iOS平台上的一个功能,这个功能是为了辅助苹果的iOS平台,甚至Mac iOS混合平台而存在,这个混合平台和微信几乎不存在任何竞争关系。

所以,微信什么都不需要做,也什么都不需要怕,他只要继续做自己的平台就好了。

==========体内酒精含量:0.4%============
这次发布会感触最深的就是iMessage的那个语音交互。某人曾经说过微信是国内用户体验、交互做得最好的软件,这最好的软件在iMessage的面前 简直就是渣啊……微信不是用户体验最好的软件,他是一个国人要的平台,平台不需要用 户体验。
——来自我的微博

— 完 —
本文作者: Bill Cheng

【知乎日报】 你都看到这啦,快来点我嘛 Σ(▼□▼メ)

此问题还有 27 个回答,查看全部。
延伸阅读:
如何评价微信 4.2 支持视频通话功能?
如何评价微信 4.5 测试版的语音聊天室功能?

iOS 8新功能也专注细节:可精确检测单个应用耗电量

$
0
0

batteryusage

iOS 8新功能:精确检测单个应用耗电量

【TechWeb报道】6月3日消息,据国外媒体报道,苹果CEO及其高管在今日召开的全球开发者大会(WWDC)上向开发者展示了iOS 8系统的新功能,其中包括了Messages更新、新QuickType键盘、支持第三方输入法等。但是其中也不乏一些有趣的细节更新,如电量管理可精确到每个应用。

该功能可以方便用户及时查看手机应用的耗电量,并及时对“耗电大户”予以关闭。

同时,iPad将获得跟iPhone一样的全景拍摄功能,其摄像头可以拥有instant burst模式、定时器模式、以及对焦和曝光的单独控制。

电子书iBooks新增支持自动夜间模式(auto Night mode),可以主动将图书进行分类,同时通知将涵盖旅行时间等信息。

此外,iOS 8还拥有一个“小贴士”应用(Tips app),但是目前还不清楚这款应用的具体功能及作用。

iOS还拥有“以防万一”(In Case of Emergency)卡片,可显示联系人和可能与健康相关的信息。

当然,以上所讲述的iOS 8的新功能仅仅是其所有功能的一小部分,由于目前新系统仍在开发阶段,所以正式版面世还需耐心等到今年秋季。(易木)

苹果WWDC 2014汇总:iOS 8、OS X和新的编程语言

$
0
0



北京时间6月3日凌晨1点,苹果在美国旧金山Moscone中心举行了一年一度的WWDC开发者大会。传闻中的iPhone 6、Retina版本的MacBook Air、4K分辨率的iMac均爽约,这是一场只有软件没有硬件的发布会。

1.  全新的Mac OS X 10.10 Yosemite



没有任何悬念,今年的 WWDC 如期发布了全新的OS X Yosemite。和当初的 iOS 7 一样, OS X Yosemite 来了一个超级大变脸,整体采用了扁平化的设计风格:和 iOS 一样的 Dock 栏、全部重新绘制的应用图标,以及随处可见的毛玻璃效果,OS X 的整体设计和 iOS 如出一辙。

当然不仅仅是设计上的变化, 在整个功能上 OS X Yosemite 都借鉴了不少 iOS 的元素,并且进一步同 iOS 进行无缝的整合。例如:

  • 完全重新设计的通知中心,新加入了日历提醒、天气、股票等 iOS 常见的通知栏内容;
  • 首次实现了 OS X 和 iOS 的 AirDrop 连接功能;
  • 通过 Handoff 功能,苹果在 OS X 上整合了 iPhone 的短信和通话功能,可以直接通过 Mac 接打电话......
另外 OS X Yosemite 还带了不少功能上的强化,例如:

  • 重新设计的邮件客户端,支持超大附件的云端中专功能;
  • 全新升级的 Safari 浏览器,据苹果官方给出的数据,几乎在任何测试环节都完胜 Chrome,带来全新的浏览体验;
  • 全新的 iCloud Drive 客户端,用户可以在 Mac、iPhone、iPad 甚至是 PC 之间同步数据。
OS X Yosemite 将在秋季向所有用户免费开放更新,开发者们今天就可以下载测试版本。不是开发者又想提前体验最新 OS X 的朋友则可以通过OS X Beta Seed Program申请。

2.  万众期待的iOS 8,更多的是功能上的改进



刚刚经历过 iOS 7 的重大升级,iOS 8 在界面设计上并没有带给我们太多的惊喜, 依旧延续了 iOS 7 扁平化的风格,但在功能上 iOS 8 还是带来了不少惊喜,比较简单粗暴的总结就是 iOS 越发的 Android 化了。

iOS 8 进一步强化了通知栏的功能,不仅仅是功能上的改动,而是开放了接口,第三方应用可以利用 iOS 8 的接口,直接在通知中心创建 Widget;iOS 8 在收到消息提醒后,可以直接在消息通知栏中回复信息;在多任务界面中整合了常用联系人,点击头像就可以打电话、发短信、或者进行 Facetime;Family Sharing,可以建立一个属于家庭成员之间的“私有云”等等。

iOS 8 还专门针对中国地区进行了优化,例如新增加了矢量地图、点对点导航功能、增加对中国农历的支持,iOS 8 中的 QuickType 功能同样支持中文输入。

尤其值得一提的是新版的 iMessage,iOS 8 中的 iMessage 新增多人群组聊天,支持发送语音消息,支持发送视频,支持发送地理位置,聊天记录中的图片可以归档查看等等,简单的说就是 iMessage 已经全面微信化,引用网友的评论就是,iMessage和微信就只差了一个朋友圈......

3.  对开发者而言,iOS 8正前所未有的开放



相信对于大多数用户来说,他们对于 iOS 8 的感受远不如开发者们来的震撼,这一次的 WWDC 苹果确实给了开发者不少惊喜,而但中很大一部分的惊喜都来自 iOS 8 的开放,不仅仅是开放,而且是前所未有的开放。

就像上面在介绍 iOS 8 功能时提到的那样, iOS 8 强化了通知中心的功能,开发者可以根据苹果提供的接口自行在通知中心创建 Widget,这只是 iOS 8 众多开放接口中的一个而已。例如在 iOS 8 中,苹果向所有开发者开放了社交分享和自定义动作接口,第三方应用也可以像现在 Facebook、Twitter 那样,将分享组件整合进 iOS 中。

大家普遍关心的苹果健康管理和智能家居系统,同样是通过开放系统 API 来实现的。 Healthkit 为可穿戴设备和 App 提供了数据接口,而自带应用 Health 则取代传闻中的 Healthbook,成为苹果对健康类硬件和 App 搭建的信息窗口 + 控制中心 + 数据池。

在智能家居方面,苹果推出的 Homekit 可以对家庭中的灯光、门锁、摄像头、插座开关等各种联网设备进行控制。场景模式与 Siri 的结合十分有趣,你可以睡觉前跟 Siri 说声“晚安”,然后你家大门将自动上锁,灯光则自动关闭。

不仅如此, 有着严格安全红线的 Touch ID 现在也可以被第三方应用所使用,但为了确保安全性,用户指纹数据将被隔离保护,iOS 和第三方应用均无法获取。

相信还有个开放的地方尤其受到中国用户的喜欢,那就是苹果开放了输入法。 在 iOS 8 中,开发者可以向用户提供全系统使用的输入法,输入模式和布局都可以自由定制,WWDC 现场就显示了一款 Swype 式的滑动输入。第三方输入法的记录和词库将可以与 iOS 默认输入法同步。

4.  全新的开发语言Swift,苹果想要再次定义开发规则



在我看来, 整场 WWDC 最大的惊喜就是苹果新推出的全新开发语言——Swift,无论实在编程的难度还是执行效率上,都要甩出 Object-C 好几条街的全新语言, 用苹果自己的话说就是,编程从未如此简单。

Swift 被外国不少技术大牛认为是苹果接下来最具影响力的产品,因为 Swift 会影响整个 OS X 和 iOS 的开发环境。 Swift 比较牛的地方在于,可以兼容 Object-C 和 C 语言,开发者可以在 Object-C 和 C 语言的基础上,继续用 Swift 进行开发

Swift 比起之前的 Object-C 要精简不少,去掉了很多繁琐的代码符号,执行效率要高出不少,而且难度也相应的开发难度也要降低不少;并且 Swift 全部采用可视化编程设计,用户可以一遍写代码,一遍查看代码的实际运行效果,可以进行实时预览,大大提到编程的效率。

为了帮助开发者熟悉 Swift 语言,苹果官方还推出了《The Swift Programming Language》开发指南

其实整场发布会看下来,一个比较强烈的感觉是苹果正在进一步整合 OS X 和 iOS 这两大操作系统,无论是在设计风格上,还是功能设置上,都在相互借鉴融合。

虽然没有发布任何硬件,但足可见苹果在软件生态上下的功夫。尤其是 iOS 8 开放的各种接口,以及推出更加高效的开放工具,苹果对于软件的重视程度可见一斑。

最后,如果错过了苹果的发布会,但又觉得图文直播看得不过瘾的同学,苹果官方已经放出了发布会的视频,点击直接观看。

Via 36氪 / 作者:WANGJINGYU

感谢 WnouM投递这篇资讯

资讯来源: 36氪

已有 2人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



iOS 8与安卓系统有哪些相似点与不同点

$
0
0

今天凌晨,苹果在 WWDC 2014 大会发布了 iOS 8 新系统,关于新系统的新功能和新特性,想必大家都已经初步了解。在初步了解之后,下面我们要讨论的是,iOS 8 的发布对于安卓系统来说意味着什么,它与安卓系统又有哪些异同。

萝卜网

今天的 WWDC 2014 上,苹果用诸多的权限和接口开放接超出了我们的预期,iOS 8 的SDK 含有超过 4000 个新的 API,而且它还有一个 Extensibility 计划,不同的应用可以通过iOS系统级的安全机制,与其它应用进行互动:分享内容至其它应用、在照片应用里使用其它应用的滤镜、在通知栏里添加插件,更夸张的是,支持第三方输入法。

iOS 8 的发布让我们对苹果的看法稍有改观,主要还是与“开放”相关,Extensibility 项目意味着 iOS 8 支持应用间通讯,可以更加开放的共享功能;iOS 8 支持第三方键盘输入法;iOS 8 内嵌的 Touch ID 指纹扫描功能将向应用开放,第三方应用也可以使用。

萝卜网

原本,“开放”的特性是安卓的骄傲,现在苹果也渐渐参与进来,对此,有不少网友表示,iOS 8 加入了“开放性”给了安卓沉重一击,安卓可以洗洗睡了。其实不然,市场往往要比我们所认为的要复杂得多,也要灵活得多。如果你一味的认为 iOS 8 将终结安卓系统,那么请点击电脑右上方的小X。

iOS 8 的发布不只对苹果有利,同时也对安卓有益。iOS 8 的发布对谷歌来说意味着安卓不能懈怠,需要时刻保持警惕。在移动系统市场,苹果与谷歌相互竞争,同时也相互促使彼此进步。通过 Jelly Bean 和 Kitkat 系统,谷歌发布了一些优秀的功能与服务,苹果现在以 iOS 8 的发布给予有力回应,在 iOS 8 发布之后,谷歌又将会在下一代系统中回应 iOS 8,这是一种良性竞争。

下面我们来对比 iOS 8 和安卓系统之间功能的异同。

萝卜网

交互通知(Interactive Notifications),iOS 8 的交互通知功能允许用户直接在通知中心回复信息,而当 Facebook 等社交网络更新时,用户可以直接在通知栏评论或者点赞,在锁屏界面也可以直接回复或删除信息和 iMessage 音频内容。

这个功能很酷,虽然安卓早就已经拥有类似功能,但 iOS 8 的似乎更加完善或者说更加便捷。在安卓系统上,当你点击通知中心里的按钮时,你需要退出当前应用,然后进入附在通知中心中的应用。

在 iOS 8 上,用户不需要离开当前应用也可在通知内回复短信息,这就是 iOS 8 交互通知更为方便的体现。

自动热点和拨打电话

苹果为 iOS 8 加入了自动热点和 Wi-Fi 拨号功能,将 iPhone 自动变成电脑热点,不需要人工设置,然后通过电脑拨打和接听电话。等等,我听到安卓粉丝在说:我们安卓早就有 Google Voice、Hang Outs 和热点应用啦!

没错,安卓早就已经有这些应用,但是 iOS 8 是无缝集成的,无需启动应用,也无需注册 Google Voice,不需要手动设置。iOS 8 新的语音通话和热点集成功能为用户时刻准备着。

萝卜网

通过 Automatic Hotpot 热点功能,用户电脑会识别 iPhone 就在附近,然后允许用户通过热点连接它来使用手机的数据连接,它就出现在 Wi-Fi 选项列表中。在安卓系统中,你需要点击一个部件图标来加载热点,然后激活它。

使用 iOS 8 的语音通话功能,只要用户 iPhone 与电脑相连,用户就可以在电脑上拨打和接听电话。虽然安卓集成的 Google Voice 和 Hangouts 也可以实现这一功能,但安卓用户需要先注册另一个应用或者服务,而 iOS 8 不需要注册。谷歌 Hangouts 未来也打算往这个方向走,在谷歌新 Hangouts(环聊)到来之前,iOS 8 先来了。

萝卜网

快速访问常用联系人

在 iOS 8 系统中,用户双击 iPhone 的 Home 键即可调出用户常用应用,还可以调出常用联系人,点击并进行联系。说句调侃的话,这一功能不止方便我们联系朋友,同时也方便了福尔摩斯女友们抓情敌。

在安卓上,用户不是需要通过 Hangouts(环聊)就是通过 People(通讯录)应用开进行对话,如果有更快捷的联系方式岂不是更好?虽然安卓也有诸多可访问最常用联系人的第三方应用,但 iOS 8 为原生的。

萝卜网

信息、群组信息

Hangouts(环聊)是安卓系统的信息应用,虽然整合了通讯录和 Google +,但 iOS 8 上的 iMessage 或 Messages 更好一些。苹果今天发布了新的群组控制功能,比如在群组信息中,地图可以显示参与者的位置,或者也可以在群组中分享相册。

以上这一功能未来安卓也会增加,谷歌或许正在努力。

萝卜网

Family Sharing(家庭分享功能)

苹果为 iOS 8 加入了 Family Share(家庭分享功能),允许用户分享位置、照片、日历、应用程序、音乐和视频等等。家庭分享功能中最重要的是 iTunes 购买内容的分享,也就是说同一张信用卡的所购买的专辑或者电影可以分享给家人(最多不超过 6 人),家人无需再次购买。

安卓也有类似的分享功能,不同的是,安卓用户需要再多款不同的设备上添加相同的 Gmail 账户之后才可以分享。

萝卜网

应用程序包

App Bundle 是捆缚式的应用出售,开发者可以将几个应用捆绑在一起,以一个比单独分别购买便宜的价格出售。

这样的应用促销模式安卓 Google Play 或许也可以借鉴,在节日的时候将受欢迎的数款应用捆绑出售。

Hey,Siri 和 Ok,Google

最后我们要讲的是是Hey,Siri和安卓的 Ok,Google 功能。一听到 iOS 8 添加 Hey,Siri 的时候,我们第一反应是 Ok,Google。

Siri的新版本可以不接触手机就被激活,用户只要说“Hey,Siri”就可以把它唤醒,让它听从你的命令为你工作。其实这与 Ok,Google 的功能一模一样,用过的人都知道。


您可能对以下文章感兴趣:

是否值得升级:iOS 8系统截图画廊

iOS7最凶残功能

伤害小伙伴们的机会来啦!IOS/MacOS系统发现存在远程拒绝服务漏洞

牛人用Word撸出一个iOS 7出来 中英字幕

从城市废水到Isar河水——慕尼黑的排水系统
来自无觅网络的相关文章:

30个iOS系统的App应用程序Icon设计(@uuhy)

【技巧】如何解决 iOS 4.3 系统同步失败问题(@syncoo)

苹果 iOS5 系统体验评测 [iPad] (多图+附下载地址)(@syncoo)

[征文] A.shun:假如一小时后我的系统崩溃…?(@syncoo)

这台笔记本用的是win7系统吗?(@fanjian)
无觅

相似度计算常用方法综述

$
0
0

1、引言

相似度计算用于衡量对象之间的相似程度,在数据挖掘、自然语言处理中是一个基础性计算。其中的关键技术主要是两个部分,对象的特征表示,特征集合之间的相似关系。在信息检索、网页判重、推荐系统等,都涉及到对象之间或者对象和对象集合的相似性的计算。而针对不同的应用场景,受限于数据规模、时空开销等的限制,相似度计算方法的选择又会有所区别和不同。下面章节会针对不同特点的应用,进行一些常用的相似度计算方法进行介绍。

2、向量空间模型

向量空间模型(Vector space model)是应用最广泛的一个基础相似度计算模型,在该模型中,每个对象映射为一个特征向量:

image

image

作为一个应用广泛的模型,向量空间模型在现有的很多应用中仍然起着至关重要的作用,也是很多扩展方法的基础。

3、基于hash方法的相似计算

基于hash的相似度计算方法,是一种基于概率的高维度数据的维度削减的方法,主要用于大规模数据的压缩与实时或者快速的计算场景下,基于hash方法的相似度计算经常用于高维度大数据量的情况下,将利用原始信息不可存储与计算的问题转化为映射空间的可存储计算问题,在海量文本重复性判断方面,近似文本查询方面有比较多的应用,google的网页去重 [1],google news的协同过滤 [2,3]等都是采用hash方法进行近似相似度的计算,比较常见的应用场景Near-duplicate detection、Image similarity identification、nearest neighbor search,常用的一些方法包括I-match,Shingling、Locality-Sensitive Hashing族等方法,下面针对几种常见的hash方法进行介绍。

3.1 minhash方法介绍

Minhash方法是Locality-sensitive hashing [4,5]算法族里的一个常用方法,基本的思想是,对于每一个对象的itemlist,将输入的item进行hash,这样相似的item具有很高的相似度被映射到相同的buckets 里面,这样尽量保证了hash之后两个对象之间的相似程度和原来是高相似的,而buckets的数量是远远小于输入的item的,因此又达到降低复杂度的目的。

minhash方法用Jaccard进行相似度的计算方法,则对于两个集合Ci和Cj,Ci 和Cj的相似性的计算方法为:

image

当两个集合越相似,则该值越接近1,否则越接近0。用minhash方法,将一个集合映射到[0-R-1]之间的值,以相同的概率随机的抽取一个[0-R-1[的一个排列,依次排列查找第一次出现1的行。

image

设随机排列为43201(edcab),对于C1列,第一次出现1的行是R4,所以h(C1) = 3,同理有h(C2)=2, h(C3)=4, h(C4)=3。

通过多次抽取随机排列得到n个minhash函数h1,h2,…,hn,依此对每一列都计算n个minhash值。对于两个集合,看看n个值里面对应相等的比例,即可估计出两集合的Jaccard相似度。可以把每个集合的n个minhash值列为一列,得到一个n行C列的签名矩阵。因为n可远小于 R,这样在压缩了数据规模的同时,并且仍能近似计算出相似度。

3.2 simhash方法介绍

simhash方法是在大文本重复识别常用的一个方法,该方法主要是通过将对象的原始特征集合映射为一个固定长度的签名,将对象之间的相似度的度量转化为签名的汉明距离,通过这样的方式,极大限度地进行了降低了计算和存储的消耗。

3.2.1 签名计算过程

       该方法通过对输入特征集合的计算步骤可以描述如下:

  1. 将一个f维的向量V初始化为0;f位的二进制数S初始化为0;
  2. 对每一个特征:用传统的hash算法对该特征产生一个f位的签名b。对i=1到f:

      如果b的第i位为1,则V的第i个元素加上该特征的权重;

      否则,V的第i个元素减去该特征的权重。

  1. 如果V的第i个元素大于0,则S的第i位为1,否则为0;
  2. 输出S作为签名。

通过上述步骤将输入的表示对象的特征集合转化为该对象的一个签名,在完成签名之后,度量两个对象的相似度的差异即变成了对量二者的指纹的K位的差异情况。

3.2.2 汉明距离查找优化

对于如何快速查找出某一个签名是否与其存在最大差异不超过K个bit的指纹,Detecting Near-Duplicates for Web Crawling这篇论文中进行了介绍。该查找方法的基本思想是利用空间换时间的方法,该方法的依据是需要查找的两个指纹的差异很小,这样可以通过将原始指纹进行分块索引,如果两个指纹的差异很小,则合理的分块后,根据鸽笼原理,其中存在一定数量的块是一致的,通过利用相同的块进行相似的指纹的召回,只需要比对召回的块中有差异的块的bit差异,这样减少了需要比对的数量,节省了比对的时间开销。

3.3 小结

hash方法的相似度计算的主要应用场景,一般是针对大规模数据进行压缩,在保证效果损失可接受的情况下,节省存储空间,加快运算速度,针对该方法的应用,在目前的大规模的互联网处理中,很多相似度的计算都是基于这种近似性的计算,并取得了比较好的效果。

设随机排列为43201(edcab),对于C1列,第一次出现1的行是R4,所以h(C1) = 3,同理有h(C2)=2, h(C3)=4, h(C4)=3。

通过多次抽取随机排列得到n个minhash函数h1,h2,…,hn,依此对每一列都计算n个minhash值。对于两个集合,看看n个值里面对应相等的比例,即可估计出两集合的Jaccard相似度。可以把每个集合的n个minhash值列为一列,得到一个n行C列的签名矩阵。因为n可远小于R,这样在压缩了数据规模的同时,并且仍能近似计算出相似度。

4、基于主题的相似度计算

传统的BOW(bag-of_words)模型,一般都会建立在特征独立假设的基础上,按照特征向量的匹配情况来度量对象之间的相似度,但是在实际的应用中,很多时候特征之间存在着很多的关联关系,二者在传统的BOW模型中无法解决,在这个基础上,引入了主题的概念,通过主题的思想,建立起基本特征与对象的中间层的关联关系,主题的概念的引入,主要是在原有的基本特征粒度的基础上,引入了更为丰富的隐含层特征,提高了相似性计算的效果,常用的主题分析方法包括Latent Semantic Analysis (LSA) 、 Probabilitistic Latent Semantic Analysis (PLSA)、Latent Dirichlet Allocation ( LDA)。这些方法在分类,聚类、检索、推荐等领域都有着很多的应用,并取得了比较好的效果。下面就LSA及PLSA方法进行简要介绍。

4.1 LSA简介

LSA [6,7]模型认为特征之间存在某种潜在的关联结构,通过特征-对象矩阵进行统计计算,将高维空间映射到低纬的潜在语义结构上,构建出LSA空间模型,从而提取出潜在的语义结构,并用该结构表示特征和对象,消除了词汇之间的相关性影响,并降低了数据维度。增强了特征的鲁棒性

LSA利用奇异值分解来进行计算,数学过程可以表述如下:

对于 的矩阵A,其中m为特征数,n为样本数。令 image,经过奇异值分解,矩阵A可分解成3个矩阵的乘积:

image

其中,U、V是m×r和n×r的正交矩阵,分别称为矩阵A的奇异值对应的左、右奇异向量,∑是r×r的对角矩阵,称为A的奇异标准形,其对角元素为矩阵A的奇异值。奇异值按照递减的排列构成对角矩阵∑,取∑中前k个最大奇异值构成∑k的,取U和V最前面的k列构成m×k的U k和n×k的V k,构建A的k-秩矩阵Ak(m×n)

image

其中,U k和V k中的行向量分别作为特征向量和对象向量,k是降维后的维数。

4.2 plsa介绍

PLSA [8,9]模型是由Hofmann提出的用于文本检索的概率生成模型,与相比较于LSA,PLSA是基于概率模型的,并直接引入了潜在class变量 z∈Z={Z 1…Z k},下面的用文本处理语言来描述该模型。

image

选定一篇文档的概率p(d),每篇文档以概率p(z|d)属于一个主题,而给定一个主题,每一个词以概率p(w|z) 产生。将这个过程形成联合的概率模型表达式:

image

在PLSA实际的使用过程中,存在着overfit的风险,一般训练过程是通过EM算法,进行模型参数训练,获得p(z|d)、p(w|z)概率。

PLSA和其相关的变形,在分类、聚类、检索等方面,特征相关性计算等方面,获得了广泛的应用,并取得了比较好的效果。

4.3 小结

主题方法的引入,在一定程度上弥补了BOW的假设的独立性,在工业中,主题的方法也越来越多的应用到实际的机器学习中,包括在图像处理领域、传统的分类、聚类、检索等方面,都取得了比较好的效果。

5、总结

相似度的计算在数据挖掘方面有着广泛的应用,根据不同的应用场景,各种方法各有其优劣特点,对于相似度效果的影响,除了方法本身之外,合理有效的特征的选择和使用也是至关重要的,同时,根据应用场景的不同,选择合理的方法,对于解决问题,有着重要的作用。

 

参考文献:

1. G.S. Manku, A. Jain, A.D. Sarma. Detecting Near-Duplicates for Web Crawling. WWW2007, 2007

2. A. Das, M. Datar, A.Garg. Google News Personalization: Scalable Online Collaborative Filtering. WWW2007, 2007

3. http://en.wikipedia.org/wiki/MinHash

4. M. S. Charikar. Similarity estimation techniques from rounding algorithms. STOC’02. 2002

5. http://en.wikipedia.org/wiki/Locality-sensitive_hashing

6. K. Dave, S. Lawrence, and D. Pennock. Mining the peanut gallery: opinion extraction and semantic classification of product reviews. In Proceedings of the 22th International World Wide Web Conference, Budapest, Hungary, 2003

7. http://en.wikipedia.org/wiki/Latent_semantic_analysis

8. T. Hofmann. Probabilistic Latent Semantic Analysis. In Proceedings of the 15th Conference on Uncertainty in AI(1999).

9. Y. M kim, J. F. Pressiot M. R.Amini etc. An Extension of PLSA for Document Clustering. CIKM’08

 

全文转载自: http://stblog.baidu-tech.com/?p=1846


  青春就应该这样绽放   游戏测试:三国时期谁是你最好的兄弟!!   你不得不信的星座秘密
Viewing all 15843 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>