前端面试(代码)
2017-03-24 12:45
309 查看
一
JS数组去重
二
js中for循环中的setTimeout()正常工作
我们希望每隔2秒依次输出1,2,3
实际上却是,在间隔2秒后直接输出3个3。
原因在于计时器是共享一个i,当for循环结束时,i已经变成3,所以这时就会多次弹出3.所以通过定义一个函数来实现中介的作用,从而创建了变量的值的副本。
这时虽然输出1,2,3,但却是间隔2秒后一次性输出,并未达到我们要求的每隔2秒输出一个要求。所以这时我们要调整setTimeout的时间间隔
三
结果:依次弹出 2和1
分析:函数体内,bb并没有使用var来定义,按理说这个bb在预处理的时候应该是window的属性。但在这里,函数声明的时候,带了一个参数bb,也就是相当于在函数体内声明了var bb。所以,函数里的bb就是函数活动对象的属性。所以函数执行时会输出2。函数执行完后,函数的活动对象被销毁,也就是局部的这个bb被删除了,执行流进入到window,再输出bb,值就是1了。如果声明函数时,把参数那里的bb去掉,这段代码执行起来,结果就是弹出 2 2
四
有一个长度未知的数组a,如果它的长度为0就把数字1添加到数组里面,否则按照先进先出的队列规则让第一个元素出队。
分析:这道题主要是考核了数组的队列方法和栈方法。
五
输出5,考查自执行函数和闭包
六
请把
分析:这题主要考察了dom操作。插入节点操作的可以使用insertBefore和appendChild方法,随便用一个都行。但是,题目要求要考虑性能问题,这才是关键,因为,JavaScript操作dom的开销是很大的!提高性能就要减少dom操作。因此,我当时使用了下面的方法,只操作一次dom就够的了:
七
不使用loop循环,创建一个长度为100的数组,并且每个元素的值等于它的下标。
(1)使用setInterval
(2)使用数组
(3)es6方法
错误方法:
八
实现数组乱序
九
有一个长度为100的数组,请以优雅的方式求出该数组的前10个元素之和
分析:其实,对于数组求和有很多种方法,也很简单。但是,这题有两个限制条件:优雅的方式、前10个元素。对于“前10个元素”这个限制条件可以使用Array.prototype.slice()方法来截取,对于”优雅的方式”,我的理解是应该尽可能使用数组自带的方法,最好可以使用高阶函数!所以我觉得应该是Array.prototype.reduce()方法。
注意, Array的reduce()把一个函数作用在这个Array的[x1, x2, x3…]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算
十
这里func的上下文是window,因此已经失去了count属性。改进如下,使用Function.prototype.bind
十一
解析URL地址
这里的方法就在JS代码里先创建一个a标签然后将需要解析的URL赋值给a的href属性
用法
十二
重构如下两栏布局
Qzone、朋友网、Facebook都给左栏浮动,唯一不同的是右栏的写法,Qzone给右栏定宽并且浮动,而朋友网和Facebook则并没有给右栏定宽也未浮动,而是利用了创建BFC并且为低版本IE触发hasLayout的原理让右栏自适应宽度。
Yahoo和Google两栏都未用浮动,唯一不同的是Yahoo用了绝对定位的方法,而谷歌用了inline-block,Google已经宣布旗下一些产品放弃对IE8 的支持,所以Google可以大胆的使用inline-block去实现布局,不用去为其他低版本浏览器写一大堆的hack。
十三
常见邮箱验证
输入的数据必须包含 @ 符号和点号(.)。同时,@ 不可以是邮件地址的首字符,并且 @ 之后需有至少一个点号
?????????讲一下css的动画(我不太了解, 就直说不太了解,然后她让我试着写了下,就写了些印象里的,她说差不多)
猜一下,如果要绑定动画的话,在哪里绑定?怎么绑定?
如果是行内元素呢?如果字体font-size是10px,行高line-height是2px,显示多高?(依然不知道,猜测是2px,剩余的部分会被隐藏掉)。刚才试了下,发现打错了:
十四
找出整型数组中乘积最大的三个数
十五
给定两个数组,要求求出两个数组的交集,注意,交集中的元素应该是唯一的。
十六
给定两个字符串,判断是否颠倒字母而成的字符串,譬如Mary与Army就是同字母而顺序颠倒:
十七
判断某个字符串是否为回文字符串,譬如racecar与race car都是回文字符串:
十八
判断是否为 2 的指数值
十九
二进制转换
二十
创建一个函数来判断给定的表达式中的大括号是否闭合:
二十一
二分搜索
(1)首先,从有序数组的中间的元素开始搜索,如果该元素正好是目标元素(即要查找的元素),则搜索过程结束,否则进行下一步。
(2)如果目标元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半区域查找,然后重复第一步的操作。
(3)如果某一步数组为空,则表示找不到目标元素。
二十二
手写数组快速排序
“快速排序”的思想很简单,整个排序过程只需要三步:
(1)在数据集之中,选择一个元素作为”基准”(pivot)。
(2)所有小于”基准”的元素,都移到”基准”的左边;所有大于”基准”的元素,都移到”基准”的右边。
(3)对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
JS数组去重
Array.prototype.unique1 = function () { var n = []; //一个新的临时数组 for (var i = 0; i < this.length; i++) //遍历当前数组 { //如果当前数组的第i已经保存进了临时数组,那么跳过, //否则把当前项push到临时数组里面 if (n.indexOf(this[i]) == -1) n.push(this[i]); } return n; }
Array.prototype.unique2 = function() { var n = {},r=[]; //n为hash表,r为临时数组 for(var i = 0; i < this.length; i++) //遍历当前数组 { if (!n[this[i]]) //如果hash表中没有当前项 { n[this[i]] = true; //存入hash表 r.push(this[i]); //把当前数组的当前项push到临时数组里面 } } return r; }
Array.prototype.unique3 = function() { var n = [this[0]]; //结果数组 for(var i = 1; i < this.length; i++) //从第二项开始遍历 { //如果当前数组的第i项在当前数组中第一次出现的位置不是i, //那么表示第i项是重复的,忽略掉。否则存入结果数组 if (this.indexOf(this[i]) == i) n.push(this[i]); } return n; }
arr = [...new Set(arr)]; //ES6新方法
二
js中for循环中的setTimeout()正常工作
我们希望每隔2秒依次输出1,2,3
for (var i = 1; i <= 3; i++) { setTimeout(function () { console.log(i); },2000); }
实际上却是,在间隔2秒后直接输出3个3。
原因在于计时器是共享一个i,当for循环结束时,i已经变成3,所以这时就会多次弹出3.所以通过定义一个函数来实现中介的作用,从而创建了变量的值的副本。
function doSetTimeout(i) { setTimeout(function() { console.log(i); }, 2000); } for (var i = 1; i <= 3; ++i) doSetTimeout(i);
这时虽然输出1,2,3,但却是间隔2秒后一次性输出,并未达到我们要求的每隔2秒输出一个要求。所以这时我们要调整setTimeout的时间间隔
function doSetTimeout(i) { setTimeout(function() { console.log(i); }, 2000*i); } for (var i = 1; i <= 3; ++i) doSetTimeout(i);
三
<SCRIPT LANGUAGE="JavaScript"> var bb = 1; function aa(bb) { bb = 2; alert(bb); }; aa(bb); alert(bb); </SCRIPT>
结果:依次弹出 2和1
分析:函数体内,bb并没有使用var来定义,按理说这个bb在预处理的时候应该是window的属性。但在这里,函数声明的时候,带了一个参数bb,也就是相当于在函数体内声明了var bb。所以,函数里的bb就是函数活动对象的属性。所以函数执行时会输出2。函数执行完后,函数的活动对象被销毁,也就是局部的这个bb被删除了,执行流进入到window,再输出bb,值就是1了。如果声明函数时,把参数那里的bb去掉,这段代码执行起来,结果就是弹出 2 2
四
有一个长度未知的数组a,如果它的长度为0就把数字1添加到数组里面,否则按照先进先出的队列规则让第一个元素出队。
分析:这道题主要是考核了数组的队列方法和栈方法。
a.length === 0 ? a.push(1) : a.shift();
五
var test = ( function(a) { this.a = a; return function(b) { return this.a + b; } } (function(a, b) { return a; }(1, 2) ) ); console.log(test(4));
输出5,考查自执行函数和闭包
六
请把
<ul><li>第1行</li><li>第2行</li>...</ul>(ul之间有10个li元素)插入body里面,注意:需要考虑到性能问题。
分析:这题主要考察了dom操作。插入节点操作的可以使用insertBefore和appendChild方法,随便用一个都行。但是,题目要求要考虑性能问题,这才是关键,因为,JavaScript操作dom的开销是很大的!提高性能就要减少dom操作。因此,我当时使用了下面的方法,只操作一次dom就够的了:
var lis = ""; var ul = document.createElement("ul"); //把li以字符串形式生成 for(var i = 1; i <= 10; i++) { lis += "<li>第" + i + "行</li>"; } // 最后通过innerHTML插入ul里面 ul.innerHTML = lis; //这里才操作dom,把ul插入到body document.body.appendChild(ul);
七
不使用loop循环,创建一个长度为100的数组,并且每个元素的值等于它的下标。
(1)使用setInterval
var a = [], i = 0; var interval = setInterval(function() { i < 100 ? a.push(i++) : clearInterval(interval); }, 0);
(2)使用数组
var a = Array(100).join(",").split(",").map( function(item, index) { return index; } ); 先是创建一个数组,然后,通过join方法把它转成字符串,然后,再通过split方法把字符串转成数组,这时候,它就拥有100个值为空的元素了,然后,再通过map函数,改变这些元素的值即可。
(3)es6方法
var arrNew = Array.from({length: 100},(v,k)=>k); console.log(arrNew );
var arr = new Array(100).keys(); console.log(Array.from(arr));
错误方法:
var a = new Array(100); a = a.map(function(item, index) { return index; }); 因为JavaScript数组是稀疏数组,比如,通过new Array(100)创建一个新的数组的,虽然他的长度是100,但是实际上他是一个空数组,也就是说没有真实存在的元素。所以使用map方法,根本不会去遍历这个数组100次的。
八
实现数组乱序
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], sign = 1; a.sort(function(a, b) { //因为Math.random产生的数在0-1之间 //所以0.5两边的概率是相等的 //大于0.5时为升序,小于0.5时为降序 sign = (Math.random() > 0.5) ? 1 : -1; return (a - b) * sign; });
九
有一个长度为100的数组,请以优雅的方式求出该数组的前10个元素之和
分析:其实,对于数组求和有很多种方法,也很简单。但是,这题有两个限制条件:优雅的方式、前10个元素。对于“前10个元素”这个限制条件可以使用Array.prototype.slice()方法来截取,对于”优雅的方式”,我的理解是应该尽可能使用数组自带的方法,最好可以使用高阶函数!所以我觉得应该是Array.prototype.reduce()方法。
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], sum = 0; sum = a.slice(0, 10).reduce(function(pre, current) { return pre + current; }); console.log(sum); //55
注意, Array的reduce()把一个函数作用在这个Array的[x1, x2, x3…]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算
十
var User = { count: 1, getCount: function() { return this.count; } }; console.log(User.getCount()); //输出1 var func = User.getCount; console.log(func()); //输出Undefined
这里func的上下文是window,因此已经失去了count属性。改进如下,使用Function.prototype.bind
var func = User.getCount.bind(User); console.log(func());
十一
解析URL地址
这里的方法就在JS代码里先创建一个a标签然后将需要解析的URL赋值给a的href属性
function parseURL(url) { var a = document.createElement('a'); a.href = url; return { source: url, protocol: a.protocol.replace(':',''), host: a.hostname, port: a.port, query: a.search, params: (function(){ var ret = {}, seg = a.search.replace(/^\?/,'').split('&'), len = seg.length, i = 0, s; for (;i<len;i++) { if (!seg[i]) { continue; } s = seg[i].split('='); ret[s[0]] = s[1]; } return ret; })(), file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1], hash: a.hash.replace('#',''), path: a.pathname.replace(/^([^\/])/,'/$1'), relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [,''])[1], segments: a.pathname.replace(/^\//,'').split('/') }; }
用法
var myURL = parseURL('http://abc.com:8080/dir/index.html?id=255&m=hello#top'); myURL.file; // = 'index.html' myURL.hash; // = 'top' myURL.host; // = 'abc.com' myURL.query; // = '?id=255&m=hello' myURL.params; // = Object = { id: 255, m: hello } myURL.path; // = '/dir/index.html' myURL.segments; // = Array = ['dir', 'index.html'] myURL.port; // = '8080' myURL.protocol; // = 'http' myURL.source; // = 'http://abc.com:8080/dir/index.html?id=255&m=hello#top'
十二
重构如下两栏布局
<div class="content"><div class="aside"></div><div class="main"></div></div>
/*Qzone版*/ .aside{float:left;width:170px;} .main{float:left;width:790px;} /*朋友网版*/ .aside{float:left;width:170px;} .main{overflow:hidden;#zoom:1;} /*Facebook版*/ .aside{float:left;width:170px;} .main{margin-left:170px;zoom:1;} /*Yahoo版*/ .content{position:relative;zoom:1;} .aside{position:absolute;left:0;top:0;width:170px;} .main{margin-left:170px;zoom:1;} /*Google版*/ .aside{display:inline-block;width:170px;} .main{display:inline-block;width:790px;}
Qzone、朋友网、Facebook都给左栏浮动,唯一不同的是右栏的写法,Qzone给右栏定宽并且浮动,而朋友网和Facebook则并没有给右栏定宽也未浮动,而是利用了创建BFC并且为低版本IE触发hasLayout的原理让右栏自适应宽度。
Yahoo和Google两栏都未用浮动,唯一不同的是Yahoo用了绝对定位的方法,而谷歌用了inline-block,Google已经宣布旗下一些产品放弃对IE8 的支持,所以Google可以大胆的使用inline-block去实现布局,不用去为其他低版本浏览器写一大堆的hack。
十三
常见邮箱验证
输入的数据必须包含 @ 符号和点号(.)。同时,@ 不可以是邮件地址的首字符,并且 @ 之后需有至少一个点号
function validateForm(){ var x=document.forms["myForm"]["email"].value; var atpos=x.indexOf("@"); var dotpos=x.lastIndexOf("."); if (atpos<1 || dotpos<atpos+2 || dotpos+2>=x.length){ alert("不是一个有效的 e-mail 地址"); return false; } }
?????????讲一下css的动画(我不太了解, 就直说不太了解,然后她让我试着写了下,就写了些印象里的,她说差不多)
猜一下,如果要绑定动画的话,在哪里绑定?怎么绑定?
如果是行内元素呢?如果字体font-size是10px,行高line-height是2px,显示多高?(依然不知道,猜测是2px,剩余的部分会被隐藏掉)。刚才试了下,发现打错了:
十四
找出整型数组中乘积最大的三个数
var unsorted_array = [-10, 7, 29, 30, 5, -10, -70]; computeProduct(unsorted_array); // 21000 function sortIntegers(a, b) { return a - b; } // greatest product is either (min1 * min2 * max1 || max1 * max2 * max3) function computeProduct(unsorted) { var sorted_array = unsorted.sort(sortIntegers), product1 = 1, product2 = 1, array_n_element = sorted_array.length - 1; // Get the product of three largest integers in sorted array for (var x = array_n_element; x > array_n_element - 3; x--) { product1 = product1 * sorted_array[x]; } product2 = sorted_array[0] * sorted_array[1] * sorted_array[array_n_element]; if (product1 > product2) return product1; return product2 };
十五
给定两个数组,要求求出两个数组的交集,注意,交集中的元素应该是唯一的。
var firstArray = [2, 2, 4, 1]; var secondArray = [1, 2, 0, 2]; intersection(firstArray, secondArray); // [2, 1] function intersection(firstArray, secondArray) { var hashmap = {}; var intersectionArray = []; firstArray.forEach(function(element) { hashmap[element] = 1; }); secondArray.forEach(function(element) { if (hashmap[element] === 1) { intersectionArray.push(element); hashmap[element]++; } }); return intersectionArray; }
十六
给定两个字符串,判断是否颠倒字母而成的字符串,譬如Mary与Army就是同字母而顺序颠倒:
var firstWord = "Mary"; var secondWord = "Army"; isAnagram(firstWord, secondWord); // true function isAnagram(first, second) { // For case insensitivity, change both words to lowercase. var a = first.toLowerCase(); var b = second.toLowerCase(); // Sort the strings, and join the resulting array to a string. Compare the results a = a.split("").sort().join(""); b = b.split("").sort().join(""); return a === b; }
十七
判断某个字符串是否为回文字符串,譬如racecar与race car都是回文字符串:
function isPalindrome(word) { // Replace all non-letter chars with "" and change to lowercase var lettersOnly = word.toLowerCase().replace(/\s/g, ""); // Compare the string with the reversed version of the string return lettersOnly === lettersOnly.split("").reverse().join(""); }
十八
判断是否为 2 的指数值
// For the non-zero case: function isPowerOfTwo(number) { return number & (number - 1) === 0; } // For zero-case: function isPowerOfTwoZeroCase(number) { return (number !== 0) && ((number & (number - 1)) === 0); }
十九
二进制转换
function decimalToBinary(digit) { if(digit >= 1) { if (digit % 2) { return decimalToBinary((digit - 1) / 2) + 1; } else { // Recursively return proceeding binary digits return decimalToBinary(digit / 2) + 0; } } else { // Exit condition return ''; } }
二十
创建一个函数来判断给定的表达式中的大括号是否闭合:
var expression = "{{}}{}{}" var expressionFalse = "{}{{}"; isBalanced(expression); // true isBalanced(expressionFalse); // false isBalanced(""); // true function isBalanced(expression) { var checkString = expression; var stack = []; // If empty, parentheses are technically balanced if (checkString.length <= 0) return true; for (var i = 0; i < checkString.length; i++) { if(checkString[i] === '{') { stack.push(checkString[i]); } else if (checkString[i] === '}') { // Pop on an empty array is undefined if (stack.length > 0) { stack.pop(); } else { return false; } } } // If the array is not empty, it is not balanced if (stack.pop()) return false; return true; }
二十一
二分搜索
(1)首先,从有序数组的中间的元素开始搜索,如果该元素正好是目标元素(即要查找的元素),则搜索过程结束,否则进行下一步。
(2)如果目标元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半区域查找,然后重复第一步的操作。
(3)如果某一步数组为空,则表示找不到目标元素。
// 非递归算法 function binary_search(arr, key) { var low = 0, high = arr.length - 1; while(low <= high){ var mid = parseInt((high + low) / 2); if(key == arr[mid]){ return mid; }else if(key > arr[mid]){ low = mid + 1; }else{ high = mid -1; } } return -1; }; var arr = [1,2,3,4,5,6,7,8,9,10,11,23,44,86]; var result = binary_search(arr,10); alert(result); // 9 返回目标元素的索引值
// 递归算法 function binary_search(arr,low, high, key) { if (low > high){ return -1; } var mid = parseInt((high + low) / 2); if(arr[mid] == key){ return mid; }else if (arr[mid] > key){ high = mid - 1; return binary_search(arr, low, high, key); }else if (arr[mid] < key){ low = mid + 1; return binary_search(arr, low, high, key); } }; var arr = [1,2,3,4,5,6,7,8,9,10,11,23,44,86]; var result = binary_search(arr, 0, 13, 10); alert(result); // 9 返回目标元素的索引值
二十二
手写数组快速排序
“快速排序”的思想很简单,整个排序过程只需要三步:
(1)在数据集之中,选择一个元素作为”基准”(pivot)。
(2)所有小于”基准”的元素,都移到”基准”的左边;所有大于”基准”的元素,都移到”基准”的右边。
(3)对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
var quickSort = function(arr) { if (arr.length <= 1) { return arr; } var pivotIndex = Math.floor(arr.length / 2); var pivot = arr.splice(pivotIndex, 1)[0]; //这里注意splice返回,是一个包含被删除项目的新数组,所以执行后arr已经删除元素,而【0】则代表被删除的pivot var left = []; var right = []; for (var i = 0; i < arr.length; i++){ if (arr[i] < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } return quickSort(left).concat([pivot], quickSort(right)); };
相关文章推荐
- web前端常用代码于面试等资源
- 破解前端面试系列(3):如何搞定纸上代码环节?
- 破解前端面试系列(3):如何搞定纸上代码环节?
- 破解前端面试系列(3):如何搞定纸上代码环节?
- 问题四,关于概念的实际应用(代码题)。公司面试99%要考的,有答案!
- 编写漂亮的代码 - 将后台程序与前端程序分开
- 软件开发者面试百问-----怎么样让我们的代码可以处理各种错误事件?
- (转帖)小菜编程成长记(一 面试受挫——代码无错就是好?)
- [转]编写漂亮的代码 - 将后台程序与前端程序分开
- 收集的Asp.Net面试程序代码
- 讯雷前端面试题目之一解答
- 软件开发者面试百问-----你怎么保证代码执行速度快,而又不出问题?
- 面试中常见的java问题的代码
- 百度前端笔试面试7个试题
- javascript 密码强度规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
- 面试代码
- 软件开发者面试百问-----看别人代码的时候,你最关心什么地方?
- 面试常用代码
- 判断一个点是否在三个点组成的三角形内 java 代码 面试经典
- 前端面试总结