*:first-child {
margin-top: 0 !important; }
body > *:last-child {
margin-bottom: 0 !important; }

a {
color: #4183C4; }
a.absent {
color: #cc0000; }
a.anchor {
display: block;
padding-left: 30px;
margin-left: -30px;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
bottom: 0; }

h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
cursor: text;
position: relative; }

h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA09pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoMTMuMCAyMDEyMDMwNS5tLjQxNSAyMDEyLzAzLzA1OjIxOjAwOjAwKSAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUM2NjlDQjI4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUM2NjlDQjM4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QzY2OUNCMDg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5QzY2OUNCMTg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsQhXeAAAABfSURBVHjaYvz//z8DJYCRUgMYQAbAMBQIAvEqkBQWXI6sHqwHiwG70TTBxGaiWwjCTGgOUgJiF1J8wMRAIUA34B4Q76HUBelAfJYSA0CuMIEaRP8wGIkGMA54bgQIMACAmkXJi0hKJQAAAABJRU5ErkJggg==) no-repeat 10px center;
text-decoration: none; }

h1 tt, h1 code {
font-size: inherit; }

h2 tt, h2 code {
font-size: inherit; }

h3 tt, h3 code {
font-size: inherit; }

h4 tt, h4 code {
font-size: inherit; }

h5 tt, h5 code {
font-size: inherit; }

h6 tt, h6 code {
font-size: inherit; }

h1 {
font-size: 28px;
color: black; }

h2 {
font-size: 24px;
border-bottom: 1px solid #cccccc;
color: black; }

h3 {
font-size: 18px; }

h4 {
font-size: 16px; }

h5 {
font-size: 14px; }

h6 {
color: #777777;
font-size: 14px; }

p, blockquote, ul, ol, dl, li, table, pre {
margin: 15px 0; }

hr {
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;
border: 0 none;
color: #cccccc;
height: 4px;
padding: 0;
}

body > h2:first-child {
margin-top: 0;
padding-top: 0; }
body > h1:first-child {
margin-top: 0;
padding-top: 0; }
body > h1:first-child + h2 {
margin-top: 0;
padding-top: 0; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
margin-top: 0;
padding-top: 0; }

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0; }

h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
margin-top: 0; }

li p.first {
display: inline-block; }
li {
margin: 0; }
ul, ol {
padding-left: 30px; }

ul :first-child, ol :first-child {
margin-top: 0; }

dl {
padding: 0; }
dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px; }
dl dt:first-child {
padding: 0; }
dl dt > :first-child {
margin-top: 0; }
dl dt > :last-child {
margin-bottom: 0; }
dl dd {
margin: 0 0 15px;
padding: 0 15px; }
dl dd > :first-child {
margin-top: 0; }
dl dd > :last-child {
margin-bottom: 0; }

blockquote {
border-left: 4px solid #dddddd;
padding: 0 15px;
color: #777777; }
blockquote > :first-child {
margin-top: 0; }
blockquote > :last-child {
margin-bottom: 0; }

table {
padding: 0;border-collapse: collapse; }
table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
table tr:nth-child(2n) {
background-color: #f8f8f8; }
table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }
table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }
table tr th :first-child, table tr td :first-child {
margin-top: 0; }
table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }

img {
max-width: 100%; }

span.frame {
display: block;
overflow: hidden; }
span.frame > span {
border: 1px solid #dddddd;
display: block;
float: left;
overflow: hidden;
margin: 13px 0 0;
padding: 7px;
width: auto; }
span.frame span img {
display: block;
float: left; }
span.frame span span {
clear: both;
color: #333333;
display: block;
padding: 5px 0 0; }
span.align-center {
display: block;
overflow: hidden;
clear: both; }
span.align-center > span {
display: block;
overflow: hidden;
margin: 13px auto 0;
text-align: center; }
span.align-center span img {
margin: 0 auto;
text-align: center; }
span.align-right {
display: block;
overflow: hidden;
clear: both; }
span.align-right > span {
display: block;
overflow: hidden;
margin: 13px 0 0;
text-align: right; }
span.align-right span img {
margin: 0;
text-align: right; }
span.float-left {
display: block;
margin-right: 13px;
overflow: hidden;
float: left; }
span.float-left span {
margin: 13px 0 0; }
span.float-right {
display: block;
margin-left: 13px;
overflow: hidden;
float: right; }
span.float-right > span {
display: block;
overflow: hidden;
margin: 13px auto 0;
text-align: right; }

code, tt {
margin: 0 2px;
padding: 0 5px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #f8f8f8;
border-radius: 3px; }

pre code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent; }

.highlight pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px; }

pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px; }
pre code, pre tt {
background-color: transparent;
border: none; }

