青训营前端练习题汇总

767 阅读9分钟

本文是青训营前端练习题的汇总,题目链接在文末。

编程题

编程题 1

题目
给定一个十进制整数字符串,判断它是否是 4 的幂。
示例 1
输入:"16",输出:true
示例 2
输入:"101",输出:false
示例 3
输入:"70368744177664",输出:true
限定语言:C、 C++、Java、Python、JavaScript V8

经典幂等问题,LeetCode342. 4的幂,不过lc是整数,这里是字符串。

思路1:不断除以 4 。

function isPowerOfFour(n) {
  n = +n;
  while(n > 1){
    if(n % 4){
      return false;
    }
    n /= 4;
  }
  return true;
}

思路2:按位与。
使用按位与判断除以 4 是否有余,即二进制最后两位是否有1。

function isPowerOfFour(n) {
  n = +n;
  while(n > 1){
    if(n & 3){
    // n & 0b11其实更加清楚
      return false;
    }
    n >>= 2;
  }
  return true;
}

思路3:按位与优化。
如果 n 是 4 的幂,则 n 的二进制表示为 1 + 偶数个 0 的形式(可以参考思路2理解)。
4 的幂一定是 2 的幂,所以可以用(n & (n - 1)) === 0判断是否是 2 的幂,即二进制表示为 1 + n 个 0 的形式。
之后可以使用10101010101010101010101010101010x55555555来校验奇数位上是否有 1 (32 位内)。
同理,也可以反过来101010101010101010101010101010100xaaaaaaaa来校验偶数位上是否有 1。
另外, 4 的幂对 3 取模一定为 1 ,所以也可以用n % 3 == 1来判断。

function isPowerOfFour(n) {
  n = +n;
  // return n > 0 && (n & (n - 1)) === 0 && (n & 0x55555555);
  // return n > 0 && (n & (n - 1)) === 0 && (n & 0xaaaaaaaa) === 0;
  return n > 0 && (n & (n - 1)) == 0 && n % 3 == 1;
}

思路4:正则表达式。
转换成4进制字符串,然后使用正则表达式。

function isPowerOfFour(n) {
  n = parseInt(n).toString(4);
  return /^10+$/.test(num);
}

编程题 2

题目
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略空格、字母的大小写。
示例
输入:"A man, a plan, a canal: Panama",输出:true
限定语言:C、 C++、Java、Python、JavaScript V8

LeetCode125. 验证回文串,主要思路就是筛选+判断。

思路1:reverse()函数。

小细节:reverse()会改变数组并返回引用,所以res === res.reverse()会返回 true ,这是不对的。

function isPalindrome(s){
  let res = [], length = s.length;
  // 筛选
  for (let i = 0; i < length; i++) {
    let tmp = s[i].charCodeAt();
    if ((tmp >= 48 && tmp <= 57) || (tmp>=65 && tmp <= 90) || (tmp >= 97 && tmp <= 122)) {
      res.push(s[i].toUpperCase());
    }
  }
  // 判断
  return res.toString() === res.reverse().toString();
}

思路2:双指针。
双指针指向字符串两头不断靠近来判断是否回文串。

function isPalindrome(s){
  let res = [], length = s.length;
  // 筛选
  for (let i = 0; i < length; i++) {
    let tmp = s[i].charCodeAt();
    if ((tmp >= 48 && tmp <= 57) || (tmp>=65 && tmp <= 90) || (tmp >= 97 && tmp <= 122)) {
      res.push(s[i].toUpperCase());
    }
  }
  // 判断
  length = res.length;
  let left = 0, right = length - 1;
  while (left < right) {
    if (res[left] !== res[right]) {
      return false;
    }
    ++left;
    --right;
  }
  return true;
}

思路3:双指针优化。
指针一边动一边筛选。

function isPalindrome(s){
  let left = 0, right = s.length - 1;
  while (left < right) {
    while (left < right && !isLetterOrDigit(s[left])) {
      ++left;
    }
    while (left < right && !isLetterOrDigit(s[right])) {
      --right;
    }
    if (left >= right) {
      break;
    }
    if (s[left].toUpperCase() !== s[right].toUpperCase()) {
      return false;
    }
    ++left;
    --right;
  }
  return true;
}

function isLetterOrDigit(c){
  let tmp = c.charCodeAt();
  if ((tmp >= 48 && tmp <= 57) || (tmp>=65 && tmp <= 90) || (tmp >= 97 && tmp <= 122)) {
    return true
  }
  return false;
}

思路4:正则表达式。

function isPalindrome(s){
  let res = s.match(/[a-zA-Z0-9]/g);
  return res.toString().toUpperCase() === res.reverse().toString().toUpperCase();
}

编程题 3

题目
给定一个字符串,找出该字符串中最长回文子串的长度。
示例 1
输入:"abc",输出:0
示例 2
输入:"abcbe",输出:3
示例 3
输入:"acdcecdcf",输出:7
限定语言:C、 C++、Java、Python、JavaScript V8

