阿里巴巴2014实习生前端招聘在线笔试题

写在前面:

嗯,一共10道小题,60分钟。几天前看过题目了,也简单地挑出了知识点,并趁着还有时间把完全不懂的点看了一下。

今天鼓起勇气开始答题,结果,呃,这套题目不像表面看起来那么简单,原以为复习过之后至少拿到80%,然后做完发现只拿的到最多50%的样子。

废话就这些了,希望能提个醒,这套题目不是那么简单。

P.S.没空看网页的请直接打包带走,拿去就能直接测试

一.2014真题

  1. 请在触摸屏下实现一个按钮,当按快速触碰按钮并放开手时,立刻弹出“成功”二字的提示框。
  2. 请封装一个名叫Counter的计数器Class,只有两个公有成员:
    • 完成计数动作
    • 输出计数总数
  3. 谈谈你对前端工程化/集成开发环境的理解和实践,借助前端工程化你还可以优化前端开发过程中的哪些环节?
  4. 使用原生JavaScript给下面列表中的结点绑定点击事件,点击时创建一个Object对象,兼容IE和标准浏览器。
    HTML:
    <ul id = "nav">
    <li><a href="http://ju.taobao.com/tg/brand.htm">品牌团</a></li>
    <li><a href="http://ju.taobao.com/tg/point_list.htm">整点聚</a></li>
    <li><a href="http://ju.taobao.com/jusp/jiazhuang/tp.htm">聚家装</a></li>
    <li><a href="http://ju.taobao.com/jusp/liangfan/tp.htm">量贩团</a></li>
    </ul>
    Object:
    {
    "index" : 1, // 序号
    "name" : "品牌团",
    "link" : "http://ju.taobao.com/tg/brand.htm"
    }
    
  5. 图片分析,请编写JS代码获取下图中“红框”的位置(“红框”的颜色为“FF0000”)
  6. 请实现下面浮层demo:
    1. 这是一个盖在页面上的浮层,上下左右居中;浮层展示时,页面不可滚动;
    2. 浏览器窗口缩小时,浮层跟着缩小,最小(320px);窗口放大,浮层跟着放大,最大(650px);
    3. 尽可能用HTML5/CSS3方式写,可以不支持IE。
  7. 有一个int型数组,里面有若干数字。要求统计出一共有多少种不同的数字?每种数字出现的频率从少到多排列,频率相同则从小到大排列。
  8. HTTP协议是无状态的,为了保持用户会话状态使用了什么技术方案弥补;该技术方案在用户禁用了cookie之后,还有什么方式实现(可不考虑安全性)
  9. 题目:现有一个字符串richText,是一段富文本,需要显示在页面上。有个要求,需要给其中只包含一个img元素的p标签增加一个叫pic的class。请编写代码实现。可以使用jQuery或KISSY。
  10. 题目:实现一个简单的返回顶部组件的功能。要求:
    1. 当页面向下滚动距顶部一定距离(如100px)时出现,向上回滚距顶部低于同样距离时隐藏,点击返回顶部组件时页面滚动到顶部;
    2. 请写出HTML、CSS和JavaScript;
    3. 要求支持IE6以上、Chrome、Firefox

P.S.上面的题目来自w3cfuns,感谢前辈的题目

二.题目分析

  1. 第一题考知识面:移动端支持的特殊HTML5事件怎么用
  2. 第二题考js作用域:如何实现私有成员,考察基本功
  3. 第三题又考知识面:前端工程化是啥
  4. 第四题考事件委托:js原生事件处理以及DOM节点关系:稍有深度的js题目,考察基本功
  5. 第五题又考知识面:HTML5的Canvas有啥用(不知道就只能干瞪眼了)
  6. 第六题考DOM操作和CSS:考察基本功
  7. 第七题考数组相关函数:深度考察基本功,是否细心
  8. 第八题又考知识面:怎么用无状态的HTTP保持会话
  9. 第九题考JQuery:对JQuery一般了解是做不出来的,比如我。。
  10. 第十题考IE兼容:让人相当无语的一道题目,能当场完美搞定的请受徒儿一拜

从上面的分析可以发现:

  1. alibaba很注重知识面的广度,比如HTML各种特性,移动端,HTTP协议,前端工程化等等等等
  2. 对基本功的考察很细致,比如作用域,事件委托,DOM,CSS,JQuery
  3. 对开发经验的考察也有不少,比如第二题明摆着得用委托,第七题看似简单,第十题乍看也挺简单,越调越觉得不对劲,坑越挖越大

