Hadoop代码测试版:Hadoop2.4

原理:携带MR该程序随机抽样提取前的输入数据,样本分类,然后,MR该过程的中间Partition此值用于当样品排序分组数据。这使得可以实现全球排名的目的。

难度:假设Hadoop全局排序,那么要求Mapper的输入、输出的key不变才干够,由于在源代码InputSampler中提供的随机抽取的数据是输入数据最原始的key,例如以下代码(line:225):

      for (int i = 0; i < splitsToSample ||
(i < splits.size() && samples.size() < numSamples); ++i) {
TaskAttemptContext samplingContext = new TaskAttemptContextImpl(
job.getConfiguration(), new TaskAttemptID());
RecordReader<K,V> reader = inf.createRecordReader(
splits.get(i), samplingContext);
reader.initialize(splits.get(i), samplingContext);
while (reader.nextKeyValue()) {
if (r.nextDouble() <= freq) {
if (samples.size() < numSamples) {
samples.add(ReflectionUtils.copy(job.getConfiguration(),// here is line 225
reader.getCurrentKey(), null));
} else {
// When exceeding the maximum number of samples, replace a
// random element with this one, then adjust the frequency
// to reflect the possibility of existing elements being
// pushed out
int ind = r.nextInt(numSamples);
if (ind != numSamples) {
samples.set(ind, ReflectionUtils.copy(job.getConfiguration(),
reader.getCurrentKey(), null));
}
freq *= (numSamples - 1) / (double) numSamples;
}
}
}
reader.close();
}

