??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲日韩在线第一页,国产日产亚洲系列最新,亚洲精品456人成在线http://www.tkk7.com/cnfree/    三h行,必有我师?/description>zh-cnFri, 09 May 2025 17:36:46 GMTFri, 09 May 2025 17:36:46 GMT60怎么一键批量删除PDF中的囄水印Q?/title><link>http://www.tkk7.com/cnfree/archive/2021/03/09/435819.html</link><dc:creator>三h行,必有我师?/dc:creator><author>三h行,必有我师?/author><pubDate>Tue, 09 Mar 2021 12:29:00 GMT</pubDate><guid>http://www.tkk7.com/cnfree/archive/2021/03/09/435819.html</guid><wfw:comment>http://www.tkk7.com/cnfree/comments/435819.html</wfw:comment><comments>http://www.tkk7.com/cnfree/archive/2021/03/09/435819.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/cnfree/comments/commentRss/435819.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/cnfree/services/trackbacks/435819.html</trackback:ping><description><![CDATA[     摘要: 很多|上下蝲的PDF文g都包含各UŞ式的水印Q本文主要阐q如何用易转换一键删除PDF文g中的各种囄水印和文字水?nbsp; <a href='http://www.tkk7.com/cnfree/archive/2021/03/09/435819.html'>阅读全文</a><img src ="http://www.tkk7.com/cnfree/aggbug/435819.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/cnfree/" target="_blank">三h行,必有我师?/a> 2021-03-09 20:29 <a href="http://www.tkk7.com/cnfree/archive/2021/03/09/435819.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【原创】用Scala IDE~译Spark源代?/title><link>http://www.tkk7.com/cnfree/archive/2016/11/08/431965.html</link><dc:creator>三h行,必有我师?/dc:creator><author>三h行,必有我师?/author><pubDate>Tue, 08 Nov 2016 05:12:00 GMT</pubDate><guid>http://www.tkk7.com/cnfree/archive/2016/11/08/431965.html</guid><wfw:comment>http://www.tkk7.com/cnfree/comments/431965.html</wfw:comment><comments>http://www.tkk7.com/cnfree/archive/2016/11/08/431965.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/cnfree/comments/commentRss/431965.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/cnfree/services/trackbacks/431965.html</trackback:ping><description><![CDATA[Spark源代码下载地址Q?<a >http://spark.apache.org/downloads.html</a><br /> <br /> 下蝲后,直接?Scala IDE 通过已存在的目导入到Eclipse workspace中去Q然后Eclipse会自动进行编译。第一ơ编译会报很多错误,不过ȝ来说Q导致编译错误的源头有三个:<br /> 1、Scala~译器版本错?br /> 2、Eclipse Maven插g不能自动识别spark project的一些pomQ报Plugin execution not covered by lifecycle configuration异常<br /> 3、一些项目,maven会自动生成scala和java文gQ但是这些自动生成的代码文g没有配置在eclipse目的classpath里?br /> <br /> 针对W一U错误,比较单,对于每个scala目Q右键属性选择spark对应的scala~译器版本?br /> <br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/scala_compiler.png" border="0" alt="" /><br /> <br /> 当然spark代码里的目有几十个Q只能手工一个个讄了,比较傻,没办法,q不停的弹出对话框,不停地回车吧?br /> <br /> ~译的难点主要在W二U错误上Q比如spark-sql目的pom, 里面有个build-helper-maven-pluginQ它下面的executionQeclipse maven插g无法识别Q报Plugin execution not covered by lifecycle configuration异常Q解x案参?<a >https://www.eclipse.org/m2e/documentation/m2e-execution-not-covered.html</a>Q先使用 Eclipse <span style="color: #555555; font-family: "Open Sans", sans-serif; font-size: 15px; line-height: 24px; background-color: #ffffff;">quick-fix选项自动修复Q忽略此 maven goalQEclipse 会ؓ pom.xml自动d一Dxml代码Q包含在 </span>pluginManagement section中,里面有一D?<action><ignore/></action>Q此处手动修Ҏ<br /> <div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; "><</span><span style="color: #800000; ">action</span><span style="color: #0000FF; ">></span><br />     <span style="color: #0000FF; "><</span><span style="color: #800000; ">execute</span><span style="color: #0000FF; ">></span><br />         <span style="color: #0000FF; "><</span><span style="color: #800000; ">runOnIncremental</span><span style="color: #0000FF; ">></span>false<span style="color: #0000FF; "></</span><span style="color: #800000; ">runOnIncremental</span><span style="color: #0000FF; ">></span><br />     <span style="color: #0000FF; "></</span><span style="color: #800000; ">execute</span><span style="color: #0000FF; ">></span><br /> <span style="color: #0000ff;"></</span><span style="color: #800000; ">action</span><span style="color: #0000FF; ">></span></div> 然后右键 maven update project OK了?br /> <br /> 一共有5个project需要修改pomQ如?br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/pom.png" border="0" alt="" /><br /> <br /> 修改pom后重新编译,依旧会报一些错误,q些错误都是׃maven自动生成的java和scala代码没有d到classpath里导致的~译错误Q只需要手工添加一下即可,需要手工添加项目有 spark-streaming-flume-sink ?src_managed\main\compiled_avro 目录 ?spark-sql 目?test\gen-java 目录?br /> <br /> 全部~译好以后的截图Q?br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/spark.png" width="311" height="700" alt="" /><br /><br />修改完以后,Spark代码全部~译下来大概耗时25分钟左右QCPU 双核 I7 4600Q?br /><br />原文地址Q?a id="Editor_Edit_hlEntryLink" title="view: 【原创】用Scala IDE~译Spark源代? href="http://www.tkk7.com/cnfree/archive/2016/11/08/431965.html" target="_blank" style="color: #002c99; text-decoration: none; font-family: arial; font-size: 12px; line-height: normal; background-image: inherit; background-attachment: inherit; background-color: #ffffff; background-size: inherit; background-origin: inherit; background-clip: inherit; background-position: inherit; background-repeat: inherit;">http://www.tkk7.com/cnfree/archive/2016/11/08/431965.html</a><img src ="http://www.tkk7.com/cnfree/aggbug/431965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/cnfree/" target="_blank">三h行,必有我师?/a> 2016-11-08 13:12 <a href="http://www.tkk7.com/cnfree/archive/2016/11/08/431965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转:Spark知识体系完整解读http://www.tkk7.com/cnfree/archive/2016/09/08/431774.html三h行,必有我师?/dc:creator>三h行,必有我师?/author>Thu, 08 Sep 2016 05:11:00 GMThttp://www.tkk7.com/cnfree/archive/2016/09/08/431774.htmlhttp://www.tkk7.com/cnfree/comments/431774.htmlhttp://www.tkk7.com/cnfree/archive/2016/09/08/431774.html#Feedback0http://www.tkk7.com/cnfree/comments/commentRss/431774.htmlhttp://www.tkk7.com/cnfree/services/trackbacks/431774.html  Spark?/span>

  Spark是整个BDAS的核心组Ӟ是一个大数据分布式编E框Ӟ不仅实现了MapReduce的算子map 函数和reduce函数及计模型,q提供更Z富的子Q如filter、join、groupByKey{。是一个用来实现快速而同用的集群计算的^台?/p>

  Spark分布式数据抽象为弹性分布式数据集(RDDQ,实现了应用Q务调度、RPC、序列化和压~,qؓq行在其上的上层lg提供API。其底层采用Scalaq种函数式语a书写而成Qƈ且所提供的API深度借鉴Scala函数式的~程思想Q提供与ScalacM的编E接?/p>

  Sparkon Yarn

  

  从用h交作业到作业q行l束整个q行期间的过E分析?/span>

  一、客Lq行操作

  1. ҎyarnConf来初始化yarnClientQƈ启动yarnClient

  2. 创徏客户端ApplicationQƈ获取Application的IDQ进一步判断集中的资源是否满executor和ApplicationMaster甌的资源,如果不满_抛出IllegalArgumentExceptionQ?/span>

  3. 讄资源、环境变量:其中包括了设|Application的Staging目录、准备本地资源(jar文g、log4j.propertiesQ、设|Application其中的环境变量、创建Container启动的Context{;

  4. 讄Application提交的ContextQ包括设|应用的名字、队列、AM的申LContainer、标记该作业的类型ؓSparkQ?/span>

  5. 甌MemoryQƈ最l通过yarnClient.submitApplication向ResourceManager提交该Application?/span>

  当作业提交到YARN上之后,客户端就没事了,甚至在终端关掉那个进E也没事Q因为整个作业运行在YARN集群上进行,q行的结果将会保存到HDFS或者日志中?/span>

  二、提交到YARN集群QYARN操作

  1. q行ApplicationMaster的runҎQ?/span>

  2. 讄好相关的环境变量?/span>

  3. 创徏amClientQƈ启动Q?/span>

  4. 在Spark UI启动之前讄Spark UI的AmIpFilterQ?/span>

  5. 在startUserClass函数专门启动了一个线E(名称为Driver的线E)来启动用h交的ApplicationQ也是启动了Driver。在Driver中将会初始化SparkContextQ?/span>

  6. {待SparkContext初始化完成,最多等待spark.yarn.applicationMaster.waitTriesơ数Q默认ؓ10Q,如果{待了的ơ数过了配|的Q程序将会退出;否则用SparkContext初始化yarnAllocatorQ?/span>

  7. 当SparkContext、Driver初始化完成的时候,通过amClient向ResourceManager注册ApplicationMaster

  8. 分配q启动Executeors。在启动Executeors之前Q先要通过yarnAllocator获取到numExecutors个ContainerQ然后在Container中启动Executeors?/span>

      那么q个Application失败,Application Status标明为FAILEDQƈ关闭SparkContext。其实,启动Executeors是通过ExecutorRunnable实现的,而ExecutorRunnable内部是启动CoarseGrainedExecutorBackend的?/span>

  9. 最后,Task在CoarseGrainedExecutorBackend里面q行Q然后运行状况会通过Akka通知CoarseGrainedSchedulerQ直C业运行完成?/span>

  Spark节点的概?/strong>

  一、Spark驱动器是执行E序中的main()Ҏ的进E?/strong>它执行用L写的用来创徏SparkContext(初始?、创建RDDQ以及运行RDD的{化操作和行动操作的代码?/p>

  驱动器节点driver的职责:

  1. 把用L序{ZQ务task(driver)

      Spark驱动器程序负责把用户E序转化为多个物理执行单元,q些单元也被UCZQ务task(详解见备?

  2. 为执行器节点调度d(executor)

      有了物理计划之后QSpark驱动器在各个执行器节点进E间协调d的调度。Spark驱动器程序会Ҏ当前的执行器节点Q把所有Q务基于数据所在位|分配给合适的执行器进E。当执行dӞ执行器进E会把缓存的数据存储hQ而驱动器q程同样会跟t这些缓存数据的位置Qƈ利用q些位置信息来调度以后的dQ以量减少数据的网l传输。(是所谓的Ud计算Q而不Ud数据)?/p>

  二、执行器节点

  作用Q?/p>

  1. 负责q行l成Spark应用的Q务,q将l果q回l驱动器q程Q?/span>

  2. 通过自n的块理?blockManager)为用L序中要求~存的RDD提供内存式存储。RDD是直接缓存在执行器进E内的,因此d可以在运行时充分利用~存数据加快q算?/span>

  驱动器的职责Q?/p>

  所有的SparkE序都遵循同Ll构Q程序从输入数据创徏一pdRDDQ再使用转化操作z成新的RDDQ最后用行动操作手机或存储l果RDDQSparkE序其实是隐式地创徏Z一个由操作l成的逻辑上的有向无环图DAG。当驱动器程序执行时Q它会把q个逻辑图{为物理执行计划?/p>

  q样 Spark把逻辑计划转ؓ一pd步骤(stage)Q而每个步骤又由多个Q务组成。这些Q务会被打包送到集群中?/p>

  Spark初始?/span>

  1. 每个Spark应用都由一个驱动器E序来发起集上的各Uƈ行操作。驱动器E序包含应用的main函数Qƈ且定义了集群上的分布式数据集Q以及对该分布式数据集应用了相关操作?/span>

  2. 驱动器程序通过一个SparkContext对象来访问spark,q个对象代表对计集的一个连接。(比如在sparkshell启动时已l自动创Z一个SparkContext对象Q是一个叫做SC的变量?下图Q查看变量sc)

      

  3. 一旦创ZsparkContextQ就可以用它来创建RDD。比如调用sc.textFile()来创Z个代表文本中各行文本的RDD。(比如vallinesRDD = sc.textFile(“yangsy.text”),val spark = linesRDD.filter(line=>line.contains(“spark”),spark.count()Q?/span>

      执行q些操作Q驱动器E序一般要理多个执行?是我们所说的executor节点?/span>

  4. 在初始化SparkContext的同Ӟ加蝲sparkConf对象来加载集的配置Q从而创建sparkContext对象?/span>

      从源码中可以看到Q在启动thriftserverӞ调用了spark- daemon.sh文gQ该文g源码如左图,加蝲spark_home下的conf中的文g?/span>

      

      Q在执行后台代码Ӟ需要首先创建conf对象Q加载相应参敎ͼ val sparkConf = newSparkConf().setMaster("local").setAppName("cocapp").set("spark.executor.memory","1g"), val sc: SparkContext = new SparkContext(sparkConf))

  RDD工作原理Q?/strong>

  RDD(Resilient DistributedDatasets)[1] ,Ҏ分布式数据集,是分布式内存的一个抽象概念,RDD提供了一U高度受限的׃n内存模型Q即RDD是只ȝ记录分区的集合,只能通过在其他RDD执行定的{换操作(如map、join和group byQ而创建,然而这些限制得实现容错的开销很低。对开发者而言QRDD可以看作是Spark的一个对象,它本w运行于内存中,如读文g是一个RDDQ对文g计算是一个RDDQ结果集也是一个RDD Q不同的分片、数据之间的依赖、key-valuecd的map数据都可以看做RDD?/p>

  主要分ؓ三部分:创徏RDD对象QDAG调度器创建执行计划,Task调度器分配Q务ƈ调度Worker开始运行?/p>

  SparkContext(RDD相关操作)→通过(提交作业)→(遍历RDD拆分stage→生成作业)DAGScheduler→通过Q提交Q务集Q?#8594;d调度理(TaskScheduler)→通过Q按照资源获取Q?→d调度理(TaskSetManager)

  Transformationq回D是一个RDD。它使用了链式调用的设计模式Q对一个RDDq行计算后,变换成另外一个RDDQ然后这个RDD又可以进行另外一ơ{换。这个过E是分布式的?/p>

  Actionq回g是一个RDD。它要么是一个Scala的普通集合,要么是一个|要么是空Q最l或q回到DriverE序Q或把RDD写入到文件系l中

  转换(Transformations)(如:map, filter, groupBy, join{?QTransformations操作是Lazy的,也就是说从一个RDD转换生成另一个RDD的操作不是马上执行,Spark在遇到Transformations操作时只会记录需要这L操作Qƈ不会L行,需要等到有Actions操作的时候才会真正启动计过E进行计?/p>

  操作(Actions)(如:count, collect, save{?QActions操作会返回结果或把RDD数据写到存储pȝ中。Actions是触发Spark启动计算的动因?/p>

  它们本质区别是:Transformationq回D是一个RDD。它使用了链式调用的设计模式Q对一个RDDq行计算后,变换成另外一个RDDQ然后这个RDD又可以进行另外一ơ{换。这个过E是分布式的。Actionq回g是一个RDD。它要么是一个Scala的普通集合,要么是一个|要么是空Q最l或q回到DriverE序Q或把RDD写入到文件系l中。关于这两个动作Q在Spark开发指南中会有p一步的详细介绍Q它们是ZSpark开发的核心?/p>

  RDD基础

  1. Spark中的RDD是一个不可变的分布式对象集合。每个RDD都被分ؓ多个分区Q这些分行在集群的不同节点上。创建RDD的方法有两种Q一U是d一个外部数据集Q一U是在群东程序里分发驱动器程序中的对象集合,不如刚才的示例,d文本文g作ؓ一个字W串的RDD的示例?/span>

  2. 创徏出来后,RDD支持两种cd的操?转化操作和行动操?/span>

      转化操作会由一个RDD生成一个新的RDD。(比如刚才的根据谓词筛选)

      行动操作会对RDD计算Z个结果,q把l果q回到驱动器E序中,或把l果存储到外部存储系l(比如HDFSQ中。比如first()操作是一个行动操作,会返回RDD的第一个元素?/span>

      注:转化操作与行动操作的区别在于Spark计算RDD的方式不同。虽然你可以在Q何时候定义一个新的RDDQ但Spark只会惰性计这些RDD。它们只有第一个在一个行动操作中用到Ӟ才会真正的计。之所以这栯计,是因为比如刚才调用sc.textFile(...)时就把文件中的所有行都读取ƈ存储hQ就会消耗很多存储空_而我们马上又要筛选掉其中的很多数据?/span>

      q里q需要注意的一ҎQspark会在你每ơ对它们q行行动操作旉新计。如果想在多个行动操作中重用同一个RDDQ那么可以用RDD.persist()或RDD.collect()让Spark把这个RDD~存下来。(可以是内存,也可以是盘)

  3. Spark会用谱pd来记录这些不同RDD之间的依赖关p,Spark需要用q些信息来按需计算每个RDDQ也可以依靠q囑֜持久化的RDD丢失部分数据时用来恢复所丢失的数据?如下图,qoerrorsRDD与warningsRDD,最l调用union()函数)

      

  RDD计算方式

  

  RDD的宽H依?/strong>

  

  H依?(narrowdependencies) 和宽依赖 (widedependencies) 。窄依赖是指 ?RDD 的每个分区都只被?RDD 的一个分区所使用 。相应的Q那么宽依赖是指父 RDD 的分多个?RDD 的分区所依赖。例如, map 是一U窄依赖Q?join 则会D宽依?/p>

  q种划分有两个用处。首先,H依赖支持在一个结点上道化执行。例如基于一对一的关p,可以?filter 之后执行 map 。其ơ,H依赖支持更高效的故障还原。因为对于窄依赖Q只有丢q?RDD 的分区需要重新计。而对于宽依赖Q一个结点的故障可能D来自所有父 RDD 的分Z失,因此需要完全重新执行。因此对于宽依赖QSpark 会在持有各个父分区的l点上,中间数据持久化来简化故障还原,像 MapReduce 会持久化 map 的输Z栗?/p>

  SparkExample

  

  步骤 1 Q创?RDD ?/strong>上面的例子除L后一?collect 是个动作Q不会创?RDD 之外Q前面四个{换都会创建出新的 RDD 。因此第一步就是创建好所?RDD( 内部的五信?) ?/p>

  步骤 2 Q创建执行计划?/strong>Spark 会尽可能地管道化QƈZ是否要重新组l数据来划分 阶段 (stage) Q例如本例中?groupBy() 转换׃整个执行计划划分成两阶D|行。最l会产生一?DAG(directedacyclic graph Q有向无环图 ) 作ؓ逻辑执行计划?/p>

  步骤 3 Q调度Q务?nbsp;各阶段划分成不同的 d (task) Q每个Q务都是数据和计算的合体。在q行下一阶段前,当前阶段的所有Q务都要执行完成。因Z一阶段的第一个{换一定是重新l织数据的,所以必ȝ当前阶段所有结果数据都计算出来了才能l?/p>

  假设本例中的 hdfs://names 下有四个文g块,那么 HadoopRDD ?partitions ׃有四个分区对应这四个块数据,同时 preferedLocations 会指明这四个块的最佳位|。现在,可以创建出四个dQƈ调度到合适的集群l点上?/p>

  Spark数据分区

  1. Spark的特性是Ҏ据集在节炚w的分行控制。在分布式系l中Q通讯的代h巨大的,控制数据分布以获得最的|络传输可以极大地提升整体性能。SparkE序可以通过控制RDD分区方式来减通讯的开销?/span>

  2. Spark中所有的键值对RDD都可以进行分区。确保同一l的键出现在同一个节点上。比如,使用哈希分区一个RDD分成?00个分区,此时键的哈希值对100取模的结果相同的记录会被攑֜一个节点上?/span>

      Q可使用partitionBy(newHashPartitioner(100)).persist()来构?00个分?

  3. Spark中的许多操作都引入了数据根据键跨界点进行؜z的q程?比如Qjoin(),leftOuterJoin(),groupByKey(),reducebyKey(){?对于像reduceByKey()q样只作用于单个RDD的操作,q行在未分区的RDD上的时候会D每个键的所有对应值都在每台机器上q行本地计算?/span>

  SparkSQL的shuffleq程

  

  Spark SQL的核心是把已有的RDDQ带上Schema信息Q然后注册成cMsql里的”Table”Q对其进行sql查询。这里面主要分两部分Q一是生成SchemaRDQ二是执行查询?/p>

  如果是spark-hive目Q那么读取metadata信息作ؓSchema、读取hdfs上数据的q程交给Hive完成Q然后根据这俩部分生成SchemaRDDQ在HiveContext下进行hql()查询?/p>

  SparkSQLl构化数?/span>

  1. 首先说一下ApacheHiveQHive可以在HDFS内或者在其他存储pȝ上存储多U格式的表。SparkSQL可以dHive支持的Q何表。要把Spark SQLq接已有的hive上,需要提供Hive的配|文件。hive-site.xml文g复制到spark的conf文g夹下。再创徏出HiveContext对象(sparksql的入?Q然后就可以使用HQL来对表进行查询,q以p的RDD的Ş式拿到返回的数据?/span>

  2. 创徏Hivecontextq查询数?/span>

      importorg.apache.spark.sql.hive.HiveContext

      valhiveCtx = new org.apache.spark.sql.hive.HiveContext(sc)

      valrows = hiveCtx.sql(“SELECT name,age FROM users”)

      valfitstRow – rows.first()

      println(fitstRow.getSgtring(0)) //字段0是name字段

  3. 通过jdbcq接外部数据源更C加蝲

      Class.forName("com.mysql.jdbc.Driver")

      val conn =DriverManager.getConnection(mySQLUrl)

      val stat1 =conn.createStatement()

      stat1.execute("UPDATE CI_LABEL_INFO set DATA_STATUS_ID = 2 , DATA_DATE ='" + dataDate +"' where LABEL_ID in ("+allCreatedLabels.mkString(",")+")")

      stat1.close()

      //加蝲外部数据源数据到内存

      valDIM_COC_INDEX_MODEL_TABLE_CONF =sqlContext.jdbc(mySQLUrl,"DIM_COC_INDEX_MODEL_TABLE_CONF").cache()

      val targets =DIM_COC_INDEX_MODEL_TABLE_CONF.filter("TABLE_DATA_CYCLE ="+TABLE_DATA_CYCLE).collect

  SparkSQL解析

  

  首先说下传统数据库的解析Q传l数据库的解析过E是按Rusult、Data Source、Operation的次序来解析的。传l数据库先将d的SQL语句q行解析Q分辨出SQL语句中哪些词是关键字Q如select,from,where)Q哪些是表达式,哪些是ProjectionQ哪些是Data Source{等。进一步判断SQL语句是否规范Q不规范报错,规范则按照下一步过E绑定(Bind)。过E绑定是SQL语句和数据库的数据字???视图{)q行l定Q如果相关的Projection、Data Source{都存在Q就表示q个SQL语句是可以执行的。在执行q程中,有时候甚至不需要读取物理表可以返回结果,比如重新q行刚运行过的SQL语句Q直接从数据库的~冲池中获取q回l果。在数据库解析的q程中SQL语句Ӟ会把SQL语句转化成一个树形结构来q行处理Q会形成一个或含有多个节点(TreeNode)的Tree,然后再后l的处理政对该Treeq行一pd的操作?/span>

  Spark SQL对SQL语句的处理和关系数据库对SQL语句的解析采用了cM的方法,首先会将SQL语句q行解析Q然后Ş成一个TreeQ后l如l定、优化等处理q程都是对Tree的操作,而操作方法是采用Rule,通过模式匚wQ对不同cd的节炚w用不同的操作。SparkSQL有两个分支,sqlContext和hiveContext。sqlContext现在只支持SQL语法解析器(Catalyst)QhiveContext支持SQL语法和HiveContext语法解析器?br />
原文地址Q?span style="font-family: verdana, "courier new"; line-height: 21px;">http://mt.sohu.com/20160522/n450849016.shtml



]]>
转:spark通过合理讄spark.default.parallelism参数提高执行效率http://www.tkk7.com/cnfree/archive/2016/09/08/431773.html三h行,必有我师?/dc:creator>三h行,必有我师?/author>Thu, 08 Sep 2016 05:07:00 GMThttp://www.tkk7.com/cnfree/archive/2016/09/08/431773.htmlhttp://www.tkk7.com/cnfree/comments/431773.htmlhttp://www.tkk7.com/cnfree/archive/2016/09/08/431773.html#Feedback0http://www.tkk7.com/cnfree/comments/commentRss/431773.htmlhttp://www.tkk7.com/cnfree/services/trackbacks/431773.htmlspark中有partition的概念(和slice是同一个概念,在spark1.2中官|已l做Z说明Q,一般每个partition对应一个task。在我的试q程中,如果没有讄spark.default.parallelism参数Qspark计算出来的partition非常巨大Q与我的cores非常不搭。我在两台机器上Q?cores *2 +6g * 2Q上Qspark计算出来的partition辑ֈ2.8万个Q也是2.9万个tasksQ每个task完成旉都是几毫U或者零点几毫秒Q执行v来非常缓慢。在我尝试设|了 spark.default.parallelism 后,d数减到10Q执行一ơ计过E从minute降到20second?/p>

参数可以通过spark_home/conf/spark-default.conf配置文g讄?/p>

eg.

spark.master  spark://master:7077 

spark.default.parallelism  10 

spark.driver.memory  2g 

spark.serializer  org.apache.spark.serializer.KryoSerializer 

spark.sql.shuffle.partitions  50

 

下面是官|的相关描述Q?/p>

from:http://spark.apache.org/docs/latest/configuration.html

Property NameDefaultMeaning
spark.default.parallelism For distributed shuffle operations like reduceByKey and join, the largest number of partitions in a parent RDD. For operations likeparallelize with no parent RDDs, it depends on the cluster manager:
  • Local mode: number of cores on the local machine
  • Mesos fine grained mode: 8
  • Others: total number of cores on all executor nodes or 2, whichever is larger
Default number of partitions in RDDs returned by transformations like joinreduceByKey, and parallelize when not set by user.

from:http://spark.apache.org/docs/latest/tuning.html

Level of Parallelism

Clusters will not be fully utilized unless you set the level of parallelism for each operation high enough. Spark automatically sets the number of “map” tasks to run on each file according to its size (though you can control it through optional parameters to SparkContext.textFile, etc), and for distributed “reduce” operations, such as groupByKey and reduceByKey, it uses the largest parent RDD’s number of partitions. You can pass the level of parallelism as a second argument (see the spark.PairRDDFunctions documentation), or set the config propertyspark.default.parallelism to change the default. In general, we recommend 2-3 tasks per CPU core in your cluster.


原文地址Q?span style="font-family: verdana, "courier new"; font-size: 14px; line-height: 21px;">http://www.cnblogs.com/wrencai/p/4231966.html



]]>
Java反编译工?Eclipse Class Decompiler 2.10 已发布,支持多种反编译器http://www.tkk7.com/cnfree/archive/2016/05/13/430485.html三h行,必有我师?/dc:creator>三h行,必有我师?/author>Fri, 13 May 2016 06:23:00 GMThttp://www.tkk7.com/cnfree/archive/2016/05/13/430485.htmlhttp://www.tkk7.com/cnfree/comments/430485.htmlhttp://www.tkk7.com/cnfree/archive/2016/05/13/430485.html#Feedback5http://www.tkk7.com/cnfree/comments/commentRss/430485.htmlhttp://www.tkk7.com/cnfree/services/trackbacks/430485.html整合了多U反~译器,和Eclipse Class Viewer无缝集成Q能够很方便的用插件查看类库源码,q行Debug调试?br />同时q提供了在线自动查找源代码,查看Class二进制字节码的功能?/strong> 

Eclipse Class Decompiler对JDK的最低要求ؓJDK1.6, 能反~译和debug各版本的Class文gQ支持JDK8的Lambda语法Q同时支持中文等非Ascii码字W集的解析,支持Eclipse 3.6及以上所有版本的Eclipse?br />
本插件支持WindowsQLinuxQMacosx 32位及64位操作系l?/strong>

Github目地址为:https://github.com/cnfree/Eclipse-Class-Decompiler

请通过以下地址选择一个可用的源在U安装:

http://cnfree.github.io/Eclipse-Class-Decompiler/update
http://raw.githubusercontent.com/cnfree/eclipse/master/decompiler/update/
http://www.cpupk.com/decompiler/update/

ȝ包下载地址Q?br /> 
插g使用说明Q?br />
下图为Eclipse Class Decompiler的首选项面Q可以选择~省的反~译器工Pq进行反~译器的基本讄。缺省的反编译工具ؓJD-CoreQJD-Core更ؓ先进一些,支持泛型、Enum、注解等JDK1.5以后才有的新语法?br />
首选项配置选项Q?br />1.重用~存代码Q只会反~译一ơ,以后每次打开该类文gQ都昄的是~存的反~译代码?br />2.忽略已存在的源代码:若未选中Q则查看Class文g是否已绑定了Java源代码,如果已绑定,则显CJava源代码,如果未绑定,则反~译Class文g。若选中此项Q则忽略已绑定的Java源代码,昄反编译结果?br />3.昄反编译器报告Q显C反~译器反~译后生成的数据报告及异怿息?br />4.使用Eclipse代码格式化工P使用Eclipse格式化工具对反编译结果重新格式化排版Q反~译整个Jar包时Q此操作会消耗一些时间?br />5.使用Eclipse成员排序Q用Eclipse成员排序对反~译l果重新格式化排版,反编译整个Jar包时Q此操作会消耗大量时间?br />6.以注释方式输出原始行号信息:如果Class文g包含原始行号信息Q则会将行号信息以注释的方式打印到反~译l果中?br />7.Ҏ行号寚w源代码以便于调试Q若选中该项Q插件会采用AST工具分析反编译结果,q根据行号信息调整代码顺序,以便于Debugq程中的单步跟踪调试?br />8.讄cd~译查看器作为缺省的cL件编辑器Q默认ؓ选中Q将忽略Eclipse自带的Class ViewerQ每ơEclipse启动后,默认使用本插件提供的cL看器打开Class文g?br />


插g提供了系l菜单,工具栏,当打开了插件提供的cd~译查看器后Q会Ȁz菜单和工具栏选项Q可以方便的q行首选项配置Q切换反~译工具重新反编译,以及导出反编译结果?br />





cd~译查看器右键菜单包含了Eclipse自带cL看器右键菜单的全部选项Qƈ增加了一?#8220;导出反编译源代码”菜单V?/div>


打开目路径下的Class文gQ如果设|类反编译查看器为缺省的查看器,直接双击Class文g卛_Q如果没有设|ؓ~省查看器,可以使用右键菜单q行查看?br />



同时插g也支持直接将外部的Class文g拖拽到Eclipse~辑器中q行反编译?br />

Eclipse Class Decompiler插g也提供了反编译整个Jar文g或者Java包的反编译。该操作支持Package Explorer对包昄布局的操作,如果是^铺模式布局Q则导出的源代码不包含子包,如果是层U模式布局Q则导出选中的包及其所有的子包?br />



Debug调试Q可以在首选项选中寚w行号q行单步跟踪调试Q和普通的包含源代码时的调试操作完全一_同样的也可以讄断点q行跟踪。当透视图ؓDebugӞ插g自动生成行号q进行对齐方便调试代码,无需q行M讄?/div>

博文地址Q?a href="http://www.tkk7.com/cnfree/archive/2012/10/30/390457.html">http://www.tkk7.com/cnfree/archive/2012/10/30/390457.html

]]>Java应用定制工厂使用手册Q一Q?/title><link>http://www.tkk7.com/cnfree/archive/2013/03/03/395999.html</link><dc:creator>三h行,必有我师?/dc:creator><author>三h行,必有我师?/author><pubDate>Sun, 03 Mar 2013 09:25:00 GMT</pubDate><guid>http://www.tkk7.com/cnfree/archive/2013/03/03/395999.html</guid><wfw:comment>http://www.tkk7.com/cnfree/comments/395999.html</wfw:comment><comments>http://www.tkk7.com/cnfree/archive/2013/03/03/395999.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.tkk7.com/cnfree/comments/commentRss/395999.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/cnfree/services/trackbacks/395999.html</trackback:ping><description><![CDATA[<span style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 16px; background-color: #ffffff;">Java应用定制工厂Q以下简UCؓJCBQJava Customization BuilderQ是一个针对Java轻量U桌面应用进行精优化的小工具Q用它可以_你的jar包,q自动生成一个精的JREQ也可以使用它生成一个Exe启动引导E序Qƈ且能够对你的Java应用自动做Pack200和Unpack200处理。用本工具定制的Java桌面应用通常不会过10MQ包含JREQ,SWT客户端程序相对于Swing客户端程序更,一般不会超q?M?br /> <br /> </span>JCB是一个Java应用Q所以目标机器上必须安装1.5以上版本的JDK用以启动JCBQ但是JCB可以用来_1.4版的JREQƈ且JRE1.4_后的体积q小?.5以上的版本?br /> <br /> 1.新徏JCB目<br /> _JRE的步骤比较繁琐,有可能精p|Qؓ了不重复之前的步骤,JCB提供一个项目文件用来保存精配置信息Q扩展名为jcprj。这里我们创Z个项目,名ؓJCB<br /> <br /> <div style="text-align: left;"><img src="http://www.tkk7.com/images/blogjava_net/cnfree/create_jcb.png" width="516" height="341" alt="" /></div> <br /> Wizard需要输入一个工E名和指定工E位|,至于下面的应用程序位|和定制JRE位置由JCB自动指定Q这儿显C出来仅供参考?br /> <br /> <span style="color: #ff0000;">此时最好Ctrl+S保存一下项目,否则退出后你之前的配置信息会全部丢失,因ؓ你ƈ没有制定一个可用的目配置文g?/span><br /> <br /> 2. 配置JCB目<br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/jcb_setting.png" width="850" height="615" alt="" /><br /> <br /> 首先指定目需要的jar文gQ然后依ơ选择目的main classQ启动\径默认ؓI,一般来说无需指定。然后设定应用程序参数和虚拟机参数。最后选定需要精的JREQJCB当前支持1.4-1.7版本的JREQ未来可能会支持更高版本的JRE?br /> <br /> 右下角有2个单选按钮:全部重新q行和增量运行。全部重新运行就会放弃之前的q行l果Q增量运行就是会保留以前的运行结果?br /> <br /> 然后点击“以Verbose模式q行”按钮。Verbose模式q行JavaE序Q会昄JVM加蝲的全部类信息QJCB需要这些类信息q行JRE的精Q所以请可能的把应用所有的功能可能的跑一遍,跑的全面,D_出错的可能性就低?br /> <br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/jcb_verbose.png" width="850" height="615" alt="" /><br /> <br /> Verboseq行l果Q这个页面的昄信息仅供参考,无实际用处?br /> <br /> 3. 分析目的类依赖?br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/jcb_analyze.png" width="850" height="615" alt="" /><br /> <br /> 分析cM赖模式有2个选项Q重新完全分析和增量分析。完全分析会p较多的时间。当使用verbose模式增量q行后,可以使用增量模式分析cM赖项Q这样可以节U大量的旉。类依赖分析会反~译所有运行的c,分析cd用关p,但是无法获取Class.forNameq类动态类加蝲信息Q所以需要Verbose模式q行的尽量全面,以避免这些动态加载的cȝ~失?br /> <br /> Z么需要分析类依赖关系呢?因ؓ不同的操作系l,不同的硬仉|,JRE可能会采取策略模式加载不同的c,或者一些异常,Verbose模式一般不会加载,q样换个g环境Q仅仅用Verbose模式的类可能会导致ClassNotFoundq样的异常,DJavaE序崩溃?br /> <br /> <br /> 4. _JRE<br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/jcb_slim.png" width="850" height="615" alt="" /><br /> <br /> _JRE有两U模式:使用Verboseq行l果和用类依赖分析l果。前者只包含Verbose分析出来的类Q精出来的JRE包很,但是基本不具备跨q_性。所以一般来说推荐选择后者?br /> <br /> 如果你的E序包含Swing的客LQƈ且比较复杂的话,最好选中包含Swing选项。因为Swing的设计完全是动态化的加载,全部使用Class.forName方式Q类依赖分析对Swing是无效的。当焉中该选项后,JRE的体U会增加许多。比较好的解x案,是用SWT替代Swingq行开发,或者尽量把你的E序跑全面,包括各种异常界面都跑出来?br /> <br /> 右下角有两个按钮Q是用来自定义类和资源文件的Q比如移除JAR包的MD5文g或者无用的文g。或者测试运行发现ClassNotFound异常Q手动把~少的类加进去,然后JCB会自动运行增量类依赖分析加蝲所有可能需要的cR?br /> <br /> 选择左上角的“_Jar?#8221;按钮Q就可以对JREq行_了,_完毕后可以点?#8220;查看_l果”按钮q行查看?br /> <br /> 5.定制JRE<br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/jre_slim.png" width="850" height="615" alt="" /><br /> <br /> 上图昄了JRE_l果QJCB会自动分析所有的ClassQ生成精版JREQ包括需要的JARQDLL和资源文件。一般来说精出来的JREQ普通功能都能正完成,但是不排除有些功能不能正怋用,比如~少某个资源文g或者DLLQ需要手工添加?br /> <br /> Z保证_的正性,你需要进行运行测试,q一步是必须的,而且最好和Verboseq行模式一P把所有的功能都跑一遍,认_无误?br /> <br /> <img src="http://www.tkk7.com/images/blogjava_net/cnfree/jre_test.png" border="0" alt="" width="850" height="615" /><br /> <br /> 如果试q行有误的话Q请Ҏq行错误报告q行分析Q如果缺类Q请使用Verbose模式重新q行相应的功能,或者在步骤四手工添加需要的c,然后重新生成依赖的JRE。如果缺相关的DLL或者资源文Ӟ也请手工dQƈ且取消步骤四?#8220;清理工作区选项”Q否则每ơ精JRE都需要重新手工添加?br /> <br /> <span style="color: #ff0000;">到此为止Q精JRE部分q全部完成了,你最好用Ctrl+S保存一下结果,以避免下ơ重做项目?/span><br /><br /><strong>JCB目下蝲地址Q?a >http://www.sourceforge.net/projects/jcb</a></strong><img src ="http://www.tkk7.com/cnfree/aggbug/395999.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/cnfree/" target="_blank">三h行,必有我师?/a> 2013-03-03 17:25 <a href="http://www.tkk7.com/cnfree/archive/2013/03/03/395999.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>~程珠玑W二?/title><link>http://www.tkk7.com/cnfree/archive/2012/11/24/391908.html</link><dc:creator>三h行,必有我师?/dc:creator><author>三h行,必有我师?/author><pubDate>Sat, 24 Nov 2012 14:21:00 GMT</pubDate><guid>http://www.tkk7.com/cnfree/archive/2012/11/24/391908.html</guid><wfw:comment>http://www.tkk7.com/cnfree/comments/391908.html</wfw:comment><comments>http://www.tkk7.com/cnfree/archive/2012/11/24/391908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/cnfree/comments/commentRss/391908.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/cnfree/services/trackbacks/391908.html</trackback:ping><description><![CDATA[1. 40亿个无符h敎ͼ扑և一个不在这40亿个整数中的数。可以换个方向思考, 99个小?00的数Q找Z个不在这99个数中的于100的数?br />首先把这99个数分ؓ10l,按高位ؓ0-9分,然后计算每组的数量,数量最的那个肯定是~失的那个,然后递归……找最的那个Q组合v来的数肯定是~失的。答案是按位q算找,和这个类伹{?br /><br />2. 43亿个无符h敎ͼ扑և一个重复的整数。也是101个小?00的数Q找出重复的那个数来?br />首先把这99个数分ؓ10l,按高位ؓ0-9分,然后计算每组的数量,数量最多的那组Q肯定有重复的,一ơ类推找W二?#8230;…<img src ="http://www.tkk7.com/cnfree/aggbug/391908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/cnfree/" target="_blank">三h行,必有我师?/a> 2012-11-24 22:21 <a href="http://www.tkk7.com/cnfree/archive/2012/11/24/391908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The difference between dependency and associationhttp://www.tkk7.com/cnfree/archive/2012/11/19/391572.html三h行,必有我师?/dc:creator>三h行,必有我师?/author>Mon, 19 Nov 2012 05:16:00 GMThttp://www.tkk7.com/cnfree/archive/2012/11/19/391572.htmlhttp://www.tkk7.com/cnfree/comments/391572.htmlhttp://www.tkk7.com/cnfree/archive/2012/11/19/391572.html#Feedback0http://www.tkk7.com/cnfree/comments/commentRss/391572.htmlhttp://www.tkk7.com/cnfree/services/trackbacks/391572.html
When a object just uses a object, please use the association. 

]]>
研磨设计模式…? http://www.tkk7.com/cnfree/archive/2012/11/14/391282.html三h行,必有我师?/dc:creator>三h行,必有我师?/author>Tue, 13 Nov 2012 16:22:00 GMThttp://www.tkk7.com/cnfree/archive/2012/11/14/391282.htmlhttp://www.tkk7.com/cnfree/comments/391282.htmlhttp://www.tkk7.com/cnfree/archive/2012/11/14/391282.html#Feedback0http://www.tkk7.com/cnfree/comments/commentRss/391282.htmlhttp://www.tkk7.com/cnfree/services/trackbacks/391282.html

comparator 

Decorator Pattern and Adapter Pattern have the same alias name: wrapper. But they face different aspects. Decorator pattern changes the object function, but the adapter pattern changes the interface.

The typical decorator pattern is the java OutputStream, you can use the BufferedOutputStream to wrap it, then get the extra function.
The typical adapter pattern in the BIRT is the ElementAdapter, it can convert any object to an other object.

Decorator pattern must extend the class which you want to wrap, but the adapter class must implements the interface using by the client.


FlyWeight pattern extracts the same part of some different objects, and the part doesn't be changed when these objects changed. String class uses the FlyWeight pattern, jface 
ImageRegistry also uses it. 
FlyWeight can have a interface to get external data, and change the external data's status, but FlyWeight internal status shouldn't be changed.

The Collections.sort() method implementation contains template method design pattern and strategy design pattern, but it doesn't contain the visitor design pattern. The Collections.sort() method uses the merge sort algorithm, you can't change it, but you can change the comparator logic, it's one step of the sort algorithm. So it's a template method pattern, but not a classic implementation, it uses the callback method to implement the pattern, but not extending the parent template class. The comparator class use the strategy design pattern, it not a visitor pattern, visitor pattern have a accept method to operate the element to deal some logic. 





]]>
排序1+4Q归q排序(MergeSortQ和堆排序(HeapSortQ(转)http://www.tkk7.com/cnfree/archive/2012/11/10/391154.html三h行,必有我师?/dc:creator>三h行,必有我师?/author>Sat, 10 Nov 2012 15:18:00 GMThttp://www.tkk7.com/cnfree/archive/2012/11/10/391154.htmlhttp://www.tkk7.com/cnfree/comments/391154.htmlhttp://www.tkk7.com/cnfree/archive/2012/11/10/391154.html#Feedback2http://www.tkk7.com/cnfree/comments/commentRss/391154.htmlhttp://www.tkk7.com/cnfree/services/trackbacks/391154.html1 归ƈ排序QMergeSortQ?/strong>

归ƈ排序最差运行时间是O(nlogn)Q它是利用递归设计E序的典型例子?br />
归ƈ排序的最基础的操作就是合q两个已l排好序的序列?br />
假设我们有一个没有排好序的序列,那么首先我们使用分割的办法将q个序列分割成一个一个已l排好序的子序列。然后再利用归ƈ的方法将一个个的子序列合ƈ成排序好的序列。分割和归ƈ的过E可以看下面的图例?br />


从上囑֏以看出,我们首先把一个未排序的序列从中间分割?部分Q再?部分分成4部分Q依ơ分割下去,直到分割成一个一个的数据Q再把这些数据两两归q到一P使之有序Q不停的归ƈQ最后成Z个排好序的序列?br />
如何把两个已l排序好的子序列归ƈ成一个排好序的序列呢Q可以参看下面的Ҏ?br />
假设我们有两个已l排序好的子序列?br />序列AQ? 23 34 65
序列BQ? 13 14 87
那么可以按照下面的步骤将它们归ƈC个序列中?br />
Q?Q首先设定一个新的数列C[8]?br />Q?QA[0]和B[0]比较QA[0] = 1QB[0] = 2QA[0] < B[0]Q那么C[0] = 1
Q?QA[1]和B[0]比较QA[1] = 23QB[0] = 2QA[1] > B[0]Q那么C[1] = 2
Q?QA[1]和B[1]比较QA[1] = 23QB[1] = 13QA[1] > B[1]Q那么C[2] = 13
Q?QA[1]和B[2]比较QA[1] = 23QB[2] = 14QA[1] > B[2]Q那么C[3] = 14
Q?QA[1]和B[3]比较QA[1] = 23QB[3] = 87QA[1] < B[3]Q那么C[4] = 23
Q?QA[2]和B[3]比较QA[2] = 34QB[3] = 87QA[2] < B[3]Q那么C[5] = 34
Q?QA[3]和B[3]比较QA[3] = 65QB[3] = 87QA[3] < B[3]Q那么C[6] = 65
Q?Q最后将B[3]复制到C中,那么C[7] = 87。归q完成?br />
如果我们清楚了上面的分割和归q过E,那么我们可以用递归的方法得到归q算法的实现?/p>
    public class MergeSorter
    {
        
private static int[] myArray;
        
private static int arraySize;

        
public static void Sort( int[] a )
        {
            myArray 
= a;
            arraySize 
= myArray.Length;
            MergeSort();
        }

        
/// <summary>
        
/// 利用归ƈ的方法排序数l,首先序列分?br />        /// 然后数列归qӞq个法需要双倍的存储I间
        
/// 旉是O(nlgn)
        
/// </summary>
        private static void MergeSort()
        {
            
int[] temp = new int[arraySize];
            MSort( temp, 
0, arraySize - 1);
        }

        
private static void MSort(int[] temp, int left, int right)
        {
            
int mid;

            
if (right > left)
            {
                mid 
= (right + left) / 2;
                MSort( temp, left, mid); 
//分割左边的序?/span>
                MSort(temp, mid+1, right);//分割双的序?/span>
                Merge(temp, left, mid+1, right);//归ƈ序列
            }
        }

        
private static void Merge( int[] temp, int left, int mid, int right)
        {
            
int i, left_end, num_elements, tmp_pos;

            left_end 
= mid - 1;
            tmp_pos 
= left;
            num_elements 
= right - left + 1;

            
while ((left <= left_end) && (mid <= right)) 
            {
                
if (myArray[left] <= myArray[mid]) //左端序列归q到temp数组?/span>
                {
                    temp[tmp_pos] 
= myArray[left];
                    tmp_pos 
= tmp_pos + 1;
                    left 
= left +1;
                }
                
else//右端序列归q到temp数组?/span>
                {
                    temp[tmp_pos] 
= myArray[mid];
                    tmp_pos 
= tmp_pos + 1;
                    mid 
= mid + 1;
                }
            }

            
while (left <= left_end) //拯左边剩余的数据到temp数组?/span>
            {
                temp[tmp_pos] 
= myArray[left];
                left 
= left + 1;
                tmp_pos 
= tmp_pos + 1;
            }
            
while (mid <= right) //拯双剩余的数据到temp数组?/span>
            {
                temp[tmp_pos] 
= myArray[mid];
                mid 
= mid + 1;
                tmp_pos 
= tmp_pos + 1;
            }

            
for (i=0; i < num_elements; i++//所有元素拷贝到原始数组?/span>
            {
                myArray[right] 
= temp[right];
                right 
= right - 1;
            }
        }
    }


归ƈ排序法是一UO(nlogn)的算法。它的最差,q_Q最好时间都是O(nlogn)。但是它需要额外的存储I间Q这在某些内存紧张的机器上会受到限制?br />
归ƈ法是又分割和归q两部分l成的。对于分割部分,如果我们使用二分查找的话Q时间是O(logn)Q在最后归q的时候,旉是O(n)Q所以ȝ旉是O(nlogn)?br />
2 堆排序(HeapSortQ?/strong>

堆排序属于百万俱乐部的成员。它特别适合大数据量(百万条记录以上)的排序。因为它q不使用递归Q因大数据量的递归可能会导致堆栈溢出)Q而且它的旉也是O(nlogn)。还有它q不需要大量的额外存储I间?br />
堆排序的思\?

(1)原始未排序的数据徏成一个堆?br />(2)建成堆以后,最大值在堆顶Q也是W?个元素,q时候将W零个元素和最后一个元素交换?br />(3)q时候将?到倒数W二个元素的所有数据当成一个新的序列,Z个新的堆Q再ơ交换第一个和最后一个元素,依次cLQ就可以所有元素排序完毕?br />
建立堆的q程如下面的图所C?


堆排序的具体法如下Q?/p>

public class HeapSorter 
    {
        
private static int[] myArray;
        
private static int arraySize;

        
public static void Sort( int[] a )
        {
            myArray 
= a;
            arraySize 
= myArray.Length;
            HeapSort();
        }

        
private static void HeapSort()
        {
            BuildHeap();            
//原始序列徏成一个堆

            
while ( arraySize > 1 )
            {
                arraySize
--;
                Exchange ( 
0, arraySize );//最大值放在数l的最?/span>
                DownHeap ( 0 );  //序列从0到n-1看成一个新的序列,重新建立?/span>
            } 
        }

        
private static void BuildHeap()
        {
            
for (int v=arraySize/2-1; v>=0; v--)
                DownHeap ( v );
        }

        
//利用向下遍历子节点徏立堆
        private static void DownHeap( int v )
        {
            
int w = 2 * v + 1;                     // 节点w是节点v的第一个子节点

            
while (w < arraySize)
            {
                
if ( w+1 < arraySize )        // 如果节点v下面有第二个字节?/span>
                    if ( myArray[w+1> myArray[w] ) 
                        w
++;                        // 子节点w讄成节点v下面值最大的子节?br />
                 
// 节点v已经大于子节点wQ有了堆的性质Q那么返?/span>
                if ( myArray[v] >= myArray[w] ) 
                    
return;   
                
                Exchange( v, w );     
// 如果不是Q就交换节点v和节点w的?/span>
                v = w;        
                w 
= 2 * v + 1;            // l箋向下扑֭节点
            }
        }

        
//交换数据
        private static void Exchange( int i, int j )
        {
            
int t = myArray[i];
            myArray[i] 
= myArray[j];
            myArray[j] 
= t;
        }
    }    


 

堆排序主要用于超大规模的数据的排序。因为它不需要额外的存储I间Q也不需要大量的递归?/span>

3 几种O(nlogn)法的初步比?/span>

我们可以从下表看到几UO(nlogn)法的效率的区别。所有的数据都?Net的RandomcM生,每种法q行100ơ,旉的单位ؓ毫秒?/span>


500随机整数5000随机整数20000随机整数
合ƈ排序0.31251.56257.03125
 Shell排序0.31251.256.875
堆排?/td>0.468752.18756.71875
快速排?/td>0.156250.6252.8125

从上表可以明昑֜看出Q快速排序是最快的法。这也就l了我们一个结论,对于一般的应用来说Q我们L选择快速排序作为我们的排序法Q当数据量非常大Q百万数量Q我们可以用堆排序Q如果内存空间非常紧张,我们可以使用Shell排序。但是这意味着我们不得不损失速度?nbsp;

/******************************************************************************************
 *【Author】:flyingbread
 *【Date】:2007q???/span>
 *【Notice】:
 *1、本文ؓ原创技术文章,首发博客园个人站?http://flyingbread.cnblogs.com/)Q{载和引用h明作者及出处?/span>
 *2、本文必d文{载和引用QQ何组l和个h未授权不能修改Q何内容,q且未授权不可用于商业?/span>
 *3、本声明为文章一部分Q{载和引用必须包括在原文中?/span>
 ******************************************************************************************/

]]>
վ֩ģ壺 ŷ| ɫҹƵ˵| Ʒ10000| һƷ| AѾƷƵ| aɻ߹ۿ| ֳִˬֳƵ | ŮѾƷëƬ| ߹ۿëƬ| ɫ͵͵ͼۺ| Ʒ| վɫƬѸ| ޹˾Ʒ91þþ| պƷר| ޾Ʒ| þһѲ | ŷղ߹ۿ| ߹ۿƵվ| ɫĻ߹ۿ| ѾþþƷþþ| vƬ߹ۿ| ĻþþƷˮ| žƷƵվ| ޹һӰ| Ѹ߲| þ޾Ʒվ| ҳ˿| žŮվ| Ůɫһ| ޹Ʒ| 91ƬýѰӣ| avר| ޾Ʒ99߹ۿ| þĻƵ| ޾Ʒavˮ| 3Dһ| ۺ| ޹Ʒ˾þ | avպavվ | ˳ɵӰ| ˮƵwww|