1.JobTracker能否决定给当前的TaskTracker节点分配一个Job的具体的哪一个任务?
2.什么是map本地任务?
3.nonRunningMapCache的作用是什么?
4.从TaskTracker节点上分配挂载的本地任务时,如果以前发生过该TaskTracker节点执行某一Map任务失败了的情况,则应将该Map任务该如何处理?

 
分享到: 

QQ好友和群
腾讯微博
QQ空间

收藏
转播
分享
淘帖
支持
反对

欢迎加入about云群371358502、39327136,云计算爱好者群,亦可关注about云腾讯认证空间||关注本站微信
 

回复

使用道具
举报

   

681

主题

1201

帖子

6384

积分

超级版主

积分
6384


沙发

 

 楼主|
发表于 2014-4-6 23:51:53
|
只看该作者
 


所周知,JobTracker节点使用配置的任务调度器TaskScheduler来为某一个具体的TaskTracker节点分配任务,同时这个任务调
度器只能决定给该TaskTracker节点分配哪一个Job或者那些Job的任务以及分配多少个任务,但是它却不能决定给当前的TaskTracker
节点分配一个Job的具体的哪一个任务。

另外,针对一个具体的TaskTracker节点而言,任何一个作业都可以判断它的那些Map任务相对于该TaskTracker节点来说属于本地任务,那些Map任务是属于非本地任务的,当然,对于Reduce任务来说,是没有本地任务与非本地任务这一说法的。

因此,具体来讲就是,当任务调度器决定为一个TaskTracker节点分配一个Job的本地任务时,它会调用该JobInProgress对象的
obtainNewLocalMapTask()方法,分配一个非本地任务时,它会调用对应的obtainNewNonLocalMapTask()方
法,那么以这个TaskTracker节点在集群中的物理位置为参考,这个Job可能有多个本地任务和多个非本地任务,至于为该TaskTracker节
点分配哪一个本地或者非本地任务就由JobInProgress来决定了;当任务调度器为TaskTracker节点分配一个Job的Reduce任务
时,就会调用该Job对应的JobInProgress对象的obtainNewReduceTask()方法。至于JobInProgress对象究竟
是如何分配一个本地或非本地Map任务、Reduce任务的,那将是本文接下来要详细讲述的重点了。

1.分配作业的Map任务


 
   作业的Map任务之所以有本地和非本地之分,主要是因为该Map任务的输入数据和执行该Map任务的TaskTracker节点在集群中的位置有可
能同。本地与非本地Map任务是相对于执行或将要执行该任务的TaskTracker节点来说的,当任务调度器决定为一个TaskTracker节点分配
某一个Job的一个本地Map任务时,它(JobInProgress)会查找这个Job中的那些Map任务的输入数据合该TaskTracker节点在
同一台PC或机架上,那么这些Map任务对于TaskTracker节点来说就是本地任务了。这里要值得一提的是,在作业初始化的时候,就为每一个Map
任务做了一个本地化的预分配工作,即根据Map任务的输入数据的物理位置,将该Map任务挂载到对应的物理节点上,该过程的源代码为:

  1. private Map<Node, List<TaskInProgress>> createCache(JobClient.RawSplit[] splits, int maxLevel) {
  2. Map<Node, List<TaskInProgress>> cache = new IdentityHashMap<Node, List<TaskInProgress>>(maxLevel);
  3. for (int i = 0; i < splits.length; i++) {
  4. String[] splitLocations = splits[i].getLocations();//获取该数据切片坐在的物理位置(多个副本)
  5. if (splitLocations.length == 0) {
  6. nonLocalMaps.add(maps[i]);
  7. continue;
  8. }
  9. //针对每一个副本的物理位置
  10. for(String host: splitLocations) {
  11. //解析副本在集群中的哪一个节点上
  12. Node node = jobtracker.resolveAndAddToTopology(host);
  13. LOG.info("tip:" + maps[i].getTIPId() + " has split on node:" + node);
  14. for (int j = 0; j < maxLevel; j++) {
  15. List<TaskInProgress> hostMaps = cache.get(node);
  16. if (hostMaps == null) {
  17. hostMaps = new ArrayList<TaskInProgress>();
  18. cache.put(node, hostMaps);
  19. hostMaps.add(maps[i]);//将Map任务挂载到该节点上
  20. }
  21. //去重,避免一个节点挂载了两个相同的Map任务
  22. if (hostMaps.get(hostMaps.size() - 1) != maps[i]) {
  23. hostMaps.add(maps[i]);
  24. }
  25. node = node.getParent();//获取节点的父节点(由于maxLevel的值是2,所以父节点就是rack节点)
  26. }
  27. }
  28. }
  29. return cache;
  30. }

