025_MapReduce样例Hadoop TopKey算法
1、需求说明
aaarticlea/png;base64,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" alt="" width="307" height="210" />
2、 某个文件中某列数据的最大值。
思路:对每一个列的值依次进行比较,保存最大的值进行输出,算法的思想类似于排序算法(快速和冒泡排序)。
Mapper:因为只是在wordcount统计的基础上统计的,只是针对一个列,故可以找到最大值后,将最大值和对应的text给,cleanup中的context.write()方法,然后输出。此时不需要Reducer。
package org.dragon.hadoop.mapreduce.app.topk; import java.io.IOException; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /**
* 功能:某个文件中某列数据的最大值某个文件中
*
* 针对wordcount程序输出的单词统计信息,求出单词出现频率最高的那个。 即:求给定的键值对中,value的最大值
* @author ZhuXY
* @time 2016-3-12 下午3:43:23
*
*/
public class TopKMapReduce { /*
* ******************************************************
* 这个程序很好解释了splitsize对应一个map task,而一行数据对应一个map()函数。 即一个map task对应几个map()函数
* ******************************************************
*/ // Mapper class
static class TopKMapper extends
Mapper<LongWritable, Text, Text, LongWritable> {
// map output key
private Text mapOutputKey = new Text();//java的变量(对象)使用前一定要先创建 // map output value
private LongWritable mapOutputValue = new LongWritable(); /*
* ********************************
* 此处创建对所有的map()函数有效
* *******************************
*/ // store max value,init long.MIN_VALUE
private long topKValue = Long.MIN_VALUE; @Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// get value
String lineValue =value.toString();
String[] str = lineValue.split("\t"); Long tempValue = Long.valueOf(str[1]); // comparator
if (topKValue < tempValue) {
topKValue = tempValue;
// set mapout key当找到相对的最大值给topKValue时,将该单词同时赋值给输出key
mapOutputKey.set(str[0]);
} // 此处的context不需要填写,查看源码发现context是个内部类,源码中是由cleanup负责处理
} @Override
protected void setup(Context context) throws IOException,
InterruptedException {
super.setup(context);
} @Override
protected void cleanup(Context context) throws IOException,
InterruptedException {
// set map output value
mapOutputValue.set(topKValue); // set mapoutput context
context.write(mapOutputKey, mapOutputValue);
}
} // Driver Code
public int run(String[] args) throws Exception, IOException,
InterruptedException {
// get conf
Configuration conf = new Configuration(); // create job
Job job = new Job(conf, TopKMapReduce.class.getSimpleName()); // set job
job.setJarByClass(TopKMapReduce.class);
// 1) input
Path inputDirPath = new Path(args[0]);
FileInputFormat.addInputPath(job, inputDirPath); // 2) map
job.setMapperClass(TopKMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class); // 3) reduce
// job.setReducerClass(DataTotalReducer.class);
// job.setOutputKeyClass(Text.class);
// job.setOutputValueClass(DataWritable.class);
job.setNumReduceTasks(0);// 因为本程序没有Reducer的过程,这里必须设置为0 // 4) output
Path outputDir = new Path(args[1]);
FileOutputFormat.setOutputPath(job, outputDir); // submit job
boolean isSuccess = job.waitForCompletion(true); // return status
return isSuccess ? 0 : 1;
} // run mapreduce
public static void main(String[] args) throws Exception, IOException,
InterruptedException {
// set args
args = new String[] { "hdfs://hadoop-master:9000/wc/wcoutput",
"hdfs://hadoop-master:9000/wc/output" }; // run job
int status = new TopKMapReduce().run(args);
// exit
System.exit(status);
} }
View TopKMapReduce Code
3、 某个文件某列数据的Top Key的值(最大或者最小)
思路:用一个TreeMap保存,TreeMap可以自动根据Key排序,故将出现的次数当做Key进行hash存储。然后TreeMap.size()>NUM时,删除最小的就行了。
Mapper:在原有的基础上增加TreeMap
package org.dragon.hadoop.mapreduce.app.topk; import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import com.sun.org.apache.bcel.internal.generic.NEW; /**
* 功能:某列的TopKey的值,即最大(小)的几个。K小值问题
*
* @author ZhuXY
* @time 2016-3-12 下午3:43:23
*
*/
public class TopKMapReduceV2 { /*
* 思想:用一個集合TreeSet存儲對應的鍵值對,然後當大於三個的時候進行刪除。
* 该集合自动按照键进行排序,然后保留最大的三个
* 注意:集合 key value
* 真是 value key
*/ // Mapper class
static class TopKMapper extends
Mapper<LongWritable, Text, Text, LongWritable> { // 用作保存TopKey的键和值
private TreeMap<Long, String> topKTreeMap = new TreeMap<Long, String>(); @Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// get value
String lineValue = value.toString();
String[] str = lineValue.split("\t"); long tempKey = Long.valueOf(str[1]);
String tempValue = String.valueOf(str[0]); topKTreeMap.put(tempKey, tempValue);
if (topKTreeMap.size() > 3) {
topKTreeMap.remove(topKTreeMap.firstKey());
}
} @Override
protected void setup(Context context) throws IOException,
InterruptedException {
super.setup(context);
} @Override
protected void cleanup(Context context) throws IOException,
InterruptedException {
Set<Long> mapValueSet = topKTreeMap.keySet();// long 名字起得不好 Text mapOutputKey = new Text();
LongWritable mapOutputValue = new LongWritable(); // for (Iterator<Long> iterator = mapValueSet.iterator(); iterator
// .hasNext();) {
//
// long iteratorNum=iterator.next();
// mapOutputValue.set(iteratorNum);// long
// mapOutputKey.set(topKTreeMap.get(iteratorNum));
//
// context.write(mapOutputKey, mapOutputValue);
// } for(long key:mapValueSet){
mapOutputValue.set(key);// long
mapOutputKey.set(topKTreeMap.get(key)); context.write(mapOutputKey, mapOutputValue);
}
}
} // Driver Code
public int run(String[] args) throws Exception, IOException,
InterruptedException {
// get conf
Configuration conf = new Configuration(); // create job
Job job = new Job(conf, TopKMapReduceV2.class.getSimpleName()); // set job
job.setJarByClass(TopKMapReduceV2.class);
// 1) input
Path inputDirPath = new Path(args[0]);
FileInputFormat.addInputPath(job, inputDirPath); // 2) map
job.setMapperClass(TopKMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class); // 3) reduce
// job.setReducerClass(DataTotalReducer.class);
// job.setOutputKeyClass(Text.class);
// job.setOutputValueClass(DataWritable.class);
job.setNumReduceTasks(0);// 因为本程序没有Reducer的过程,这里必须设置为0 // 4) output
Path outputDir = new Path(args[1]);
FileOutputFormat.setOutputPath(job, outputDir); // submit job
boolean isSuccess = job.waitForCompletion(true); // return status
return isSuccess ? 0 : 1;
} // run mapreduce
public static void main(String[] args) throws Exception, IOException,
InterruptedException {
// set args
args = new String[] { "hdfs://hadoop-master:9000/wc/wcoutput",
"hdfs://hadoop-master:9000/wc/output1" }; // run job
int status = new TopKMapReduceV2().run(args);
// exit
System.exit(status);
} }
View TopKMapReduceV2 Code
4、 多个文件中某列数据的Top Key的值(最大或者最小)
思路:此处因为是多个文件,故Reducer至少且只能为1个,即default也就是1个。将TreeMap放在Reducer内部的reduce函数进行处理。
package org.dragon.hadoop.mapreduce.app.topk; import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Mapper.Context;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.eclipse.core.internal.filesystem.local.Convert; import com.sun.org.apache.bcel.internal.generic.NEW; /**
* 功能:多个文件中某列数据和的最大值
*
* 思想:类似wordcount,把每行数据统计好,context出去---mapper
* 接收到经过shuffle和merge形成<key,list<1,2,3,4…>>----透明
* 在cleanup中,收集reduce中的TreeMap集合,进行排序删除-------reduce、cleanup
*
* @author ZhuXY
* @time 2016-3-12 下午3:43:23
*
*/
public class TopKMapReduceV3 { /*
* 思想:用一個集合TreeSet存儲對應的鍵值對,然後當大於三個的時候進行刪除。
* 该集合自动按照键进行排序,然后保留最大的三个
* 注意:集合 key value
* 真是 value key
*/ // Mapper class
static class TopKMapper extends
Mapper<LongWritable, Text, Text, LongWritable> { Text mapOutputKey=new Text(); //key
LongWritable mapOutputValue=new LongWritable();//value @Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// get value
String lineValue = value.toString();
String[] str = lineValue.split("\t"); mapOutputKey.set(str[0]); mapOutputValue.set(Long.parseLong(str[1])); context.write(mapOutputKey, mapOutputValue); }
} static class TopKReducer extends
Reducer<Text, LongWritable, Text, LongWritable>{ // 用作保存TopKey的键和值
private TreeMap<Long, String> topKTreeMap = new TreeMap<Long, String>(); @Override
protected void reduce(Text key, Iterable<LongWritable> values,Context context)
throws IOException, InterruptedException {
int sum=0;
//循环遍历Interable
for(LongWritable value:values)
{
//累加
sum+=value.get();
} long tempKey = Long.valueOf(sum);
String tempValue = String.valueOf(key); topKTreeMap.put(tempKey, tempValue);
if (topKTreeMap.size() > 3) {
topKTreeMap.remove(topKTreeMap.firstKey());
}
} @Override
protected void cleanup(Context context)
throws IOException, InterruptedException { //TreeMap键的集合
Set<Long> mapValueSet = topKTreeMap.keySet();// long 名字起得不好 Text mapOutputKey = new Text();
LongWritable mapOutputValue = new LongWritable(); //根据键,获取值,并交叉赋予context中参数
for(long key:mapValueSet){
mapOutputValue.set(key);// long
mapOutputKey.set(topKTreeMap.get(key)); context.write(mapOutputKey, mapOutputValue);
}
} } // Driver Code
public int run(String[] args) throws Exception, IOException,
InterruptedException {
// get conf
Configuration conf = new Configuration(); // create job
Job job = new Job(conf, TopKMapReduceV3.class.getSimpleName()); // set job
job.setJarByClass(TopKMapReduceV3.class);
// 1) input
Path inputDirPath = new Path(args[0]);
FileInputFormat.addInputPath(job, inputDirPath); // 2) map
job.setMapperClass(TopKMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class); // 3) reduce
job.setReducerClass(TopKReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//job.setNumReduceTasks(0);// default 1 // 4) output
Path outputDir = new Path(args[1]);
FileOutputFormat.setOutputPath(job, outputDir); // submit job
boolean isSuccess = job.waitForCompletion(true); // return status
return isSuccess ? 0 : 1;
} // run mapreduce
public static void main(String[] args) throws Exception, IOException,
InterruptedException {
// set args
args = new String[] { "hdfs://hadoop-master:9000/wc/wcinput",
"hdfs://hadoop-master:9000/wc/output2" }; // run job
int status = new TopKMapReduceV3().run(args);
// exit
System.exit(status);
} }
View TopKMapReduceV3 Code
5、 统计和Top Key
思路:这个比较难。没有在统计好的基础上进行操作,而是直接统计,然后进行比较。具体看下面应用
数据格式:
语言类别 歌曲名称 收藏次数 播放次数 歌手名称
需求:
统计前十首播放次数最多的歌曲名称和次数。
测试数据:
经典老歌 我只在乎你 1234 34535 邓丽君
流行歌曲 流着泪说分手 125 2342 金志文
流行歌曲 菠萝菠萝蜜 543 536 谢娜
经典老歌 大花轿 123 3465 火风
流行歌曲 无所谓 3453 87654 杨坤
定义一个数据类型TopKWritable:
package org.dragon.hadoop.mapreduce.app.topk; import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.io.WritableComparable; /**
*
* @author ZhuXY
* @time 2016-3-13 下午7:30:21
*
*/ /**
*
* 数据格式:
* 语言类别 歌曲名称 收藏次数 播放次数 歌手名称
* 需求:
* 统计前十首播放次数最多的歌曲名称和次数。
*/
public class TopKWritable implements WritableComparable<TopKWritable>{
private String languageType=null;
private String songName=null;
private long playNum=0; public TopKWritable(){ }
public TopKWritable(String languageType,String songName,long playNum){
set(languageType, songName, playNum);
}
public void set(String languageType,String songName,Long playNum){
this.languageType=languageType;
this.songName=songName;
this.playNum=playNum;
} public String getLanguageType() {
return languageType;
}
public String getSongName() {
return songName;
}
public Long getPlayNum() {
return playNum;
} @Override
public void write(DataOutput out) throws IOException {
out.writeUTF(languageType);
out.writeUTF(songName);
out.writeLong(playNum);
} @Override
public void readFields(DataInput in) throws IOException {
this.languageType=in.readUTF();
this.songName=in.readUTF();
this.playNum=in.readLong();
} @Override
public int compareTo(TopKWritable o) { //此处-1是为了在输出的时候是按照从大到小的次序输出
return -this.getPlayNum().compareTo(o.getPlayNum());
} @Override
public String toString() {
return languageType + "\t"
+ songName + "\t"
+ playNum;
} @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((languageType == null) ? 0 : languageType.hashCode());
result = prime * result + (int) (playNum ^ (playNum >>> 32));
result = prime * result
+ ((songName == null) ? 0 : songName.hashCode());
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TopKWritable other = (TopKWritable) obj;
if (languageType == null) {
if (other.languageType != null)
return false;
} else if (!languageType.equals(other.languageType))
return false;
if (playNum != other.playNum)
return false;
if (songName == null) {
if (other.songName != null)
return false;
} else if (!songName.equals(other.songName))
return false;
return true;
}
}
View TopKWritable Code
正式的Mapper和Reducer类;
package org.dragon.hadoop.mapreduce.app.topk; import java.io.IOException;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.TreeSet; import javax.security.auth.callback.LanguageCallback; import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.Mapper.Context;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.dragon.hadoop.mapreduce.app.topk.TopKMapReduceV3.TopKReducer; import com.sun.jersey.core.header.LanguageTag; import sun.reflect.LangReflectAccess; /**
*
* @author ZhuXY
* @time 2016-3-13 下午12:57:26
*
*/ /**
* 统计 & TopKey
*
* 数据格式: 语言类别 歌曲名称 收藏次数 播放次数 歌手名称 需求: 统计前十首播放次数最多的歌曲名称和次数。
*
* 思想:在Mapper中输出:key---歌曲类型+歌曲名称
* value---播放次数
* Reducer中:key----封装成TopKWritable对象
* value---nullwritable
* reduce方法中进行集合存储,然后删除多余的
*
*/
public class TopKMapReduceV4 {
private static final int KEY = 4; // Mapper class
public static class TopKMapper extends
Mapper<LongWritable, Text, Text, LongWritable> { @Override
protected void cleanup(Context context) throws IOException,
InterruptedException {
super.cleanup(context);
} @Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
//文件的输入类型为TextInputFormat,默认到map中的为<Longwritable,Text>
String lineValue = value.toString(); if (null == lineValue) {
return;
} //split
String[] splitValue = lineValue.split("\t"); if (splitValue != null && splitValue.length == 5) {
String languageType = splitValue[0];
String songName = splitValue[1];
Long playNum = Long.parseLong(splitValue[3]); context.write(new Text(languageType + "\t" + songName),
new LongWritable(playNum));
}
} @Override
protected void setup(Context context) throws IOException,
InterruptedException {
// TODO Auto-generated method stub
super.setup(context);
}
} // Reducer class
public static class TopKReducer extends
Reducer<Text, LongWritable, TopKWritable, NullWritable> { //此集合的排序规则即为TopKWritable中comparaTo的排序规则
TreeSet<TopKWritable> treeSet=new TreeSet<TopKWritable>(); @Override
protected void setup(Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
super.setup(context);
} @Override
protected void reduce(Text key, Iterable<LongWritable> values,
Context context) throws IOException, InterruptedException { Long palyNum=(long) 0;
if (key==null) {
return;
} //get key
String[] keyArr=key.toString().split("\t");
String languageType=keyArr[0];
String songName=keyArr[1]; //sum
for(LongWritable value:values){
palyNum+=value.get();
} //歌曲类型、歌曲名称、歌曲播放次数封装成TopKWritable对象,保存在treeSet集合中,此集合自动排序
treeSet.add(new TopKWritable(
languageType,songName,palyNum
)); if (treeSet.size()>KEY) {
treeSet.remove(treeSet.last());//remove the current small longNum
}
} @Override
protected void cleanup(Context context)
throws IOException, InterruptedException {
for (TopKWritable topKWritable : treeSet) {
context.write(topKWritable,NullWritable.get());
}
} }
// Driver Code
public int run(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
// get conf
Configuration conf=new Configuration(); // create job
Job job =new Job(conf, TopKMapReduceV4.class.getSimpleName());//Job name // set job
job.setJarByClass(TopKMapReduceV4.class); // 1)set inputPath
FileInputFormat.addInputPath(job, new Path(args[0])); // 2)set map
job.setMapperClass(TopKMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class); // 3)set outputPath
FileOutputFormat.setOutputPath(job, new Path(args[1])); // 4)set reduce
job.setReducerClass(TopKReducer.class);
job.setOutputKeyClass(TopKWritable.class);
job.setOutputValueClass(NullWritable.class); // submit job
boolean isSuccess=job.waitForCompletion(true); //return status
return isSuccess?0:1;
} public static void main(String[] args) throws IOException, InterruptedException, Exception { args=new String[]{
"hdfs://hadoop-master.dragon.org:9000/wc/wcinput/",
"hdfs://hadoop-master.dragon.org:9000/wc/wcoutput"
};
int status =new TopKMapReduceV4().run(args);
System.exit(status);
}
}
View TopKMapReduceV4 Code
025_MapReduce样例Hadoop TopKey算法的更多相关文章
- hadoop学习;block数据块;mapreduce实现样例;UnsupportedClassVersionError异常;关联项目源代码
对于开源的东东,尤其是刚出来不久,我认为最好的学习方式就是能够看源代码和doc,測试它的样例 为了方便查看源代码,关联导入源代码的项目 先前的项目导入源代码是关联了源代码文件 block数据块,在配置 ...
- [hadoop系列]Pig的安装和简单演示样例
inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ).(来源:http://blog.csdn.net/inkfish) Pig是Yaho ...
- 一致性哈希算法(consistent hashing)样例+測试。
一个简单的consistent hashing的样例,非常easy理解. 首先有一个设备类,定义了机器名和ip: public class Cache { public String name; pu ...
- 源代码方式向openssl中加入新算法完整具体步骤(演示样例:摘要算法SM3)【非engine方式】
openssl简单介绍 openssl是一个功能丰富且自包括的开源安全工具箱.它提供的主要功能有:SSL协议实现(包括SSLv2.SSLv3和TLSv1).大量软算法(对称/非对称/摘要).大数运算. ...
- 数据挖掘之分类算法---knn算法(有matlab样例)
knn算法(k-Nearest Neighbor algorithm).是一种经典的分类算法. 注意,不是聚类算法.所以这样的分类算法必定包含了训练过程. 然而和一般性的分类算法不同,knn算法是一种 ...
- 网易2018.03.27算法岗,三道编程题100%样例AC题解
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/8660814.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- java设计模式演示样例
创建模式 1.工厂方法模式(Factory Method) 将程序中创建对象的操作,单独出来处理,创建一个产品的工厂接口,把实际的工作转移到详细的子类.大大提高了系统扩展的柔性,接口的抽象化处理给相 ...
- 策略模式——MFC样例
Context(应用场景): 1.须要使用ConcreteStrategy提供的算法. 2.内部维护一个Strategy的实例. 3. 负责动态设置执行时Strategy详细的实现算法. 4.负责跟S ...
- Hadoop0.20.2 Bloom filter应用演示样例
1. 简单介绍 參见<Hadoop in Action>P102 以及 <Hadoop实战(第2版)>(陆嘉恒)P69 2. 案例 网上大部分的说明不过依照<Hadoop ...
随机推荐
- 基于AR9331(MIPS架构)分析系统启动过程(uboot)
前提: 1.AR9331是基于MIPS 24K CPU的一款WIFI1X1芯片,其SDK采用uboot作为引导.AR9331中定义的基地址是:0x9f00,0000 2.MIPS24K芯片,将固定的起 ...
- 2017-5-14 湘潭市赛 Parentheses 转化思想+贪心 使括号序列合法的最小花费。满足前面左括号的数量>=有括号的数量。
Parentheses Accepted : Submit : Time Limit : MS Memory Limit : KB Parentheses Bobo has a very long s ...
- spring oauth Role and Authority and scope
使用hasRole class Grant implements GrantedAuthority{ @Override public String getAuthority() { return & ...
- php windows 扩展redis
一:客户端安装redis (1)下载地址:https://github.com/dmajkic/redis/downloads 根据电脑是多少位的使用对应的文件,如我的是64bit,那么我就选择64b ...
- Web Services 概要
WSDL WSDL 是基于 XML 的用来描述 Web services 以及如何访问它们的一种语言. WSDL 可描述 web service,连同用于 web service 的消息格式和协议的细 ...
- hbuilder mui如何监听搜索框点击清除按钮
监听代码如下: mui(".mui-icon-clear")[0].addEventListener('tap',function(){ console.log(456)}) ...
- 《从零开始学Swift》学习笔记(Day43)——构造函数继承
原创文章,欢迎转载.转载请注明:关东升的博客 Swift中的子类构造函数的来源有两种:自己编写和从父类继承.并不是父类的所有的构造函数都能继承下来,能够从父类继承下来的构造函数是有条件的,如下所示. ...
- 第七课 nodejs请求响应
1 server.js 接收请求接收请求参数 和接收完成需要对request增加两个监听事件 var http = require('http');var url = require('url');f ...
- On the fly test
on the fly test就是边开发边测试的意思.test code不是早就生成好的,在一边生成code的同时一边做test running,最大的好处是,flexiable ,每一次可以选择不同 ...
- ubuntu1.4搭建zookeeper3.5.2分布式集群
1.下载 官网链接:http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.5.2-alpha/zookeeper-3.5.2-alpha.ta ...