本文是青训营前端练习题的汇总,题目链接在文末。
编程题
编程题 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 的形式。
之后可以使用1010101010101010101010101010101即0x55555555来校验奇数位上是否有 1 (32 位内)。
同理,也可以反过来10101010101010101010101010101010即0xaaaaaaaa来校验偶数位上是否有 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. 增强型表单
- 新增语义化标签: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
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...of与for...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.html和 https://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:hidden 与display: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】