复制代码

通过这样的一个预处理过程,最终Node与Map任务之间的映射关系被保存在它的一个属性nonRunningMapCache中了。当
JobInProgress为一个TaskTracker节点分配一个本地Map任务时,它可以只需要解析该TaskTracker节点在集群中的哪一个
节点node上,根据该node就可以从nonRunningMapCache中获取一个Map任务,该Map任务相对于当前这个TaskTracker
来说就是本地任务了;当JobInProgress为一个TaskTracker节点分配一个非本地Map任务时,它可以获取集群中所有的rack节点
(除它自己所在的rack外),通过这些rack节点node,就可以从nonRunningMapCache中获取一个Map任务,该Map任务相对于
当前这个TaskTracker来说就是非本地任务了。

根据上面的源代码可以看出,所谓的本地任务之分就是由maxLevel来确定的,即Map任务的输入数据与TaskTracker节点在集群中的物理距
离,在目前的版本中(Hadoop-0.20.2.0),maxLevel的默认值是2,也可由JobTracker节点的配置文件来设置,对应的配置项
为:mapred.task.cache.levels。另外,从上面的源代码可以看出,这个预处理过程也明确地定义了非本地Map任务,即map操作的
输入数据的位置为null的Map任务,这并不代表说该Map任务没有输入数据。因为,Hadoop为用户提供了自定义数据切片的API(用户自己实现
InputSplit),这里的RawSplit并没有直接保存map操作所需的输入数据的位置信息,而是对真正的InputSplit进行了封装,这告
诉我们两个很重要的情况,

一:用户在自定义Map任务的InputSplit时,应考虑这个Map任务是否可以作为某些TaskTracker节点的本地任务(比如某一个Map任务的输入数据在跨越多个节点,那么这个Map任务永远也不可能是本地任务);

二:Map任务的InputSplit实现可以为map操作带入少量的输入数据(例如,某一个Map任务需要两个输入数据,一个数据很大,另一个数据很
小,只有几百或上千Bytes,那么,用户就可以自定义一个InputSplit来保存这个小数据,很明显,用HDFS保存这样小的数据根本不划算)。这
个非本地Map任务保存在nonLocalMaps属性中。

1.1 分配本地Map任务

JobInProgress给某一个TaskTracker节点分配一个本地Map任务的操作比较的简单,不过,这其中有一个异常情况,就是当这个
TaskTracker节点无法被解析成集群中的一个Node时,那么,本次的本地Map任务分配会被当做一次分配非本地Map任务来操作。这个过程的源
代码如下:

  1. public synchronized Task obtainNewLocalMapTask(TaskTrackerStatus tts,int clusterSize, int numUniqueHosts) throws IOException {
  2. if (!tasksInited.get()) {
  3. return null;
  4. }
  5. //为当前的计算节点获取一个本地map任务
  6. int target = findNewMapTask(tts, clusterSize, numUniqueHosts, maxLevel, status.mapProgress());
  7. if (target == -1) {
  8. return null;
  9. }
  10. Task result = maps[target].getTaskToRun(tts.getTrackerName());
  11. if (result != null) {
  12. addRunningTaskToTIP(maps[target], result.getTaskID(), tts, true);
  13. }
  14. return result;
  15. }