当中的samples.add(  ...   就是加入的样本。这样事实上应该是须要调整的。

举一个非常实际的样例,我的输入一般都是LongWritable(距离文本首的长度),可是我的Mapper输出的key能够是Text的类型的,那么在建立样本值的时候就会有问题。

假设解决呢?

事实上能够把上面的代码中的加入部分改动一下。改为Mapper的map逻辑就可以(參考以下的实例)。

应用场景:当MR程序有多个reducer的时候,就会对应的产生多个输出文件。这些输出文件内部是有按顺序排列的,可是,文件之间却没有依照顺序排列。使用TotalOrderPartitioner就能够达到不同的文件之间也是排序的效果。

实例:

測试数据。採用三个測试数据(这样就能够有三个分片,默认一个文件一个分片)

aaarticlea/png;base64,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" alt="" />

測试主程序完毕的任务就是把上面的数据依照“_”分隔,然后把“_”后面的数字作为key,前面的字符串作为value进行输出。这样就能够看到输出的key是否是全局排序的了。

測试主程序:

package fz.totalorder.partitioner;

import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.mapreduce.lib.partition.MyInputSampler;
import org.apache.hadoop.mapreduce.lib.partition.TotalOrderPartitioner;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner; //import fz.Utils; public class PartitionerDriver extends Configured implements Tool { @Override
public int run(String[] arg0) throws Exception {
Configuration conf = getConf();
if(arg0.length!=3){
System.err.println("Usage:\nfz.partitioner.PartitionerDriver <in> <out> <useTotalOrder>");
return -1;
}
// System.out.println(conf.get("fs.defaultFS"));
Path in = new Path(arg0[0]);
Path out= new Path(arg0[1]);
out.getFileSystem(conf).delete(out, true);
Job job = Job.getInstance(conf,"total order partitioner");
job.setJarByClass(getClass()); job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
job.setMapperClass(PartitionerMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.setReducerClass(Reducer.class);
job.setNumReduceTasks(2);
// System.out.println(job.getConfiguration().get("mapreduce.job.reduces"));
// System.out.println(conf.get("mapreduce.job.reduces"));
FileInputFormat.setInputPaths(job, in);
FileOutputFormat.setOutputPath(job, out); // reducer全局排序
if(arg0[2]!=null&&"true".equals(arg0[2])){
job.setPartitionerClass(TotalOrderPartitioner.class);
// InputSampler.Sampler<Text, Text> sampler = new
// InputSampler.RandomSampler<Text, Text>(0.1,20,3);
// InputSampler.writePartitionFile(job, sampler); MyInputSampler.Sampler<Text, Text> sampler = new
MyInputSampler.RandomSampler<Text, Text>(0.1,20,3);
MyInputSampler.writePartitionFile(job, sampler); String partitionFile = TotalOrderPartitioner.getPartitionFile(getConf());
URI partitionUri= new URI(partitionFile+"#"+TotalOrderPartitioner.DEFAULT_PATH);
job.addCacheArchive(partitionUri);
} return job.waitForCompletion(true)?0:-1;
} public static void main(String[] args) throws Exception {
ToolRunner.run(new Configuration(), new PartitionerDriver(),args); // String[] arg = new String[]{
// "hdfs://node33:8020/user/root/partition",
// "hdfs://node33:8020/user/Administrator/partition",
// "true"
// };
// ToolRunner.run(Utils.getConf(), new PartitionerDriver(),arg);
}
}

PartitionerMapper类:

package fz.totalorder.partitioner;

import java.io.IOException;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; public class PartitionerMapper extends Mapper<LongWritable,Text,Text ,Text>{ private Text newKey= new Text();
private Text newValue = new Text();
public void map(LongWritable key, Text value, Context cxt) throws IOException,InterruptedException{
String [] line =value.toString().split("_");
if(line.length!=2){
return ;
}
newKey.set(line[1]);
newValue.set(line[0]);
cxt.write(newKey, newValue);
}
}

这里能够看到Mapper的输出和输出是不一样的。所以我们须要自己定义InputSampler类,加入经过处理的key。

其详细代码为:

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.apache.hadoop.mapreduce.lib.partition; import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.RawComparator;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.mapreduce.InputFormat;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.TaskAttemptID;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.task.TaskAttemptContextImpl;
import org.apache.hadoop.util.ReflectionUtils;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner; /**
* Utility for collecting samples and writing a partition file for
* {@link TotalOrderPartitioner}.
*/
@InterfaceAudience.Public
@InterfaceStability.Stable
public class MyInputSampler<K,V> extends Configured implements Tool { private static final Log LOG = LogFactory.getLog(MyInputSampler.class); static int printUsage() {
System.out.println("sampler -r <reduces>\n" +
" [-inFormat <input format class>]\n" +
" [-keyClass <map input & output key class>]\n" +
" [-splitRandom <double pcnt> <numSamples> <maxsplits> | " +
" // Sample from random splits at random (general)\n" +
" -splitSample <numSamples> <maxsplits> | " +
" // Sample from first records in splits (random data)\n"+
" -splitInterval <double pcnt> <maxsplits>]" +
" // Sample from splits at intervals (sorted data)");
System.out.println("Default sampler: -splitRandom 0.1 10000 10");
ToolRunner.printGenericCommandUsage(System.out);
return -1;
} public MyInputSampler(Configuration conf) {
setConf(conf);
} /**
* Interface to sample using an
* {@link org.apache.hadoop.mapreduce.InputFormat}.
*/
public interface Sampler<K,V> {
/**
* For a given job, collect and return a subset of the keys from the
* input data.
*/
K[] getSample(InputFormat<K,V> inf, Job job)
throws IOException, InterruptedException;
} /**
* Samples the first n records from s splits.
* Inexpensive way to sample random data.
*/
public static class SplitSampler<K,V> implements Sampler<K,V> { protected final int numSamples;
protected final int maxSplitsSampled; /**
* Create a SplitSampler sampling <em>all</em> splits.
* Takes the first numSamples / numSplits records from each split.
* @param numSamples Total number of samples to obtain from all selected
* splits.
*/
public SplitSampler(int numSamples) {
this(numSamples, Integer.MAX_VALUE);
} /**
* Create a new SplitSampler.
* @param numSamples Total number of samples to obtain from all selected
* splits.
* @param maxSplitsSampled The maximum number of splits to examine.
*/
public SplitSampler(int numSamples, int maxSplitsSampled) {
this.numSamples = numSamples;
this.maxSplitsSampled = maxSplitsSampled;
} /**
* From each split sampled, take the first numSamples / numSplits records.
*/
@SuppressWarnings("unchecked") // ArrayList::toArray doesn't preserve type
public K[] getSample(InputFormat<K,V> inf, Job job)
throws IOException, InterruptedException {
List<InputSplit> splits = inf.getSplits(job);
ArrayList<K> samples = new ArrayList<K>(numSamples);
int splitsToSample = Math.min(maxSplitsSampled, splits.size());
int samplesPerSplit = numSamples / splitsToSample;
long records = 0;
for (int i = 0; i < splitsToSample; ++i) {
TaskAttemptContext samplingContext = new TaskAttemptContextImpl(
job.getConfiguration(), new TaskAttemptID());
RecordReader<K,V> reader = inf.createRecordReader(
splits.get(i), samplingContext);
reader.initialize(splits.get(i), samplingContext);
while (reader.nextKeyValue()) {
samples.add(ReflectionUtils.copy(job.getConfiguration(),
reader.getCurrentKey(), null));
++records;
if ((i+1) * samplesPerSplit <= records) {
break;
}
}
reader.close();
}
return (K[])samples.toArray();
}
} /**
* Sample from random points in the input.
* General-purpose sampler. Takes numSamples / maxSplitsSampled inputs from
* each split.
*/
public static class RandomSampler<K,V> implements Sampler<K,V> {
protected double freq;
protected final int numSamples;
protected final int maxSplitsSampled; /**
* Create a new RandomSampler sampling <em>all</em> splits.
* This will read every split at the client, which is very expensive.
* @param freq Probability with which a key will be chosen.
* @param numSamples Total number of samples to obtain from all selected
* splits.
*/
public RandomSampler(double freq, int numSamples) {
this(freq, numSamples, Integer.MAX_VALUE);
} /**
* Create a new RandomSampler.
* @param freq Probability with which a key will be chosen.
* @param numSamples Total number of samples to obtain from all selected
* splits.
* @param maxSplitsSampled The maximum number of splits to examine.
*/
public RandomSampler(double freq, int numSamples, int maxSplitsSampled) {
this.freq = freq;
this.numSamples = numSamples;
this.maxSplitsSampled = maxSplitsSampled;
} /**
* Randomize the split order, then take the specified number of keys from
* each split sampled, where each key is selected with the specified
* probability and possibly replaced by a subsequently selected key when
* the quota of keys from that split is satisfied.
*/
@SuppressWarnings("unchecked") // ArrayList::toArray doesn't preserve type
public K[] getSample(InputFormat<K,V> inf, Job job)
throws IOException, InterruptedException {
List<InputSplit> splits = inf.getSplits(job);
ArrayList<K> samples = new ArrayList<K>(numSamples);
int splitsToSample = Math.min(maxSplitsSampled, splits.size()); Random r = new Random();
long seed = r.nextLong();
r.setSeed(seed);
LOG.debug("seed: " + seed);
// shuffle splits
for (int i = 0; i < splits.size(); ++i) {
InputSplit tmp = splits.get(i);
int j = r.nextInt(splits.size());
splits.set(i, splits.get(j));
splits.set(j, tmp);
}
// our target rate is in terms of the maximum number of sample splits,
// but we accept the possibility of sampling additional splits to hit
// the target sample keyset
for (int i = 0; i < splitsToSample ||
(i < splits.size() && samples.size() < numSamples); ++i) {
TaskAttemptContext samplingContext = new TaskAttemptContextImpl(
job.getConfiguration(), new TaskAttemptID());
RecordReader<K,V> reader = inf.createRecordReader(
splits.get(i), samplingContext);
reader.initialize(splits.get(i), samplingContext);
while (reader.nextKeyValue()) {
if (r.nextDouble() <= freq) {
if (samples.size() < numSamples) {
samples.add(ReflectionUtils.copy(job.getConfiguration(),
getFixedKey(reader), null)); // add here
} else {
// When exceeding the maximum number of samples, replace a
// random element with this one, then adjust the frequency
// to reflect the possibility of existing elements being
// pushed out
int ind = r.nextInt(numSamples);
if (ind != numSamples) {
samples.set(ind, ReflectionUtils.copy(job.getConfiguration(),
getFixedKey(reader), null)); // add here
}
freq *= (numSamples - 1) / (double) numSamples;
}
}
}
reader.close();
}
return (K[])samples.toArray();
}
/**
* use new key
* @param reader
* @return
*/
private K getFixedKey(RecordReader<K, V> reader) {
K newKey =null;
String[] line;
try {
line = reader.getCurrentValue().toString().split("_");
Text newTmpKey = new Text(line[1]);
newKey =(K) newTmpKey;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} return newKey;
}
} /**
* Sample from s splits at regular intervals.
* Useful for sorted data.
*/
public static class IntervalSampler<K,V> implements Sampler<K,V> {
protected final double freq;
protected final int maxSplitsSampled; /**
* Create a new IntervalSampler sampling <em>all</em> splits.
* @param freq The frequency with which records will be emitted.
*/
public IntervalSampler(double freq) {
this(freq, Integer.MAX_VALUE);
} /**
* Create a new IntervalSampler.
* @param freq The frequency with which records will be emitted.
* @param maxSplitsSampled The maximum number of splits to examine.
* @see #getSample
*/
public IntervalSampler(double freq, int maxSplitsSampled) {
this.freq = freq;
this.maxSplitsSampled = maxSplitsSampled;
} /**
* For each split sampled, emit when the ratio of the number of records
* retained to the total record count is less than the specified
* frequency.
*/
@SuppressWarnings("unchecked") // ArrayList::toArray doesn't preserve type
public K[] getSample(InputFormat<K,V> inf, Job job)
throws IOException, InterruptedException {
List<InputSplit> splits = inf.getSplits(job);
ArrayList<K> samples = new ArrayList<K>();
int splitsToSample = Math.min(maxSplitsSampled, splits.size());
long records = 0;
long kept = 0;
for (int i = 0; i < splitsToSample; ++i) {
TaskAttemptContext samplingContext = new TaskAttemptContextImpl(
job.getConfiguration(), new TaskAttemptID());
RecordReader<K,V> reader = inf.createRecordReader(
splits.get(i), samplingContext);
reader.initialize(splits.get(i), samplingContext);
while (reader.nextKeyValue()) {
++records;
if ((double) kept / records < freq) {
samples.add(ReflectionUtils.copy(job.getConfiguration(),
reader.getCurrentKey(), null));
++kept;
}
}
reader.close();
}
return (K[])samples.toArray();
}
} /**
* Write a partition file for the given job, using the Sampler provided.
* Queries the sampler for a sample keyset, sorts by the output key
* comparator, selects the keys for each rank, and writes to the destination
* returned from {@link TotalOrderPartitioner#getPartitionFile}.
*/
@SuppressWarnings("unchecked") // getInputFormat, getOutputKeyComparator
public static <K,V> void writePartitionFile(Job job, Sampler<K,V> sampler)
throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = job.getConfiguration();
final InputFormat inf =
ReflectionUtils.newInstance(job.getInputFormatClass(), conf);
int numPartitions = job.getNumReduceTasks();
K[] samples = (K[])sampler.getSample(inf, job);
LOG.info("Using " + samples.length + " samples");
RawComparator<K> comparator =
(RawComparator<K>) job.getSortComparator();
Arrays.sort(samples, comparator);
Path dst = new Path(TotalOrderPartitioner.getPartitionFile(conf));
FileSystem fs = dst.getFileSystem(conf);
if (fs.exists(dst)) {
fs.delete(dst, false);
}
SequenceFile.Writer writer = SequenceFile.createWriter(fs,
conf, dst, job.getMapOutputKeyClass(), NullWritable.class);
NullWritable nullValue = NullWritable.get();
float stepSize = samples.length / (float) numPartitions;
int last = -1;
for(int i = 1; i < numPartitions; ++i) {
int k = Math.round(stepSize * i);
while (last >= k && comparator.compare(samples[last], samples[k]) == 0) {
++k;
}
writer.append(samples[k], nullValue);
last = k;
}
writer.close();
} /**
* Driver for MyInputSampler from the command line.
* Configures a JobConf instance and calls {@link #writePartitionFile}.
*/
public int run(String[] args) throws Exception {
Job job = new Job(getConf());
ArrayList<String> otherArgs = new ArrayList<String>();
Sampler<K,V> sampler = null;
for(int i=0; i < args.length; ++i) {
try {
if ("-r".equals(args[i])) {
job.setNumReduceTasks(Integer.parseInt(args[++i]));
} else if ("-inFormat".equals(args[i])) {
job.setInputFormatClass(
Class.forName(args[++i]).asSubclass(InputFormat.class));
} else if ("-keyClass".equals(args[i])) {
job.setMapOutputKeyClass(
Class.forName(args[++i]).asSubclass(WritableComparable.class));
} else if ("-splitSample".equals(args[i])) {
int numSamples = Integer.parseInt(args[++i]);
int maxSplits = Integer.parseInt(args[++i]);
if (0 >= maxSplits) maxSplits = Integer.MAX_VALUE;
sampler = new SplitSampler<K,V>(numSamples, maxSplits);
} else if ("-splitRandom".equals(args[i])) {
double pcnt = Double.parseDouble(args[++i]);
int numSamples = Integer.parseInt(args[++i]);
int maxSplits = Integer.parseInt(args[++i]);
if (0 >= maxSplits) maxSplits = Integer.MAX_VALUE;
sampler = new RandomSampler<K,V>(pcnt, numSamples, maxSplits);
} else if ("-splitInterval".equals(args[i])) {
double pcnt = Double.parseDouble(args[++i]);
int maxSplits = Integer.parseInt(args[++i]);
if (0 >= maxSplits) maxSplits = Integer.MAX_VALUE;
sampler = new IntervalSampler<K,V>(pcnt, maxSplits);
} else {
otherArgs.add(args[i]);
}
} catch (NumberFormatException except) {
System.out.println("ERROR: Integer expected instead of " + args[i]);
return printUsage();
} catch (ArrayIndexOutOfBoundsException except) {
System.out.println("ERROR: Required parameter missing from " +
args[i-1]);
return printUsage();
}
}
if (job.getNumReduceTasks() <= 1) {
System.err.println("Sampler requires more than one reducer");
return printUsage();
}
if (otherArgs.size() < 2) {
System.out.println("ERROR: Wrong number of parameters: ");
return printUsage();
}
if (null == sampler) {
sampler = new RandomSampler<K,V>(0.1, 10000, 10);
} Path outf = new Path(otherArgs.remove(otherArgs.size() - 1));
TotalOrderPartitioner.setPartitionFile(getConf(), outf);
for (String s : otherArgs) {
FileInputFormat.addInputPath(job, new Path(s));
}
MyInputSampler.<K,V>writePartitionFile(job, sampler); return 0;
} public static void main(String[] args) throws Exception {
MyInputSampler<?,? > sampler = new MyInputSampler(new Configuration());
int res = ToolRunner.run(sampler, args);
System.exit(res);
}
}