sup {
font-size: 0.83em;
vertical-align: super;
line-height: 0;
}

kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #555;
vertical-align: middle;
background-color: #fcfcfc;
border: solid 1px #ccc;
border-bottom-color: #bbb;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #bbb
}

* {
-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
body {
width: 854px;
margin:0 auto;
}
}
@media print {
table, pre {
page-break-inside: avoid;
}
pre {
word-wrap: break-word;
}
}
-->

Spark Programming--- Shuffle operations

http://spark.apache.org/docs/latest/rdd-programming-guide.html#shuffle-operations

一些spark的特定操作将会触发被称为shuffle的事件。Shuffle是Spark用于重新分布数据的机制,这样可以在不同的分区来分组。这通常涉及到在executor和机器之间进行拷贝数据,所以shuffle是一个很复杂并且消耗高的操作。

背景

为了了解shuffle期间发生了什么,我们可以考虑reduceByKey操作作为例子。reduceByKey操作生成了一个新的RDD通过所有的单个键值组合为一个元组-关键字和针对与该关键字相关的所有值执行reduce函数的结果。这里的挑战不是所有的值对一个单独的键都在同一个分区上或者甚至说在一台机器上,而是它们必须被重新分布来计算结果。
在Spark,数据通常不会跨分区分布到特定操作的必要位置。在计算中,一个单独的任务将会在一个单独的分区上操作-然而为了组织所有的数据来被一个的单独reduceByKey 的reduce任务来执行,Spark需要来执行一个all-to-all操作。它必须读取所有分区来找到所有键的值,然后将它们带到一起跨分区来为每一个键计算最终的结果---这个被称为shuffle。
尽管在每一个分区中的新的shuffled数据的元素集是很重要的,同样分区自己的顺序也很重要,而元素之间的顺序就不是了。如果一个想要预测shuffle中的顺序数据那么可以使用:

  1. mapPartitions 来排序每一个分区,比如,.sorted
  2. repartitionAndSortWithinPartitions 来有效分区同时同步重新分区。
  3. sortBy 创造一个全局的排序的RDD

可以引起一个shuffle 的操作包括:repartition 和 coalesce,ByKey的操作,除了counting之外的比如:groupByKey 和reduceByKey,以及join操作比如cogroup 和 join。

性能影响

Shuffle是一个昂贵的操作因为它涉及到磁盘I/O,数据序列化和网络I/O。为了给shuffle组织数据,spark生成一系列任务-maps用于组织数据,以及一系列reduce任务来聚集它。这个命名系统来自于MapReduce而且并不直接和SparK的map,reduce操作有关。
在内部,单独的map任务的结果会被保存在内存中直到它们不适用。然后这些结果会被根据目标分区排序并且写向单一的文件。在reduce方面,任务读取相关的排序块。
一定的shuffle操作会消耗明显的数量的堆内存因为它们使用的是在内存中的数据结构来组织记录在传输之前或者之后。明显的,reduceByKey和AggregateByKey创造了这些结构在map阶段,以及 ‘Bykey的操作生成了它们在reduce阶段。当数据不能放进内存中时,Spark将会将这些表散落到硬盘中,会引起而外的磁盘I/O和增加垃圾回收次数。
Shuffle同样会生成大量的中间文件在磁盘中。从Spark1.3开始,这些文件被保存直到对应的RDDs不再被使用以及已经被垃圾回收了。这样做是为了shuffle文件不需要被重新创造如果lineage被重新计算时。垃圾回收也许会发生只有在一段很长时间,如果这个应用保留了对RDD的引用或者如果GC没有频繁的发生。这意味着长期运行的spark任务也许会消耗大量的磁盘空间。这个零时的磁盘目录会被spark.local.dir参数所指定。
Shuffle行为可以被调整通过一系列的参数。可以参考Spark Configuration Guide.‘Shuffle Behavior’章节。

Shuffle Behavior

