1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements.  See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership.  The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License.  You may obtain a copy of the License at
  9. *
  10. *     http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.mapreduce;
  19. import java.io.IOException;
  20. import java.security.PrivilegedExceptionAction;
  21. import org.apache.hadoop.conf.Configuration;
  22. import org.apache.hadoop.fs.Path;
  23. import org.apache.hadoop.io.RawComparator;
  24. import org.apache.hadoop.mapreduce.TaskAttemptID;
  25. import org.apache.hadoop.mapred.JobClient;
  26. import org.apache.hadoop.mapred.JobConf;
  27. import org.apache.hadoop.mapred.RunningJob;
  28. import org.apache.hadoop.mapred.TaskCompletionEvent;
  29. /**
  30. * The job submitter's view of the Job. It allows the user to configure the
  31. * job, submit it, control its execution, and query the state. The set methods
  32. * only work until the job is submitted, afterwards they will throw an
  33. * IllegalStateException.
  34. * job 提交者看到的job的视图。它允许用户配置job,提交job,控制job的执行,并且查询他的状态
  35. * set方法只有在job提交的时候才会工作
  36. */
  37. public class Job extends JobContext {
  38. public static enum JobState {DEFINE, RUNNING};//job的状态,有定义好的和正在运行
  39. private JobState state = JobState.DEFINE;
  40. private JobClient jobClient;
  41. private RunningJob info;
  42. /**
  43. * Creates a new {@link Job}
  44. * A Job will be created with a generic {@link Configuration}.
  45. *创建一个新的job,用通用的configuration
  46. * @return the {@link Job}
  47. * @throws IOException
  48. */
  49. public static Job getInstance() throws IOException {
  50. // create with a null Cluster
  51. return getInstance(new Configuration());
  52. }
  53. /**
  54. * Creates a new {@link Job} with a given {@link Configuration}.
  55. * The <code>Job</code> makes a copy of the <code>Configuration</code> so
  56. * that any necessary internal modifications do not reflect on the incoming
  57. * parameter.
  58. *使用给定的configuration创建job
  59. *这里对configuration进行了备份,如此,任何必要的对configuration内部修改,都不会影响传进来的conf参数
  60. * @param conf the {@link Configuration}
  61. * @return the {@link Job}
  62. * @throws IOException
  63. */
  64. public static Job getInstance(Configuration conf) throws IOException {
  65. // create with a null Cluster 没有任何集群的创建
  66. JobConf jobConf = new JobConf(conf);
  67. return new Job(jobConf);
  68. }
  69. /**
  70. * Creates a new {@link Job} with a given {@link Configuration}
  71. * and a given jobName.
  72. *用给定的conf和jobname
  73. * The <code>Job</code> makes a copy of the <code>Configuration</code> so
  74. * that any necessary internal modifications do not reflect on the incoming
  75. * parameter.
  76. *
  77. * @param conf the {@link Configuration}
  78. * @param jobName the job instance's name
  79. * @return the {@link Job}
  80. * @throws IOException
  81. */
  82. public static Job getInstance(Configuration conf, String jobName)
  83. throws IOException {
  84. // create with a null Cluster
  85. Job result = getInstance(conf);
  86. result.setJobName(jobName);
  87. return result;
  88. }
  89. public Job() throws IOException {
  90. this(new Configuration());
  91. }
  92. public Job(Configuration conf) throws IOException {
  93. super(conf, null);
  94. }
  95. public Job(Configuration conf, String jobName) throws IOException {
  96. this(conf);
  97. setJobName(jobName);
  98. }
  99. JobClient getJobClient() {
  100. return jobClient;
  101. }
  102. //确保job的状态
  103. private void ensureState(JobState state) throws IllegalStateException {
  104. if (state != this.state) {
  105. throw new IllegalStateException("Job in state "+ this.state +
  106. " instead of " + state);
  107. }
  108. if (state == JobState.RUNNING && jobClient == null) {
  109. throw new IllegalStateException("Job in state " + JobState.RUNNING +
  110. " however jobClient is not initialized!");
  111. }
  112. }
  113. /**
  114. * Set the number of reduce tasks for the job.
  115. * 设置reducer的个数 常用
  116. * @param tasks the number of reduce tasks
  117. * @throws IllegalStateException if the job is submitted
  118. */
  119. public void setNumReduceTasks(int tasks) throws IllegalStateException {
  120. ensureState(JobState.DEFINE);
  121. conf.setNumReduceTasks(tasks);
  122. }
  123. /**
  124. * Set the current working directory for the default file system.
  125. * 为默认文件系统 设置当前工作目录
  126. * @param dir the new current working directory.
  127. * @throws IllegalStateException if the job is submitted
  128. */
  129. public void setWorkingDirectory(Path dir) throws IOException {
  130. ensureState(JobState.DEFINE);
  131. conf.setWorkingDirectory(dir);
  132. }
  133. /**
  134. * Set the {@link InputFormat} for the job.
  135. * @param cls the <code>InputFormat</code> to use
  136. * @throws IllegalStateException if the job is submitted
  137. */
  138. public void setInputFormatClass(Class<? extends InputFormat> cls
  139. ) throws IllegalStateException {
  140. ensureState(JobState.DEFINE);
  141. conf.setClass(INPUT_FORMAT_CLASS_ATTR, cls, InputFormat.class);
  142. }
  143. /**
  144. * Set the {@link OutputFormat} for the job.
  145. * @param cls the <code>OutputFormat</code> to use
  146. * @throws IllegalStateException if the job is submitted
  147. */
  148. public void setOutputFormatClass(Class<? extends OutputFormat> cls
  149. ) throws IllegalStateException {
  150. ensureState(JobState.DEFINE);
  151. conf.setClass(OUTPUT_FORMAT_CLASS_ATTR, cls, OutputFormat.class);
  152. }
  153. /**
  154. * Set the {@link Mapper} for the job.
  155. * @param cls the <code>Mapper</code> to use
  156. * @throws IllegalStateException if the job is submitted
  157. */
  158. public void setMapperClass(Class<? extends Mapper> cls
  159. ) throws IllegalStateException {
  160. ensureState(JobState.DEFINE);
  161. conf.setClass(MAP_CLASS_ATTR, cls, Mapper.class);
  162. }
  163. /**
  164. * Set the Jar by finding where a given class came from.
  165. * 设置jar包,hadoop根据给定的class来寻找他的jar包
  166. * @param cls the example class
  167. */
  168. public void setJarByClass(Class<?> cls) {
  169. conf.setJarByClass(cls);
  170. }
  171. /**
  172. * Get the pathname of the job's jar.
  173. * @return the pathname
  174. */
  175. public String getJar() {
  176. return conf.getJar();
  177. }
  178. /**
  179. * Set the combiner class for the job.
  180. * @param cls the combiner to use
  181. * @throws IllegalStateException if the job is submitted
  182. */
  183. public void setCombinerClass(Class<? extends Reducer> cls
  184. ) throws IllegalStateException {
  185. ensureState(JobState.DEFINE);
  186. conf.setClass(COMBINE_CLASS_ATTR, cls, Reducer.class);
  187. }
  188. /**
  189. * Set the {@link Reducer} for the job.
  190. * @param cls the <code>Reducer</code> to use
  191. * @throws IllegalStateException if the job is submitted
  192. */
  193. public void setReducerClass(Class<? extends Reducer> cls
  194. ) throws IllegalStateException {
  195. ensureState(JobState.DEFINE);
  196. conf.setClass(REDUCE_CLASS_ATTR, cls, Reducer.class);
  197. }
  198. /**
  199. * Set the {@link Partitioner} for the job.
  200. * @param cls the <code>Partitioner</code> to use
  201. * @throws IllegalStateException if the job is submitted
  202. */
  203. public void setPartitionerClass(Class<? extends Partitioner> cls
  204. ) throws IllegalStateException {
  205. ensureState(JobState.DEFINE);
  206. conf.setClass(PARTITIONER_CLASS_ATTR, cls, Partitioner.class);
  207. }
  208. /**
  209. * Set the key class for the map output data. This allows the user to
  210. * specify the map output key class to be different than the final output
  211. * value class.
  212. *
  213. * @param theClass the map output key class.
  214. * @throws IllegalStateException if the job is submitted
  215. */
  216. public void setMapOutputKeyClass(Class<?> theClass
  217. ) throws IllegalStateException {
  218. ensureState(JobState.DEFINE);
  219. conf.setMapOutputKeyClass(theClass);
  220. }
  221. /**
  222. * Set the value class for the map output data. This allows the user to
  223. * specify the map output value class to be different than the final output
  224. * value class.
  225. *
  226. * @param theClass the map output value class.
  227. * @throws IllegalStateException if the job is submitted
  228. */
  229. public void setMapOutputValueClass(Class<?> theClass
  230. ) throws IllegalStateException {
  231. ensureState(JobState.DEFINE);
  232. conf.setMapOutputValueClass(theClass);
  233. }
  234. /**
  235. * Set the key class for the job output data.
  236. *
  237. * @param theClass the key class for the job output data.
  238. * @throws IllegalStateException if the job is submitted
  239. */
  240. public void setOutputKeyClass(Class<?> theClass
  241. ) throws IllegalStateException {
  242. ensureState(JobState.DEFINE);
  243. conf.setOutputKeyClass(theClass);
  244. }
  245. /**
  246. * Set the value class for job outputs.
  247. *
  248. * @param theClass the value class for job outputs.
  249. * @throws IllegalStateException if the job is submitted
  250. */
  251. public void setOutputValueClass(Class<?> theClass
  252. ) throws IllegalStateException {
  253. ensureState(JobState.DEFINE);
  254. conf.setOutputValueClass(theClass);
  255. }
  256. /**
  257. * Define the comparator that controls how the keys are sorted before they
  258. * are passed to the {@link Reducer}.
  259. * @param cls the raw comparator
  260. * @throws IllegalStateException if the job is submitted
  261. */
  262. public void setSortComparatorClass(Class<? extends RawComparator> cls
  263. ) throws IllegalStateException {
  264. ensureState(JobState.DEFINE);
  265. conf.setOutputKeyComparatorClass(cls);
  266. }
  267. /**
  268. * Define the comparator that controls which keys are grouped together
  269. * for a single call to
  270. * {@link Reducer#reduce(Object, Iterable,
  271. *                       org.apache.hadoop.mapreduce.Reducer.Context)}
  272. * @param cls the raw comparator to use
  273. * @throws IllegalStateException if the job is submitted
  274. */
  275. public void setGroupingComparatorClass(Class<? extends RawComparator> cls
  276. ) throws IllegalStateException {
  277. ensureState(JobState.DEFINE);
  278. conf.setOutputValueGroupingComparator(cls);
  279. }
  280. /**
  281. * Set the user-specified job name.
  282. *
  283. * @param name the job's new name.
  284. * @throws IllegalStateException if the job is submitted
  285. */
  286. public void setJobName(String name) throws IllegalStateException {
  287. ensureState(JobState.DEFINE);
  288. conf.setJobName(name);
  289. }
  290. /**
  291. * Turn speculative execution on or off for this job.
  292. * 设置推测执行的开关
  293. * @param speculativeExecution <code>true</code> if speculative execution
  294. *                             should be turned on, else <code>false</code>.
  295. */
  296. public void setSpeculativeExecution(boolean speculativeExecution) {
  297. ensureState(JobState.DEFINE);
  298. conf.setSpeculativeExecution(speculativeExecution);
  299. }
  300. /**
  301. * Turn speculative execution on or off for this job for map tasks.
  302. *
  303. * @param speculativeExecution <code>true</code> if speculative execution
  304. *                             should be turned on for map tasks,
  305. *                             else <code>false</code>.
  306. */
  307. public void setMapSpeculativeExecution(boolean speculativeExecution) {
  308. ensureState(JobState.DEFINE);
  309. conf.setMapSpeculativeExecution(speculativeExecution);
  310. }
  311. /**
  312. * Turn speculative execution on or off for this job for reduce tasks.
  313. *
  314. * @param speculativeExecution <code>true</code> if speculative execution
  315. *                             should be turned on for reduce tasks,
  316. *                             else <code>false</code>.
  317. */
  318. public void setReduceSpeculativeExecution(boolean speculativeExecution) {
  319. ensureState(JobState.DEFINE);
  320. conf.setReduceSpeculativeExecution(speculativeExecution);
  321. }
  322. /**
  323. * Get the URL where some job progress information will be displayed.
  324. * 得到 一些job 进度信息会展示的url地址
  325. * @return the URL where some job progress information will be displayed.
  326. */
  327. public String getTrackingURL() {
  328. ensureState(JobState.RUNNING);
  329. return info.getTrackingURL();
  330. }
  331. /**
  332. * Get the <i>progress</i> of the job's setup, as a float between 0.0
  333. * and 1.0.  When the job setup is completed, the function returns 1.0.
  334. *
  335. * @return the progress of the job's setup.
  336. * @throws IOException
  337. */
  338. public float setupProgress() throws IOException {
  339. ensureState(JobState.RUNNING);
  340. return info.setupProgress();
  341. }
  342. /**
  343. * Get the <i>progress</i> of the job's map-tasks, as a float between 0.0
  344. * and 1.0.  When all map tasks have completed, the function returns 1.0.
  345. *
  346. * @return the progress of the job's map-tasks.
  347. * @throws IOException
  348. */
  349. public float mapProgress() throws IOException {
  350. ensureState(JobState.RUNNING);
  351. return info.mapProgress();
  352. }
  353. /**
  354. * Get the <i>progress</i> of the job's reduce-tasks, as a float between 0.0
  355. * and 1.0.  When all reduce tasks have completed, the function returns 1.0.
  356. *
  357. * @return the progress of the job's reduce-tasks.
  358. * @throws IOException
  359. */
  360. public float reduceProgress() throws IOException {
  361. ensureState(JobState.RUNNING);
  362. return info.reduceProgress();
  363. }
  364. /**
  365. * Check if the job is finished or not.
  366. * This is a non-blocking call.
  367. *
  368. * @return <code>true</code> if the job is complete, else <code>false</code>.
  369. * @throws IOException
  370. */
  371. public boolean isComplete() throws IOException {
  372. ensureState(JobState.RUNNING);
  373. return info.isComplete();
  374. }
  375. /**
  376. * Check if the job completed successfully.
  377. *
  378. * @return <code>true</code> if the job succeeded, else <code>false</code>.
  379. * @throws IOException
  380. */
  381. public boolean isSuccessful() throws IOException {
  382. ensureState(JobState.RUNNING);
  383. return info.isSuccessful();
  384. }
  385. /**
  386. * Kill the running job.  Blocks until all job tasks have been
  387. * killed as well.  If the job is no longer running, it simply returns.
  388. * 杀掉正在运行的job 直到所有的job tasks都被杀掉之后 才会停止。
  389. * 如果job不再运行来 他就会返回
  390. * @throws IOException
  391. */
  392. public void killJob() throws IOException {
  393. ensureState(JobState.RUNNING);
  394. info.killJob();
  395. }
  396. /**
  397. * Get events indicating completion (success/failure) of component tasks.
  398. *
  399. * @param startFrom index to start fetching events from
  400. * @return an array of {@link TaskCompletionEvent}s
  401. * @throws IOException
  402. */
  403. public TaskCompletionEvent[] getTaskCompletionEvents(int startFrom
  404. ) throws IOException {
  405. ensureState(JobState.RUNNING);
  406. return info.getTaskCompletionEvents(startFrom);
  407. }
  408. /**
  409. * Kill indicated task attempt.
  410. *
  411. * @param taskId the id of the task to be terminated.
  412. * @throws IOException
  413. */
  414. public void killTask(TaskAttemptID taskId) throws IOException {
  415. ensureState(JobState.RUNNING);
  416. info.killTask(org.apache.hadoop.mapred.TaskAttemptID.downgrade(taskId),
  417. false);
  418. }
  419. /**
  420. * Fail indicated task attempt.
  421. *
  422. * @param taskId the id of the task to be terminated.
  423. * @throws IOException
  424. */
  425. public void failTask(TaskAttemptID taskId) throws IOException {
  426. ensureState(JobState.RUNNING);
  427. info.killTask(org.apache.hadoop.mapred.TaskAttemptID.downgrade(taskId),
  428. true);
  429. }
  430. /**
  431. * Gets the counters for this job.
  432. *
  433. * @return the counters for this job.
  434. * @throws IOException
  435. */
  436. public Counters getCounters() throws IOException {
  437. ensureState(JobState.RUNNING);
  438. return new Counters(info.getCounters());
  439. }
  440. private void ensureNotSet(String attr, String msg) throws IOException {
  441. if (conf.get(attr) != null) {
  442. throw new IOException(attr + " is incompatible with " + msg + " mode.");
  443. }
  444. }
  445. /**
  446. * Sets the flag that will allow the JobTracker to cancel the HDFS delegation
  447. * tokens upon job completion. Defaults to true.
  448. */
  449. public void setCancelDelegationTokenUponJobCompletion(boolean value) {
  450. ensureState(JobState.DEFINE);
  451. conf.setBoolean(JOB_CANCEL_DELEGATION_TOKEN, value);
  452. }
  453. /**
  454. * Default to the new APIs unless they are explicitly set or the old mapper or
  455. * reduce attributes are used.
  456. * @throws IOException if the configuration is inconsistant
  457. */
  458. private void setUseNewAPI() throws IOException {
  459. int numReduces = conf.getNumReduceTasks();
  460. String oldMapperClass = "mapred.mapper.class";
  461. String oldReduceClass = "mapred.reducer.class";
  462. conf.setBooleanIfUnset("mapred.mapper.new-api",
  463. conf.get(oldMapperClass) == null);
  464. if (conf.getUseNewMapper()) {
  465. String mode = "new map API";
  466. ensureNotSet("mapred.input.format.class", mode);
  467. ensureNotSet(oldMapperClass, mode);
  468. if (numReduces != 0) {
  469. ensureNotSet("mapred.partitioner.class", mode);
  470. } else {
  471. ensureNotSet("mapred.output.format.class", mode);
  472. }
  473. } else {
  474. String mode = "map compatability";
  475. ensureNotSet(JobContext.INPUT_FORMAT_CLASS_ATTR, mode);
  476. ensureNotSet(JobContext.MAP_CLASS_ATTR, mode);
  477. if (numReduces != 0) {
  478. ensureNotSet(JobContext.PARTITIONER_CLASS_ATTR, mode);
  479. } else {
  480. ensureNotSet(JobContext.OUTPUT_FORMAT_CLASS_ATTR, mode);
  481. }
  482. }
  483. if (numReduces != 0) {
  484. conf.setBooleanIfUnset("mapred.reducer.new-api",
  485. conf.get(oldReduceClass) == null);
  486. if (conf.getUseNewReducer()) {
  487. String mode = "new reduce API";
  488. ensureNotSet("mapred.output.format.class", mode);
  489. ensureNotSet(oldReduceClass, mode);
  490. } else {
  491. String mode = "reduce compatability";
  492. ensureNotSet(JobContext.OUTPUT_FORMAT_CLASS_ATTR, mode);
  493. ensureNotSet(JobContext.REDUCE_CLASS_ATTR, mode);
  494. }
  495. }
  496. }
  497. /**
  498. * Submit the job to the cluster and return immediately.
  499. * 提交job到集群上面 并且立刻返回
  500. * @throws IOException
  501. */
  502. public void submit() throws IOException, InterruptedException,
  503. ClassNotFoundException {
  504. ensureState(JobState.DEFINE);
  505. setUseNewAPI();
  506. // Connect to the JobTracker and submit the job
  507. //连接到jobtracker 并且提交作业
  508. connect();
  509. info = jobClient.submitJobInternal(conf);//这里才真正的提交作业
  510. super.setJobID(info.getID());
  511. state = JobState.RUNNING;
  512. }
  513. /**
  514. * Open a connection to the JobTracker
  515. * 打开到jobtracker的连接
  516. * @throws IOException
  517. * @throws InterruptedException
  518. */
  519. private void connect() throws IOException, InterruptedException {
  520. ugi.doAs(new PrivilegedExceptionAction<Object>() {
  521. public Object run() throws IOException {
  522. jobClient = new JobClient((JobConf) getConfiguration());
  523. return null;
  524. }
  525. });
  526. }
  527. /**
  528. * Submit the job to the cluster and wait for it to finish.
  529. * @param verbose print the progress to the user
  530. * @return true if the job succeeded
  531. * @throws IOException thrown if the communication with the
  532. *         <code>JobTracker</code> is lost
  533. */
  534. public boolean waitForCompletion(boolean verbose
  535. ) throws IOException, InterruptedException,
  536. ClassNotFoundException {
  537. if (state == JobState.DEFINE) {
  538. submit();
  539. }
  540. if (verbose) {
  541. jobClient.monitorAndPrintJob(conf, info);
  542. } else {
  543. info.waitForCompletion();
  544. }
  545. return isSuccessful();
  546. }
  547. }