三.我的答案

  1. function tapHandler(e){
      alert("成功");
    }
    var btn = document.getElementById("btn");
    btn.addEventListener("touchend", tapHandler, false);
    btn.addEventListener("MSPointerUp", tapHandler, false);//IE
    
  2. function Counter(){
      var num = 0;//私有成员
      
      this.count = function(){
        num++;
      }
      
      this.display = function(){
        return num;
      }
    }
    
  3. 在我看来,前端工程化就是在整个开发过程中用自动化工具来简化开发工作。从项目构建到模块化开发,模块共享再到调试以及版本控制和发布,这整个过程中很多地方都可以利用自动化工具来帮助我们高效地完成工作。也有很多好用的IDE,比如知名的Grunt,京东的JDF等等,可以根据简单的配置文件自动生成项目目录,并提供模块化开发所需的模块管理组件以及版本控制功能,可以自动处理很多细节问题,让开发人员可以更多地关注业务实现,以提高工作效率。
    
  4. var nav = document.getElementById('nav');
    function listHandler(e){
      e = e || window.event;
      var target = e.target || e.srcElement;
      if(target.nodeName === 'A'){
    	//计算索引
    	var currLi = target.parentNode;
    	var i = 1;
    	while(true){
    	  if(currLi.previousSibling === null){
    		break;
    	  }
    	  else{
    		currLi = currLi.previousSibling;
    		if(currLi.nodeName === 'LI'){//再做一次筛选,防止li间的空白字符被当作有效节点
    		  i++;
    		}
    	  }
    	}
    	
    	//返回Object
    	return {index: i,
    	  name: target.innerHTML,
    	  link: target.href
    	};
      }
    }
    
    if(nav.addEventListener){
      nav.addEventListener("click", listHandler, false);
    }
    else if(nav.attachEvent){//IE
      nav.attachEvent("onclick", listHandler);
    }
    
  5. window.onload = function(){
      var canvas = document.createElement("canvas");
      var img = document.getElementById("targetImg");
    
      if(canvas.getContext){
        var pos = {x: 0, y: 0, w: 0, h: 0};//结果对象
        var totalW = canvas.width = img.width;
        var totalH = canvas.height = img.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);
        var imgData = ctx.getImageData(0, 0, totalW, totalH);
        var data = imgData.data;//获取rgba值
        var r = 0,
            g = 0,
    	    b = 0;
        for(var i = 0;i < data.length;i += 4){
          r = data[i];
    	  g = data[i+1];
    	  b = data[i+2];
    	
    	  if(r === 255 && g === 0 && b === 0){
    	    //找到左上角
    	    pos.x = (i / 4) % totalW;
    	    pos.y = (i / 4) / totalW;
    	    //找到宽度
    	    for(var j = i + 4;j < totalW * (pos.y+1) * 4;j += 4){
    	      r = data[j];
    		  g = data[j+1];
    		  b = data[j+2];
    		
    		  if(!(r === 255 && g === 0 && b === 0)){
    		    pos.w = (j / 4) % totalW - pos.x;
    		    break;
    		  }
    	    }
    	    //找到高度
    	    for(j = i + totalW * 4; j < totalW * totalH * 4;j += totalW * 4){
    	      r = data[j];
    		  g = data[j+1];
    		  b = data[j+2];
    		
    		  if(!(r === 255 && g === 0 && b === 0)){
    		    pos.h = (j / 4) / totalW - pos.y;
    		    break;
    		  }
    	    }
    	  
    	    break;
    	  }
        }
      
        alert(pos.x + ', ' + pos.y + ', ' + pos.w + ', ' + pos.h);///
      }
    }
    
  6. var $ = function(s){
      return document.querySelector(s);
    }
    
    var mask = document.createElement('div');
    var body = document.body;
    var scale = 650 / 1366;//假设默认屏幕宽度是1366px
    mask.style.width = scale * 100 + '%';
    mask.style.height = '50%';
    mask.style.maxHeight = '400px';
    mask.style.maxWidth = '650px';
    mask.style.minWidth = '320px';
    mask.style.zIndex = 9999;
    mask.style.position = 'fixed';
    mask.style.left = (100 - scale * 100)/2 + '%';
    mask.style.top = '25%';
    mask.style.backgroundColor = '#ccc';
    mask.style.display = 'none';
    
    mask.innerHTML = '点击浮层关闭';
    body.appendChild(mask);
    
    var btn = $('#btn');
    btn.onclick = function(e){
      mask.style.display = 'block';
      body.style.overflowY = 'hidden';
    }
    
    mask.onclick = function(e){
      mask.style.display = 'none';
      body.style.overflowY = 'auto';
    }
    
  7. var arr = [1, 2, 2, 4, -1, 3, 6, 15, 1];
    
    function count(arrArg){
      var arr = arrArg.concat();//复制一个数组
      arr.sort();//排序
      var index = 0;
      var result = [{value : arr[0], times : 1}];//结果数组
      for(var i = 1;i < arr.length;i++){
        if(arr[i] === result[index].value){
    	  result[index].times++;
    	}
    	else{
    	  result[++index] = {value : arr[i], times : 1};//创建新元素并存入结果数组
    	}
      }
      
      return result;
    }
    
  8. 利用存储在客户端的Cookie来维持会话状态,可以简单地用URL传值(把一个特殊串作为会话ID嵌在页面URL中),或者使用HTML5的localStorage,IndexedDB等技术,但需要做好浏览器兼容
    
  9. //JQuery
    //插入节点
    var richText = $('<div id="richText">' + text + '</div>');
    $(document.body).append(richText);
    //设置样式
    $('p>img').each(function(){
      var $p = $(this).parent();
      console.log($p.html());///
      if($p.children().length === 1 && $p.find('img').length === 1 && $p.text() === ''){
        $p.addClass('pic');
      }
    });
    
  10. <style type="text/css">
    .top{
    width : 50px;
    height : 50px;
    z-index : 9999;
    position : fixed;
    bottom : 20px;
    right : 20px;
    display : none;
    background-color:#ccc;
    border:1px solid red;
    }
    </style>
    <!-- ie6 hack -->
    <!--[if lt IE 7]>
    <style type="text/css">
    /*防止抖动*/
    body{
    background-image:url(about:blank);
    background-attachment:fixed;
    }
    /*用css表达式模拟fixed*/
    div.top{
    position: absolute;
    right: 20px;
    top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)) - 20);
    }
    </style>
    <![endif]-->
    <script type="text/javascript">
    var topDiv = document.createElement('div');
    topDiv.className = 'top';
    topDiv.innerHTML = 'TOP';
    
    topDiv.onclick = function(){
      document.documentElement.scrollTop = document.body.scrollTop = 0;
      this.style.display = 'none';
    }
    
    document.body.appendChild(topDiv);
    
    function topHandler(e){
      var dis = document.body.scrollTop;
      dis = dis === 0 ? document.documentElement.scrollTop : dis;//FF
      if(dis >= 100){
        topDiv.style.display = 'block';
      }
      else{
        topDiv.style.display = 'none';
      }
    }
    
    if(document.addEventListener){
      document.addEventListener('scroll', topHandler, false);
    }
    else if(document.attachEvent){//IE,给document和body添加onscroll都没有用,只能给window添加
      window.attachEvent('onscroll', topHandler);
    }
    