牛客最长回文子串,LeetCode5. 最长回文子串也类似,不过不是求串长。

注意:测试用例中单个字符不为回文串。

思路1:动态规划。
j 至 i 组成的字符串为回文串的条件是 s[i] 与 s[j] 相同且 j + 1 至 i - 1 组成字符串为回文串。

function getLongestPalindrome(s){
  let length = s.length,
      dp =new Array(length).fill().map(() => new Array(length)),
      maxLength = 1;
  for(let i = 0; i < length; ++i){
    for(let j = i; j >= 0; --j){
      if(s[i] === s[j] && (i - j <= 1 || dp[i - 1][j + 1])){
        dp[i][j] = true;
        maxLength = Math.max(maxLength, i - j + 1)
      }
    }
  }
  return maxLength === 1 ? 0 : maxLength;
}

思路2:中心扩展法。
枚举所有的回文中心并尝试扩展,直到无法扩展为止,此时的回文串长度即为此回文中心下的最长回文串长度。

function getLongestPalindrome(s) {
  let maxLength = 0;
  for (let i = 0; i < s.length; i++) {
    let len1 = expandAroundCenter(s, i, i),
        len2 = expandAroundCenter(s, i, i + 1),
        len = Math.max(len1, len2);
    maxLength = Math.max(maxLength, len);
  }
  return maxLength === 1 ? 0 : maxLength;
}

function expandAroundCenter(s, left, right) {
  while (left >= 0 && right < s.length && s[left] === s[right]) {
    --left;
    ++right;
  }
  return right - left - 1;
}

选择题

day1

下列哪些是 HTML5 的新特性?ABCD
A. 语义标签
B. Canvas 绘图
C. <audio>元素
D. 增强型表单

HTML5新特性

  • 新增语义化标签:nav、header、footer、aside、section、article
  • 音频、视频标签:audio、video
  • 数据存储:localStorage、sessionStorage
  • canvas(画布)、Geolocation(地理定位)、websocket(通信协议)
  • input标签新增属性:placeholder、autocomplete、autofocus、required
  • history API:go、forward、back、pushstate

下面可以继承的属性有哪些?ACD
A. font-size
B. background
C. color
D. cursor

参见前端面试题之CSS篇

day2

对于一条100M的宽带,理论下载速度上限是多少?A
A. 12.5MB/s
B. 100MB/s
C. 10MB/s
D. 10Mb/s

100 M 的单位是 Mbps 。 1 Byte = 8 bit ,除以 8 就行了。

关于 for of 和 for in 的描述,正确的是?AD
A. for in 可以循环普通对象
B. for of 可以循环普通对象
C. 都不可以循环数组
D. 都可以循环数组

