由我出的题目,是一道比较考验编码能力和即时学习能力的题。
应聘者普遍是北京各理工科高校的硕士生。
机试试题:
小明非常喜欢综艺节目,他发现优酷网上有一个用户叫做“琪琪综艺”上传相关的综艺节目特别多。所以他想监控“琪琪综艺”的更新信息。他的需求有:
<!--[if !supportLists]-->1. <!--[endif]-->收集“琪琪综艺”所有上传过的影片信息。
<!--[if !supportLists]-->2. <!--[endif]-->若“琪琪综艺”发布了新的影片,需要在尽快通知小明。
<!--[if !supportLists]-->3. <!--[endif]-->影片信息包括两点:影片名 和 播放地址。
如影片 首尔酷旅行20101031 的播放地址是
http://v.youku.com/v_show/id_XMjE5MTQ1NzE2.html
请为小明编写这个程序。
具体要求:
<!--[if !supportLists]-->1. <!--[endif]-->由于时间有限,所以你只需要成功抓到前100个视频信息,就认为你已经完成了“收集所有上传影片”的任务。
<!--[if !supportLists]-->2. <!--[endif]-->将要求1抓取到的影片信息记入文本文件(movies.txt),格式为:每个影片信息一行,包括影片名和播放地址,中间用制表符(/t)隔开。
<!--[if !supportLists]-->3. <!--[endif]-->在要求2完成之后,对于“琪琪综艺”新发布的影片,立即在控制台打印影片信息,并将信息追加到文件movies.txt末尾。
小提示:
<!--[if !supportLists]-->1. <!--[endif]-->你可以在http://u.youku.com/user_video/id_UNDM5NjAyNzY=.html获得“琪琪综艺”的所有上传影片。
<!--[if !supportLists]-->2. <!--[endif]-->你有最多4个小时时间进行编码,但提前完成将提高你的最终得分。
<!--[if !supportLists]-->3. <!--[endif]-->你可以任意使用互联网搜索需要的信息,但严禁上网与其他人讨论或在论坛发帖咨询。
目前情况:
机试的学生普遍情况看来不太理想,一般表现为:
集中表现为代码的逻辑性较低,然后是相关知识获取、即时学习的速度(比如正则表达式,网页抓取),最后是异常处理(健壮性),以及审题。
例如以下是一个学生写的部分代码,其中///<是我给的评价
package main; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.Calendar; import java.util.Date; import util.ContentUtil; public class Task implements Runnable { String httpurl; FileHandler fh; Task(String httpurl, FileHandler fh) { this.httpurl = httpurl; this.fh = fh; } public void run() { // TODO Auto-generated method stub System.out.println(Calendar.getInstance().getTime()); getHtmlReadLine(httpurl, fh, true); ///< 为什么上来就一定翻页? } /** * @param httpurl * @param fh * @param searchNextPage:search the videos at other pages or not */ public int getHtmlReadLine(String httpurl, FileHandler fh, boolean searchNextPage) { ///< 本函数评价: ///< 1. 使用了正则表达式,但只使用了最基本的match功能。实际上可以直接使用正则表达式挖取所有数据。 ///< 包括视频名、视频URL、翻页地址等; ///< 2. 是否继续爬取(翻页)的逻辑有问题,应该是抓到已重复的数据就标识任务完成,否则继续翻页抓取。 ///< 而不仅仅限于翻页一次。(有可能用户一次就更新N个视频,占据多个页面,这样就会漏掉信息); ///< 3. 耦合了页面抓取本身与业务逻辑,可以直接把整个页面内容全部拿下来再进行逻辑(不要把对行的读取 ///< 耦合在页面分析中。 String currentLine = ""; InputStream urlStream; int newArrival = 0; try { URL url = new URL(httpurl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); urlStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(urlStream, "utf-8")); Video video;///< 没有必要在此声明,参考就近原则 boolean alreadyFindVideo = false; //Only search the other pages after already analyze the videos. ///< 基于每一行的内容解析 while ((currentLine = reader.readLine()) != null) { currentLine = currentLine.trim(); if (ContentUtil.matchTitle(currentLine)) { ///< 匹配行 alreadyFindVideo = true; video = ContentUtil.analizeVideo(currentLine); ///< 解析HTML if (!fh.existUrl(video)) { ///< 文件或缓存里面没有 System.out.println("New arrival:"); System.out.print(video); fh.add(video); newArrival++; } } else if (alreadyFindVideo && searchNextPage && ContentUtil.matchPages(currentLine)) { String nextpage = ContentUtil.analizePage(currentLine); ///< 解析下一页的地址 // System.out.println("Search Next Page at:" + nextpage); newArrival += getHtmlReadLine(nextpage, fh, false); ///< 翻页,为什么翻页就一定是传false? ///< 递归?这样会造成栈内资源不释放,是否考虑放到更上层来调度? } } } catch (Exception e) { e.printStackTrace();///< 没有处理该异常 ///< 如果异常了,可能会是什么? ///< 最可能是网页抓取超时,这时应该考虑重试抓取网页。 } if (searchNextPage && newArrival == 0) ///< 没有新的,就不抓取? System.out.println("No new arrival!"); return newArrival; } }