四.做后感

把所有的坑的都踩了一遍,第十题本来费了好大劲用onmousewheel搞定了,结果想想觉得要用onscroll。

还有JQuery的第九题,看似特别好欺负,谁知道JQuery里面文本不算节点的,用siblings用next用prev用children用:only-child都~~~没有用,测试了很久才发现没有TextNode一说,直接导致N种方案全部失效,做完发现还不如不用JQuery呢,唯一的便利就是$('strHtml')。。

不知道是不是我的理解能力有问题,觉得有的题目说的并不清楚,比如第九题,想考JQuery,题目的意思更像是做字符串处理,找红色块的位置,只要左上角坐标吗?不说清楚,答题的只好把(x, y, w, h)全都算了一遍。。。

因为题目表意不明,需要不停地揣摩出题人的意图,而时间只有60分钟,所以,答题时候应该“渐进增强”,明确每题只有6分钟,不行就只完整实现最简单的功能,比如只找出红色块左上角坐标,力求完整,千万不要出现代码因为Syntax Error而不能运行的情况,否则就真的一分都没有了。。

参考资料

  1. w3cfuns真题
  2. IE6的fixed兼容问题:前端观察,唯一一个彻底的解决方案,看到最后一题的答案了吗,那个css表达式。。
  3. HTML5触摸事件:黯羽轻扬
  4. Canvas教程:黯羽轻扬

资源下载

打包下载,所有东西都在这里,需要的朋友尽管拿去,一起考试也是一种缘分,虽然成事在天,加油。

posted @ 2015-03-30 11:00  梦烬  阅读(3109)  评论(15编辑  收藏  举报