for...of只可以遍历一个含有 iterator 接口的数据结构, Object 没有定义迭代器。
MDN中对for...offor...in的区别做了详细解释,也可以参见前端面试题之JavaScript篇
对象(Object)之所以没有默认部署 Iterator 接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。本质上,遍历器是一种线性处理,对于任何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换。不过,严格地说,对象部署遍历器接口并不是很必要,因为这时对象实际上被当作 Map 结构使用,ES5 没有 Map 结构,而 ES6 原生提供了。(摘自Iterator 和 for...of 循环 - ECMAScript 6入门

day3

关于事件冒泡描述正确的是?A
A. 从目标元素向 document 冒泡
B. 从 document 向目标元素冒泡
C. 从 document 向目标元素冒泡,再从目标元素向 document 冒泡
D. 以上都不是

从底往外冒才叫冒泡。

以下哪些 script 标签属性会使脚本有可能在 DOMContentLoaded 事件之后加载?AD
A. <script async>
B. <script defer>
C. <script type="module">
D. <script type="module" async>

defer会使脚本在 DOMContentLoaded 之前执行,而使用async的话,如果页面加载时间较长,脚本可能会先执行,但绝大多数会在 DOMContentLoaded 之后执行。

day4

以下哪些是 CSS 块级元素的特性?BD
A. 宽度默认由其中的内容决定
B. 高度默认由其中的内容决定
C. 可以被分拆到多行
D. 可以通过 height 属性指定高度

块级元素占据其父元素(容器)的整个水平空间,垂直空间等于其内容高度,因此创建了一个“块”。

以下关于跨域说法错误的是?A
A. http://example.com/a.htmlhttps://example.com/b.html是相同的域名,属于同源
B. 跨域资源共享规范中规定了除了 GET 之外的 HTTP 请求,或者搭配某些 MINE 类型的 POST 请求,浏览器都需要先发一个 OPTIONS 请求。
C. CSS 中通过 @font-face 使用字体也会有跨域问题
D. Cookie,LocalStorage 和 IndexedDB 都会受到同源策略的限制

协议、域名、端口任意一个不同即为跨域。
B选项参见跨源资源共享(CORS)

day5

下列哪些可以实现浏览器存储数据?ABD
A. cookie
B. localStorage
C. session
D. sessionStorage

参见前端面试题之浏览器原理篇

对以下代码说法正确的是?A

let arr = [1,2,3,4,5];
let arr2 = [1, , 3];

A. 执行 arr.length = 3,此时数组为 [1,2,3]
B. 执行 arr[10] = 11,此时 arr.length 为 6
C. 执行 delete arr[2],此时 arr.length 为 4,数组为 [1,2,4,5]
D. arr2.length 的长度为 2

JavaScript 数组的 length 属性和数值属性是连接的,参见Array - JavaScript | MDN
B中arr.length 为 11。
C中数组为 [1,2, ,4,5]。
D中arr2.length 的长度为 3。

day6

在 css 选择器当中,优先级排序正确的是?D
A. id选择器>标签选择器>类选择器
B. 标签选择器>类选择器>id选择器
C. 类选择器>标签选择器>id选择器
D. id选择器>类选择器>标签选择器

参见前端面试题之CSS篇

如以下代码所示,给 body 绑定两个事件后,调用 document.body.click() 输出的结果是?A

document.body.addEventListener('click', () => {
	Promise.resolve().then(() => console.log(1))
	console.log(2);
}, false);
document.body.addEventListener('click', () => {
	Promise.resolve().then(() => console.log(3))
	console.log(4);
}, false);

A. 2, 4, 1, 3
B. 2, 1, 4, 3
C. 1, 2, 3, 4
D. 1, 3, 2, 4

先绑定的事件会先执行,异步任务结果会放置在任务队列中,执行栈完成后才读取任务队列。

day7

浮动会导致页面的非正常显示,以下几种清除浮动的方法,哪个是不推荐使用的?D
A. 在浮动元素末尾添加一个空的标签例如 <div style="clear:both"></div>
B. 通过设置父元素overflow值为hidden
C. 给父元素添加clearfix类
D. 父元素也设置浮动

浮动可能导致高度塌陷。父元素也设置浮动,那“祖宗元素”不就可能高度塌陷了吗?可能会破坏布局。
其他参见前端面试题之CSS篇

以下代码的运行结果是?D

var f = function () {
console.log("1");
};
function f() {
console.log("2");
}

f();

A. undefined
B. 报错
C. 2
D. 1

函数提升到最上面了,之后被重新覆盖,所以运行结果是 1 。
类似,下列代码运行结果是 2 1 1 。

f();
var f = function () {
  console.log("1");
};
f();
function f() {
  console.log("2");
}
f();

这里原题没换行,没打分号报错了,原题答案是 B or D 。

day8

下列说法正确的有哪些?AB
A. visibility:hidden 表示所占据的空间位置仍然存在,仅为视觉上的完全透明
B. display:none 不为被隐藏的对象保留其物理空间
C. visibility:hiddendisplay:none 两者没有本质上的区别
D. visibility:hidden 回流与重绘

回流:布局引擎会根据各种样式计算每个盒子在页面上的大小与位置。
重绘:当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘制。
回流一定引起重绘。
具体参见面试官:怎么理解回流跟重绘?什么场景下会触发?
display:none会引起回流与重绘,visibility:hidden 只会引起重绘,参见前端面试题之CSS篇

若主机甲与主机已已建立一条 TCP 链接,最大段长(MSS)为 1KB,往返时间(RTT)为 2 ms,则在不出现拥塞的前提下,拥塞窗口从 8KB 增长到 32KB 所需的最长时间是?D
A. 4ms
B. 8ms
C. 24ms
D. 48ms

从 8KB 开始使用拥塞避免算法,每次增加 1KB,增加 24KB 需要 48ms。

day9

以下对HTML标签的使用,哪些是符合语义的?
A. 使用 table 展示表格数据
B. 使用 span 表示按钮
C. 使用 article 展示文章内容
D. 使用 p 标签展示文章标题

<span>元素是短语内容的通用行内容器,并没有任何特殊语义。
<p>元素(或者说 HTML 段落元素)表示文本的一个段落。

包过滤防火墙对数据包的过滤依据不包括哪些?
A. 源IP地址
B. 源端口号
C. MAC 地址
D. 目的 IP 地址

包过滤防火墙对数据包的过滤依据包括:IP源地址、IP目标地址、协议(TCP包、UDP包和ICMP包)、TCP或UDP包的源端口、TCP或UDP包的目标端口、ICMP消息类型、TCP包头中的ACK位、数据包到达的端口、数据包出去的端口。(摘自百度百科

原文链接

【青训营 - 前端练习题 - DAY1】
【青训营 - 前端练习题 - DAY2】
【青训营 - 前端练习题 - DAY3】
【青训营 - 前端练习题 - DAY4】
【青训营 - 前端练习题 - DAY5】
【青训营 - 前端练习题 - DAY6】
【青训营 - 前端练习题 - DAY7】
【青训营 - 前端练习题 - DAY8】
【青训营 - 前端练习题 - DAY9】