复制代码

  1. /**
  2. * 为当前的计算节点从作业的map任务集中选取一个合适的任务;
  3. * 参数maxCacheLevel决定了当前分配的是本地任务还是非本地任务
  4. */
  5. private synchronized int findNewMapTask(final TaskTrackerStatus
    tts, final int clusterSize, final int numUniqueHosts, final int
    maxCacheLevel, final double avgProgress) {
  6. ...
  7. Node node = jobtracker.getNode(tts.getHost());  //根据当前计算节点的主机/IP来获取其在集群拓扑结构中对应的位置节点
  8. //
  9. // I) Non-running TIP :
  10. // 1. check from local node to the root [bottom up cache lookup]
  11. //    i.e if the cache is available and the host has been resolved
  12. //    (node!=null)
  13. if (node != null) {
  14. Node key = node;    //当前待分配的map任务的输入数据所在的节点
  15. int level = 0;
  16. // maxCacheLevel might be greater than this.maxLevel if findNewMapTask is
  17. // called to schedule any task (local, rack-local, off-switch or speculative)
  18. // tasks or it might be NON_LOCAL_CACHE_LEVEL (i.e. -1) if findNewMapTask is
  19. //  (i.e. -1) if findNewMapTask is to only schedule off-switch/speculative
  20. // tasks
  21. int maxLevelToSchedule = Math.min(maxCacheLevel, maxLevel);
  22. for (level = 0;level < maxLevelToSchedule; ++level) {
  23. List <TaskInProgress> cacheForLevel = nonRunningMapCache.get(key);    //获取节点key上还未分配的map任务
  24. if (cacheForLevel != null) {
  25. tip = findTaskFromList(cacheForLevel, tts, numUniqueHosts,level == 0);   //从一个map任务集中为当前的计算节点找到一个合适的任务
  26. if (tip != null) {
  27. // Add to running cache
  28. scheduleMap(tip);
  29. // remove the cache if its empty
  30. if (cacheForLevel.size() == 0) {
  31. nonRunningMapCache.remove(key);
  32. }
  33. return tip.getIdWithinJob();
  34. }
  35. }
  36. key = key.getParent();
  37. }
  38. // Check if we need to only schedule a local task (node-local/rack-local)
  39. if (level == maxCacheLevel) {
  40. return -1;
  41. }
  42. }
  43. ...
  44. }

复制代码

还有一个值得注意的问题就是,如果该TaskTracker节点所在的Node上有Map任务时,当从该Node上分配挂载的本地任务时,如果以前发生过
该TaskTracker节点执行某一Map任务失败了的情况,则应将该Map任务从Node上删除,同时,对于无法执行或正在执行的Map任务也应该从
Node上删除,对应的源码为:

  1. private synchronized
    TaskInProgress findTaskFromList(Collection<TaskInProgress> tips,
    TaskTrackerStatus ttStatus, int numUniqueHosts, boolean removeFailedTip)
    {
  2. Iterator<TaskInProgress> iter = tips.iterator();
  3. while (iter.hasNext()) {
  4. TaskInProgress tip = iter.next();
  5. // Select a tip if
  6. //   1. runnable   : still needs to be run and is not completed
  7. //   2. ~running   : no other node is running it
  8. //   3. earlier attempt failed : has not failed on this host
  9. //                               and has failed on all the other hosts
  10. // A TIP is removed from the list if
  11. // (1) this tip is scheduled
  12. // (2) if the passed list is a level 0 (host) cache
  13. // (3) when the TIP is non-schedulable (running, killed, complete)
  14. if (tip.isRunnable() && !tip.isRunning()) {
  15. // check if the tip has failed on this host
  16. if (!tip.hasFailedOnMachine(ttStatus.getHost()) || tip.getNumberOfFailedMachines() >= numUniqueHosts) {
  17. // check if the tip has failed on all the nodes
  18. iter.remove();
  19. return tip;
  20. }
  21. else if (removeFailedTip) {
  22. // the case where we want to remove a failed tip from the host cache
  23. // point#3 in the TIP removal logic above
  24. iter.remove();
  25. }
  26. } else {
  27. // see point#3 in the comment above for TIP removal logic
  28. iter.remove();
  29. }
  30. }
  31. return null;
  32. }