job源码分析的更多相关文章

  1. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  2. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  3. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  4. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  5. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  6. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  7. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  8. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

  9. ABP源码分析三:ABP Module

    Abp是一种基于模块化设计的思想构建的.开发人员可以将自定义的功能以模块(module)的形式集成到ABP中.具体的功能都可以设计成一个单独的Module.Abp底层框架提供便捷的方法集成每个Modu ...

  10. ABP源码分析四:Configuration

    核心模块的配置 Configuration是ABP中设计比较巧妙的地方.其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配 ...

随机推荐

  1. js学习之正则表达式

    js学习之正则表达式 正则表达式(英语:Regular Expression,在代码中常简写为regex.regexp或RE)使用单个字符串来描述.匹配一系列符合某个句法规则的字符串搜索模式 一:语法 ...

  2. js经典试题之w3规范系列

    js经典试题之w3规范系列 1:w3c 制定的 javascript 标准事件模型的正确的顺序? 答案:事件捕获->事件处理->事件冒泡 解析:先事件捕获从windows > doc ...

  3. Alpha发布文案加美工展示

    目录 团队简介 项目进展 组内分工 队员总结 后期计划 一.团队简介 二.项目进展 从选题发布到今天的Alpha发布,我们团队经历了许许多多的磨难.我们最终设计了如下的功能:首页.班级.个人.更多.打 ...

  4. Uva 1600 Patrol Robot (BFS 最短路)

    这道题运用的知识点是求最短路的算法.一种方法是利用BFS来求最短路. 需要注意的是,我们要用一个三维数组来表示此状态是否访问过,而不是三维数组.因为相同的坐标可以通过不同的穿墙方式到达. #inclu ...

  5. # 团队作业MD

    队员姓名与学号 051501124 王彬(组长) 111500206 赵畅 031602215 胡展瑞 031602320 李恒达 031602131 佘岳昕 031602431 王源 0316022 ...

  6. python学习笔记08:安装django

    linux环境安装django: sudo pip install django windows环境安装django: pip install django 验证django是否安装: python ...

  7. iOS- 非ARC的项目内存管理细节详解(实战)

    1.前言 接上文:iOS- 如何将非ARC的项目转换成ARC项目(实战) 2.内存管理时相关的配置 当我们把将非ARC的内存管理都管理好后,发现在做有些操作的时候内存还是在一直的缓慢增加 比如做一个最 ...

  8. TCP源码—连接建立

    一.SYN报文处理: 公共部分:tcp_v4_rcv->tcp_v4_do_rcv->tcp_v4_cookie_check(无处理动作)->tcp_rcv_state_proces ...

  9. 转 【.NET平台下使用MongoDB入门教程】

    目录 一.了解MongoDB 二.MongoDB特点 三.安装及常用命令 3.1 下载安装 3.2 启动服务器 3.3 常用操作 3.4 其他命令 3.5 做成windows服务 四.批处理程序开启M ...

  10. HDU 2163 Palindromes

    http://acm.hdu.edu.cn/showproblem.php?pid=2163 Problem Description Write a program to determine whet ...