属性名称Property Name 默认值Default 含义Meaning
spark.reducer.maxSizeInFlight 48m 从每一个reduce任务中同步获取的map输出的最大值。由于每一个输出需要我们创造一个缓存来接受它,这个代表了每个任务的固定的内存开销,所以尽量保证它较小除非你有很多内存。
spark.reducer.maxReqsInFlight Int.MaxValue 这个配置限制了任意给定点远程请求获取块数。当集群中的主机数量增加的时候,它也许会导致一个非常大数量的内部连接到一到多个节点,引起worker在负载下失败。通过允许它来限制获取请求的数量,这个情况也许会缓解
spark.reducer.maxBlocksInFlightPerAddress Int.MaxValue 这个配置限制了每一个从给定端口里的的reduce任务可以获取的远程端口数量。当一个大量的block被一个给定的地址在一次单独获取或者同步获取所请求时,可能会冲垮服务的executor或者Node Manager。这个配置对于减少Node Manager的负载尤为有用当外部的shuffle是被允许的。你可以通过设定一个较低值来减轻这个情况。
spark.maxRemoteBlockSizeFetchToMem Long.MaxValue 远程的块将会被获取到磁盘中,当这个块的大小超过了这个配置的值在byte单位上。这个用于避免一个巨大的请求占据了太多的内存。我们可以将这个配置为一个指定的值(比如,200M)。注意到这个配置将会影响到shuffle的获取以及远程块获取的块管理。对于允许了外部shuffle服务的用户,这个特性只会在外部shuffle服务版本高于Spark2。2时有效。
spark.shuffle.compress true 是否压缩map的输出文件,通常是一个好想法。压缩将会使用spark.io.compression.codec.
spark.shuffle.file.buffer 32k 对每一个shuffle文件输出流的在内存中的缓存大小,单位是KiB除非有其他的特别指定。这些缓存减少了硬盘查找和系统调用创建中间shuffle文件的过程。
spark.shuffle.io.maxRetries 3 (Netty only)最大自动重复尝试的次数如果这个值没有被设置为0.这个重试逻辑有助于稳定大型的shuffle在长时间的GC暂停或者暂时的网络连接问题上。
spark.shuffle.io.numConnectionsPerPeer 1 (Netty only) 节点之间的连接的重复使用为了减少大型集群中重复建立连接的情况。对于有很多硬盘和很少主机的集群,这个将会导致并发行不足以饱和所有硬盘,因此用户可能会考虑增加这个值。
spark.shuffle.io.preferDirectBufs true (Netty only) 堆外缓冲区在shuffle和缓存块转移期间被用于减少垃圾回收。对于对外缓存内存数量有限的环境,用户也许想要关掉这个来强迫所有的来自于Netty的分配都是在堆上。
spark.shuffle.io.retryWait 5s (Netty only) 在每一次重试直接需要等待多久。最大的延迟时间默认是15秒,maxRetries * retryWait.
spark.shuffle.service.enabled false 允许外部shuffle服务。这个服务保存了通过executor所写的shuffle文件,这样这个executor可以安全的被移除。这个配置必须被允许如果spark.dynamicAllocation.enabled是“true”。这个外部的shuffle服务必须被启动。查看dynamic allocation configuration and setup documentation来获得更多信息。
spark.shuffle.service.port 7337 外部shuffle服务将会运行的端口。
spark.shuffle.service.index.cache.size 100m 缓存条目限制在指定的内存占用空间中,以字节为单位
spark.shuffle.maxChunksBeingTransferred Long.MAX_VALUE 在shuffle服务中同一时间最大允许传输的块数量。注意到新来的连接将会被关闭如果达到了最大数量。这个客户端将会尝试重新连接根据shuffle的重试配置(see spark.shuffle.io.maxRetries and spark.shuffle.io.retryWait),如果这个限制也被达到了,那么这个任务将会失败。
spark.shuffle.sort.bypassMergeThreshold 200 (Advanced)在基于排序的shuffle管理中,避免合并排序数据如果这里没有map-side的聚合和这里最多有配置的这么多的reduce分区。
spark.shuffle.spill.compress true 是否压缩溢出的数据在shuffle期间
spark.shuffle.accurateBlockThreshold 100 * 1024 * 1024 阀值是以bytes为单位,高于此值将准确记录HighlyCompressedMapStatus中的shuffle块的大小。这个用于帮助阻止OOM通过避免错误估计了shuffle块大小当获取了shuffle块时。
spark.shuffle.registration.timeout 5000 注册外部shuffle服务的超时时间,单位是毫秒
spark.shuffle.registration.maxAttempts 3 当注册外部shuffle服务失败的时候,我们会重复尝试的最大次数
spark.io.encryption.enabled false 允许IO编码。目前支持所有的模式除了Mesos。当使用这个特性的时候,我们推荐RPC编码。
spark.io.encryption.keySizeBits 128 IO编码的值大小单位为bit。支持的值有128,192和256.
spark.io.encryption.keygen.algorithm HmacSHA1 当生成一个IO编码键值时使用的算法。被支持的算法在Java Cryptography Architecture Standard Algorithm Name 文档的KeyGenerator章节中被描述。