复制代码

1.2 分配非本地Map任务

JobInProgress为某一个TaskTracker节点分配一个非本地Map任务相对于分配一个本地任务来说要复杂的多,它首先会先从
nonRunningMapCache中选择一个非本地任务,如果没有找到再从nonLocalMaps中选择一个任务,如果还没有找到,则判断这个作业
是否设置了hasSpeculativeMaps,如果没有设置,则不再为该TaskTracker节点分配非本地Map任务了;如果设置了,则从正在被
其它TaskTracker节点执行的本地或非本地Map任务中选一个,不过这是有优先顺序的,首先从正在运行的runningMapCache中寻找一
个本地Map任务,如果没有找到再从runningMapCache中寻找一个非本地Map任务,最后再从nonLocalRunningMaps中寻找
一个非本地Map任务,此时还没有找到的话,就不再为该TaskTracker节点分配Map任务了。这个过程的源代码如下:

  1. public synchronized Task obtainNewNonLocalMapTask(TaskTrackerStatus tts, int clusterSize, int numUniqueHosts)
  2. throws IOException {
  3. if (!tasksInited.get()) {
  4. return null;
  5. }
  6. int target = findNewMapTask(tts, clusterSize, numUniqueHosts, NON_LOCAL_CACHE_LEVEL, status.mapProgress());
  7. if (target == -1) {
  8. return null;
  9. }
  10. Task result = maps[target].getTaskToRun(tts.getTrackerName());
  11. if (result != null) {
  12. addRunningTaskToTIP(maps[target], result.getTaskID(), tts, true);
  13. }
  14. return result;
  15. }
  16. private synchronized int findNewMapTask(final TaskTrackerStatus
    tts, final int clusterSize, final int numUniqueHosts, final int
    maxCacheLevel, final double avgProgress) {
  17. ...
  18. Collection<Node> nodesAtMaxLevel = jobtracker.getNodesAtMaxLevel();
  19. // get the node parent at max level
  20. Node nodeParentAtMaxLevel = (node == null) ? null : JobTracker.getParentNode(node, maxLevel - 1);
  21. for (Node parent : nodesAtMaxLevel) {
  22. // skip the parent that has already been scanned
  23. if (parent == nodeParentAtMaxLevel) {
  24. continue;
  25. }
  26. List<TaskInProgress> cache = nonRunningMapCache.get(parent);
  27. if (cache != null) {
  28. tip = findTaskFromList(cache, tts, numUniqueHosts, false);
  29. if (tip != null) {
  30. // Add to the running cache
  31. scheduleMap(tip);
  32. // remove the cache if empty
  33. if (cache.size() == 0) {
  34. nonRunningMapCache.remove(parent);
  35. }
  36. LOG.info("Choosing a non-local task " + tip.getTIPId());
  37. return tip.getIdWithinJob();
  38. }
  39. }
  40. }
  41. // 3. Search non-local tips for a new task
  42. tip = findTaskFromList(nonLocalMaps, tts, numUniqueHosts, false);
  43. if (tip != null) {
  44. // Add to the running list
  45. scheduleMap(tip);
  46. LOG.info("Choosing a non-local task " + tip.getTIPId());
  47. return tip.getIdWithinJob();
  48. }
  49. // II) Running TIP :
  50. if (hasSpeculativeMaps) {
  51. long currentTime = System.currentTimeMillis();
  52. // 1. Check bottom up for speculative tasks from the running cache
  53. if (node != null) {
  54. Node key = node;
  55. for (int level = 0; level < maxLevel; ++level) {
  56. Set<TaskInProgress> cacheForLevel = runningMapCache.get(key);
  57. if (cacheForLevel != null) {
  58. tip = findSpeculativeTask(cacheForLevel, tts, avgProgress, currentTime, level == 0);
  59. if (tip != null) {
  60. if (cacheForLevel.size() == 0) {
  61. runningMapCache.remove(key);
  62. }
  63. return tip.getIdWithinJob();
  64. }
  65. }
  66. key = key.getParent();
  67. }
  68. }
  69. // 2. Check breadth-wise for speculative tasks
  70. for (Node parent : nodesAtMaxLevel) {
  71. // ignore the parent which is already scanned
  72. if (parent == nodeParentAtMaxLevel) {
  73. continue;
  74. }
  75. Set<TaskInProgress> cache = runningMapCache.get(parent);
  76. if (cache != null) {
  77. tip = findSpeculativeTask(cache, tts, avgProgress, currentTime, false);
  78. if (tip != null) {
  79. // remove empty cache entries
  80. if (cache.size() == 0) {
  81. runningMapCache.remove(parent);
  82. }
  83. LOG.info("Choosing a non-local task " + tip.getTIPId() + " for speculation");
  84. return tip.getIdWithinJob();
  85. }
  86. }
  87. }
  88. // 3. Check non-local tips for speculation
  89. tip = findSpeculativeTask(nonLocalRunningMaps, tts, avgProgress, currentTime, false);
  90. if (tip != null) {
  91. LOG.info("Choosing a non-local task " + tip.getTIPId() + " for speculation");
  92. return tip.getIdWithinJob();
  93. }
  94. }
  95. return -1;
  96. }