其主要代码是:

/**
* use new key
* @param reader
* @return
*/
private K getFixedKey(RecordReader<K, V> reader) {
K newKey =null;
String[] line;
try {
line = reader.getCurrentValue().toString().split("_");
Text newTmpKey = new Text(line[1]);
newKey =(K) newTmpKey;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} return newKey;
}
}

事实上就是把Mapper的逻辑拿过来而已。

查看输出:

首先不使用全局分类的代码:

aaarticlea/png;base64,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" alt="" />aaarticlea/png;base64,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" alt="" />

能够看到文件之间是没有排序的;

全局排序的文件输出为:

aaarticlea/png;base64,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" alt="" />

aaarticlea/png;base64,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" alt="" />

能够看到文件之间是有全局排序的。

总结:使用Hadoop默认提供的全局排序功能有限,能够自己定义全局排序的类,可是这样针对每一个MR可能都须要提供一个自己定义的类。这样也比較麻烦。

整体来说。全局排序的应用场景比較少见。

分享,成长,快乐

转载请注明blog地址:http://blog.csdn.net/fansy1990

版权声明:本文博主原创文章。博客,未经同意不得转载。

hadoop编程技巧(4)---总体情况key按类别搜索TotalOrderPartitioner的更多相关文章

  1. hadoop编程技巧(6)---处理大量的小型数据文件CombineFileInputFormat申请书

    代码测试环境:Hadoop2.4 应用场景:当需要处理非常多的小数据文件,这种技术的目的,可以被应用到实现高效的数据处理. 原理:申请书CombineFileInputFormat,能够进行切片合并的 ...

  2. hadoop编程技巧(8)---Unit Testing (单元测试)

    所需的环境: Hadoop相关jar包裹(下载版本的官方网站上可以): 下载junit包裹(新以及). 下载mockito包裹: 下载mrunit包裹: 下载powermock-mockito包裹: ...

  3. hadoop编程技巧(3)---定义自己的区划类别Partitioner

    Hadoop代码测试环境:Hadoop2.4 原则:在Hadoop的MapReduce过程.Mapper阅读过程完成后数据.它将数据发送到Partitioner.由Partitioner每个记录应当采 ...

  4. hadoop编程:分析CSDN注冊邮箱分布情况

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jdh99/article/details/37565825 hadoop编程:分析CSDN注冊邮箱分 ...

  5. 18个Python高效编程技巧,Mark!

    初识Python语言,觉得python满足了我上学时候对编程语言的所有要求.python语言的高效编程技巧让我们这些大学曾经苦逼学了四年c或者c++的人,兴奋的不行不行的,终于解脱了.高级语言,如果做 ...

  6. 大数据学习笔记——Hadoop编程实战之Mapreduce

    Hadoop编程实战——Mapreduce基本功能实现 此篇博客承接上一篇总结的HDFS编程实战,将会详细地对mapreduce的各种数据分析功能进行一个整理,由于实际工作中并不会过多地涉及原理,因此 ...

  7. Python 高效编程技巧实战(2-1)如何在列表,字典, 集合中根据条件筛选数据

    Python 高效编程技巧实战(2-1)如何在列表,字典, 集合中根据条件筛选数据 学习目标 1.学会使用 filter 借助 Lambda 表达式过滤列表.集合.元组中的元素: 2.学会使用列表解析 ...

  8. js异步编程技巧一

    异步回调是js的一大特性,理解好用好这个特性可以写出很高质量的代码.分享一些实际用的一些异步编程技巧. 1.我们有些应用环境是需要等待两个http请求或IO操作返回后进行后续逻辑的处理.而这种情况使用 ...

  9. java命名规范和编程技巧

    一个好的java程序首先命名要规范. 命名规范 定义这个规范的目的是让项目中所有的文档都看起来像一个人写的,增加可读性,方便维护等作用 Package 的命名 Package 的名字应该都是由一个小写 ...