Spark Programming--- Shuffle operations的更多相关文章

  1. Spark Programming Guide《翻译》

    转载必须注明出处:梁杰帆 在这里要先感谢原作者们!如果各位在这里发现了错误之处,请大家提出 1.Initializing Spark     Spark程序必须做的第一件事就是创建一个SparkCon ...

  2. spark.sql.shuffle.partitions和spark.default.parallelism的区别

    在关于spark任务并行度的设置中,有两个参数我们会经常遇到,spark.sql.shuffle.partitions 和 spark.default.parallelism, 那么这两个参数到底有什 ...

  3. 【Spark】Spark的Shuffle机制

    MapReduce中的Shuffle 在MapReduce框架中,shuffle是连接Map和Reduce之间的桥梁,Map的输出要用到Reduce中必须经过shuffle这个环节,shuffle的性 ...

  4. 【Spark篇】---Spark中Shuffle文件的寻址

    一.前述 Spark中Shuffle文件的寻址是一个文件底层的管理机制,所以还是有必要了解一下的. 二.架构图 三.基本概念: 1) MapOutputTracker MapOutputTracker ...

  5. 【Spark篇】---Spark中Shuffle机制,SparkShuffle和SortShuffle

    一.前述 Spark中Shuffle的机制可以分为HashShuffle,SortShuffle. SparkShuffle概念 reduceByKey会将上一个RDD中的每一个key对应的所有val ...

  6. Spark 的 Shuffle过程介绍`

    Spark的Shuffle过程介绍 Shuffle Writer Spark丰富了任务类型,有些任务之间数据流转不需要通过Shuffle,但是有些任务之间还是需要通过Shuffle来传递数据,比如wi ...

  7. 研究一下Spark Hash Shuffle 和 SortShuffle 原理机制

    研究一下Spark Hash Shuffle 和 SortShuffle 原理机制研究一下Spark Hash Shuffle 和 SortShuffle 原理机制研究一下Spark Hash Shu ...

  8. 剖析Hadoop和Spark的Shuffle过程差异

    一.前言 对于基于MapReduce编程范式的分布式计算来说,本质上而言,就是在计算数据的交.并.差.聚合.排序等过程.而分布式计算分而治之的思想,让每个节点只计算部分数据,也就是只处理一个分片,那么 ...

  9. [Spark]What's the difference between spark.sql.shuffle.partitions and spark.default.parallelism?

    From the answer here, spark.sql.shuffle.partitions configures the number of partitions that are used ...

  10. spark的shuffle机制

    对于大数据计算框架而言,Shuffle阶段的设计优劣是决定性能好坏的关键因素之一.本文将介绍目前Spark的shuffle实现,并将之与MapReduce进行简单对比.本文的介绍顺序是:shuffle ...

随机推荐

  1. df命令,du命令,磁盘分区

    df 命令 功能:用来检查linux的文件系统的磁盘空间占用情况 1. df -h 2. 以innode节点数量显示磁盘空间占用情况 df -ih 3. 列出文件系统类型 df -Th du 命令 功 ...

  2. 解决time_wait过多

    需要真正找出问题或瓶颈,但调整单机参数能临时解决:(收集自:https://www.cnblogs.com/dadonggg/p/8778318.html) 编辑内核文件/etc/sysctl.con ...

  3. layer弹出层不居中解决方案(转)

    @感谢参考文章 原文内容: 一.问题描述 用layer做操作结果提示时,发现如果页面超出屏幕的高度时,弹出的提示不是屏幕居中,而是在页面高度的中间,如果一个页面的高度比较大,就看不到提示了. 还有一种 ...

  4. iview 路由权限判断的处理

    主要是在main.vue做处理 其它地方不需要处理 menuList () { let getRouter = JSON.parse(sessionStorage.getItem('getUserDa ...

  5. 监控服务器配置(五)-----Redis_exporter安装配置

    1.下载redis_exporter安装包(linux版)到 /opt/minitor/redis_exporter . 下载地址:https://download.csdn.net/download ...

  6. 两个Integer比较

    两个Integer类型比较不能使用==,要使用equals,   == 在-127~128是可以用的,超出这个范围就不行 public static void main(String[] args) ...

  7. day04-Servlet介绍(1)

    1.servlet的概述 a.什么是servlet --servlet是javaWeb的三大组件(Listener,Filter)之一,他属于动态资源 --servlet的作用是(10086): 服务 ...

  8. JavaScript初见

    警告alert() 确认confirm() 提问prompt() 空格 JavaScript-打开新窗口(window.open) open() 方法可以查找一个已经存在或者新建的浏览器窗口. 语法: ...

  9. 旅游类的APP原型模板分享——Priceline

    Priceline是一款旅游服务的APP应用.功能有查找预订酒店.车票.机票等服务. 本原型由国产Mockplus(原型工具)和iDoc(智能标注,一键切图工具)提供. 先简单看看动图: 点击这里,可 ...

  10. Gym - 101848B Almost AP 暴力

    题目链接:http://codeforces.com/gym/101848/problem/B 给出一串数字要你最多改动三个数字使这一串数字成为等差数列.因为最多改动三个数字所以可以先求出相邻两项的差 ...