复制代码

2. 分配作业的Reduce任务


      由于
Reduce任务的输入数据来源于该作业所有的Map任务的输出,而执行Map任务的TaskTracker节点将map的输出保存在自己本地,所以
Reduce任务的输入数据在绝大多数情况下不可能都在某一个TaskTracker节点上,因此对于任何一个TaskTracker节点来说没有本地和
非本地的Reduce任务之分。JobInProgress为某一个TaskTracker节点分配一个Reduce任务的操作就相当的简单了,这个过程
类似于分配非本地Map任务。

它首先直接从nonRunningReduces中寻找一个任务,如果没有找到则在看这个作业设置了hasSpeculativeReduces没有,若
没有则不分配了;若设置了,则从runningReduces中寻找一个正在被其它TaskTracker节点执行的Reduce任务分配给该
TaskTracker节点。该过程对应的源代码如下:

  1. public synchronized Task obtainNewReduceTask(TaskTrackerStatus tts, int clusterSize, int numUniqueHosts) throws IOException {
  2. if (status.getRunState() != JobStatus.RUNNING) {
  3. return null;
  4. }
  5. // Ensure we have sufficient map outputs ready to shuffle before
  6. // scheduling reduces
  7. if (!scheduleReduces()) {
  8. return null;
  9. }
  10. int  target = findNewReduceTask(tts, clusterSize, numUniqueHosts, status.reduceProgress());
  11. if (target == -1) {
  12. return null;
  13. }
  14. Task result = reduces[target].getTaskToRun(tts.getTrackerName());
  15. if (result != null) {
  16. addRunningTaskToTIP(reduces[target], result.getTaskID(), tts, true);
  17. }
  18. return result;
  19. }
  20. private synchronized int findNewReduceTask(TaskTrackerStatus tts, int clusterSize, int numUniqueHosts, double avgProgress) {
  21. if (numReduceTasks == 0) {
  22. return -1;
  23. }
  24. String taskTracker = tts.getTrackerName();
  25. TaskInProgress tip = null;
  26. // Update the last-known clusterSize
  27. this.clusterSize = clusterSize;
  28. if (!shouldRunOnTaskTracker(taskTracker)) {
  29. return -1;
  30. }
  31. long outSize = resourceEstimator.getEstimatedReduceInputSize();
  32. long availSpace = tts.getResourceStatus().getAvailableSpace();
  33. if(availSpace < outSize) {
  34. LOG.warn("No local disk space for reduce task.
    TaskTracker[" + taskTracker + "] has " + availSpace + " bytes free; but
    we expect reduce input to take " + outSize);
  35. return -1; //see if a different TIP might work better.
  36. }
  37. // 1. check for a never-executed reduce tip
  38. // reducers don't have a cache and so pass -1 to explicitly call that out
  39. tip = findTaskFromList(nonRunningReduces, tts, numUniqueHosts, false);
  40. if (tip != null) {
  41. scheduleReduce(tip);
  42. return tip.getIdWithinJob();
  43. }
  44. // 2. check for a reduce tip to be speculated
  45. if (hasSpeculativeReduces) {
  46. tip = findSpeculativeTask(runningReduces, tts, avgProgress, System.currentTimeMillis(), false);
  47. if (tip != null) {
  48. scheduleReduce(tip);
  49. return tip.getIdWithinJob();
  50. }
  51. }
  52. return -1;
  53. }
  54. private synchronized TaskInProgress
    findSpeculativeTask(Collection<TaskInProgress> list,
    TaskTrackerStatus ttStatus, double avgProgress, long currentTime,
    boolean shouldRemove) {
  55. Iterator<TaskInProgress> iter = list.iterator();
  56. while (iter.hasNext()) {
  57. TaskInProgress tip = iter.next();
  58. // should never be true! (since we delete completed/failed tasks)
  59. if (!tip.isRunning()) {
  60. iter.remove();
  61. continue;
  62. }
  63. //当前TaskTracker节点没有运行该任务
  64. if (!tip.hasRunOnMachine(ttStatus.getHost(), ttStatus.getTrackerName())) {
  65. if (tip.hasSpeculativeTask(currentTime, avgProgress)) {
  66. // In case of shared list we don't remove it. Since the TIP failed
  67. // on this tracker can be scheduled on some other tracker.
  68. if (shouldRemove) {
  69. iter.remove(); //this tracker is never going to run it again
  70. }
  71. return tip;
  72. }
  73. } else {
  74. // Check if this tip can be removed from the list.
  75. // If the list is shared then we should not remove.
  76. if (shouldRemove) {
  77. // This tracker will never speculate this tip
  78. iter.remove();
  79. }
  80. }
  81. }
  82. return null;
  83. }

复制代码

在目前的Hadoop版本设计中,作业中任务的调度细节被封装到了JobInProgress中,使得作业调度器TaskScheduler可完全控制的
调度粒度限制在Job级,同时JobInProgress为上层的TaskScheduler实现的任务调度提供API,这样做就大大地降低了用户自行设
计TaskScheduler的门槛,即可以很容易的根据自己的应用场景集中在作业级别上实现合适的调度策略。

分析JobInProgress中Map/Reduce任务分配的更多相关文章

  1. hadoop入门级总结二:Map/Reduce

    在上一篇博客:hadoop入门级总结一:HDFS中,简单的介绍了hadoop分布式文件系统HDFS的整体框架及文件写入读出机制.接下来,简要的总结一下hadoop的另外一大关键技术之一分布式计算框架: ...

  2. MapReduce剖析笔记之五:Map与Reduce任务分配过程

    在上一节分析了TaskTracker和JobTracker之间通过周期的心跳消息获取任务分配结果的过程.中间留了一个问题,就是任务到底是怎么分配的.任务的分配自然是由JobTracker做出来的,具体 ...

  3. Map/Reduce 工作机制分析 --- 作业的执行流程

    前言 从运行我们的 Map/Reduce 程序,到结果的提交,Hadoop 平台其实做了很多事情. 那么 Hadoop 平台到底做了什么事情,让 Map/Reduce 程序可以如此 "轻易& ...

  4. 第九篇:Map/Reduce 工作机制分析 - 作业的执行流程

    前言 从运行我们的 Map/Reduce 程序,到结果的提交,Hadoop 平台其实做了很多事情. 那么 Hadoop 平台到底做了什么事情,让 Map/Reduce 程序可以如此 "轻易& ...

  5. hadoop中map和reduce的数量设置

    hadoop中map和reduce的数量设置,有以下几种方式来设置 一.mapred-default.xml 这个文件包含主要的你的站点定制的Hadoop.尽管文件名以mapred开头,通过它可以控制 ...

  6. MapReduce启动的Map/Reduce子任务简要分析

      对于Hadoop来说,是通过在DataNode中启动Map/Reduce java进程的方式来实现分布式计算处理的,那么就从源码层简要分析一下hadoop中启动Map/Reduce任务的过程.   ...

  7. hadoop中map和reduce的数量设置问题

    转载http://my.oschina.net/Chanthon/blog/150500 map和reduce是hadoop的核心功能,hadoop正是通过多个map和reduce的并行运行来实现任务 ...

  8. 【转】Python 中map、reduce、filter函数

    转自:http://www.blogjava.net/vagasnail/articles/301140.html?opt=admin 介绍下Python 中 map,reduce,和filter 内 ...

  9. 基于python的《Hadoop权威指南》一书中气象数据下载和map reduce化数据处理及其可视化

    文档内容: 1:下载<hadoop权威指南>中的气象数据 2:对下载的气象数据归档整理并读取数据 3:对气象数据进行map reduce进行处理 关键词:<Hadoop权威指南> ...

随机推荐

  1. Mac和Linux下pip更换源

    cd ~mkdir .pip vim .pip/pip.conf 在pip.conf中写入 [global]timeout = 6000index-url = https://pypi.tuna.ts ...

  2. Kali配置网卡静态信息

    临时配置ip ifconfig eth0 up //端口启用 ifconfig eth0 down //端口关闭 ifconfig eth0 192.168.1.10 //只修改ip地址 ifconf ...

  3. Java如何使用finally块来捕捉异常?

    在Java编程中,如何使用finally块来捕捉异常? 此示例显示如何使用finally块来通过使用e.getMessage()捕获运行时异常(Illegalargumentexception). p ...

  4. Java数组搜索和比较

    在Java中,如何搜索和比较数组? 示例 以下示例显示如何使用sort()和binarySearch()方法来完成任务.用户定义的方法printArray()用于显示输出 - package com. ...

  5. (资源)Git优秀学习资源

    在线教程 Try Git: Git初学者绝不能错过的Git上手资源. 廖雪峰Git教程: 比较系统的中文在线教程 易百Git教程 : 另一个比较全的中文在线教程 Git Immersion : A V ...

  6. goldengate一些參数整理

    manager參数: AUTOSTART:指定在mgr启动时自己主动启动那些进程. AUTOSTART ER * AUTOSTART extract extsz  AUTORESTART:指定在mgr ...

  7. Websphere设置JVM时区解决程序、日志时间快8小时问题

    原文链接:http://www.itpub.net/thread-1204714-1-1.html 相信很多使用Websphere的朋友会经常在Windows操作系统中遇到程序时间快8小时的问题 如果 ...

  8. Eclipse文件首部自动加 作者时间

    Window -> Preferences -> Java -> Code Style -> Code templates -> (in right-hand pane) ...

  9. PHP中全局变量的使用global和$GLOBALS[]

    From: http://blog.csdn.net/happyqyt/article/details/7219889 用PHP开发项目,不可避免的会使用到全局变量,比如一些网站的配置信息,全站通用, ...

  10. 生成asm-offset

    因为不善于在Makefile中调用shell的相关工具,所以关于asm-offsets.h中的产生的16进制数并不知如何做到. 因此自己写了个脚本,可以生成同样的文件(再次造了轮子). 参考:http ...