随机推荐

  1. 2016最新Java笔试题集锦

    更新时间:2015-08-13         来源:网络         投诉删除 [看准网(Kanzhun.com)]笔试题目频道小编搜集的范文“2016最新Java笔试题集锦”,供大家阅读参考, ...

  2. jQuery Mobile 控制 select 的显示隐藏 display none

    如需要动态控制下拉选择菜单select的显隐,一般考虑使用display:none这个方法. 但在jQueryMobile中的select添加自定义的css,display:none 是无效的. 解决 ...

  3. matlab中元胞数组(cell)转换为矩阵

    matlab中元胞数组(cell)转换为矩阵. cell转换为矩阵函数为:cell2mat(c),其中c为待转换的元胞数组: 转化之后的矩阵可能不满足我们对矩阵维数的要求,那么也许还需要下面两个函数: ...

  4. [topcoder]BinarySearchable

    http://community.topcoder.com/stat?c=problem_statement&pm=5869&rd=8078 这道题有点意思,思考理解后,就是找数组中的 ...

  5. 初次踏上GUI编程之路(有点意思,详细介绍了菜鸟的学习之路)

    初次踏上GUI编程之路 —— 我的Qt学习方法及对Qt认识的不断转变 -> 开始接触GUI与开始接触Qt: 话说,我第一次看见“Qt”这一个名词,好像是在CSDN网站的主页上吧,因为CSDN好像 ...

  6. android工程混淆和反编译

    一.工程文件的混淆 混淆文件下载:http://download.csdn.net/detail/lxq_xsyu/6328751 1.在根目录下添加progard.cfg文件 2.打开project ...

  7. phpMyAdmin 完整路径泄露漏洞3

    漏洞名称: phpMyAdmin 完整路径泄露漏洞 CNNVD编号: CNNVD-201307-652 发布时间: 2013-08-09 更新时间: 2013-08-09 危害等级: 中危   漏洞类 ...

  8. 数据结构(并查集||树链剖分):HEOI 2016 tree

    [注意事项] 为了体现增强版,题目限制和数据范围有所增强: 时间限制:1.5s 内存限制:128MB 对于15% 的数据,1<=N,Q<=1000. 对于35% 的数据,1<=N,Q ...

  9. 汇编学习笔记(14)BIOS对键盘输入的处理

    字符的处理 键盘输入的字符一般由int9中断例程从60h端口中读取,并存放在键盘缓冲区中,由int16h例程从键盘缓冲区中读取相应字符,CPU对键盘输入a.shift_a的处理过程如下 1.一开始没有 ...

  10. C++之友元函数

    1.为什么要引入友元函数:在实现类之间数据共享时,减少系统开销,提高效率 具体来说:为了使其他类的成员函数直接访问该类的私有变量 即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同 ...