知识总结
- 请写出一个符合 W3C 规范的 HTML 文件,要求
页面标题为「我的页面」
页面中引入了一个外部 CSS 文件,文件路径为 /style.css
页面中引入了另一个外部 CSS 文件,路径为 /print.css,该文件仅在打印时生效
页面中引入了另一个外部 CSS 文件,路径为 /mobile.css,该文件仅在设备宽度小于 500 像素时生效
页面中引入了一个外部 JS 文件,路径为 /main.js
页面中引入了一个外部 JS 文件,路径为 /gbk.js,文件编码为 GBK
页面中有一个 SVG 标签,SVG 里面有一个直径为 100 像素的圆圈,颜色随意
注意题目中的路径
答:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>我的页面</title>
<link rel="stylesheet" href="./stlyle.css">
<link rel="stylesheet" href="./print.css" media="print">
<link rel="stylesheet" href="./mobile.css" media="(max-width:500px)">
</head>
<body>
<svg>
<circle cx="60" cy="60" r="50" stroke="red" fill="transparent" stroke-width="5"/>
</svg>
</body>
<script src="./main.js"></script>
<script src="./jbk.js" charset="GBK"></script>
</html>
- 移动端是怎么做适配的?
回答要点:
- meta viewport
- 媒体查询
- 动态 rem 方案
答:
- meta viewpoint
一个典型的针对移动端优化的站点包含类似下面的内容:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
-
width
属性控制视口的宽度。可以像width=600
这样设为确切的像素数,或者设为
device-width
这一特殊值来指代比例为100%时屏幕宽度的CSS像素数值。(相应有height
及
device-height
属性,可能对包含基于视口高度调整大小及位置的元素的页面有用。) -
initial-scale
属性控制页面最初加载时的缩放等级。maximum-scale
、minimum-scale
及
user-scalable
属性控制允许用户以怎样的方式放大或缩小页面。
- 媒体查询
媒体查询,添加自CSS3,允许内容的呈现针对一个特定范围的输出设备而进行裁剪,而不必改变内容本身。
<!-- link元素中的CSS媒体查询 -->
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" />
<!-- 样式表中的CSS媒体查询 -->
<style>
@media (max-width: 600px) {
.facet_sidebar {
display: none;
}
}
</style>
- 动态rem方案
rem
:即root em,表示根元素的font-size
,根元素一般指<html></html>
动态REM主要利用了rem = html:font-size = viewportWidth
- 在css中我们无法获取当前设备的宽度,所以需要在JS中需要写:
var pageWidth = window.innerWidth
document.write('<style>html{font-size:'+pageWidth/10+'px;}</style>')
即让<html></html>
的font-size
= 设备宽度*0.1,即 1 rem = 0.1 pageWidth
- 使用SCSS可以写个函数,方便的将设计稿里的尺寸单位px直接转换成rem相应的值
@function px( $px ){
@return $px/$designWidth*10 + rem;
//以实际像素值➗当前页面宽度✖️rem的转换率 再加rem的后缀(字符串)
}
$designWidth : 640; // 640 是设计稿的宽度
- 用过CSS3吗? 实现圆角矩形和阴影怎么做?
答:
- 圆角矩形
border-radiu:3px;
- 阴影
box-shadow使用一个或多个投影,如果使用多个投影时必须需要用逗号,
分开。
对象选择器· box-shadow:inset x-offset y-offset blur-radius spread-radius color}
对象选择器 {box-shadow:投影方式 X轴偏移量 Y轴偏移量 阴影模糊半径 阴影扩展半径 阴影颜色}
- 什么是闭包,闭包的用途是什么?
答:
- 什么是闭包
function foo(){
var local = 1
function bar(){
local++
return local
}
return bar
}
var func = foo()
func()
函数和函数内部能访问到的变量(也叫环境)的总和,就是一个闭包,local 变量和 bar 函数就组
成了一个闭包。
- 闭包的用途
闭包常常用来间接访问一个变量。换句话说,隐藏一个变量。
闭包可以暂存数据,给变量开辟私密空间,避免外部污染,在一个函数作用域中声明一个变量,子
函数(访问器)可以操作这个变量,通过return 这个子函数(访问器),
外面可以访问这一个变量,来达到此目的,外面变量通过得到return的函数,这样外面访问这个函
数,这个函数访问父级函数的变量。
function s(){
var i = 0;
return function(){
return ++i;
}
}
var a = s()
console.log(a())
- call、apply、bind 的用法分别是什么?
答:
- 函数调用普通写法:
let me = {
name: "me",
sayHello: function (age) {
console.log("hello, I am", this.name + " " + age + " " + "years old")
}
}
let someone = {
name: "someone",
}
me.sayHello(24) // hello, I am me 24 years old
- call:call 是函数的正常调用方式,并指定上下文 this。
me.sayHello.call(someone, 24) // hello, I am someone 24 years old
- apply:apply 的作用和 call 一样,只是在调用的时候,传参数的方式不同。区别是 apply 接受的是数组参数,call 接受的是连续参数。如下代码:
me.sayHello.apply(someone, [24]) // hello, I am someone 24 years old
- bind:bind方法与call、apply最大的不同就是前者返回一个绑定上下文的函数,而后两者是直接执行了函数,bind 不会立即调用,它会生成一个新的函数,你想什么时候调就什么时候调。bind方法传递给调用函数的参数可以逐个列出,也可以写在数组中。
me.sayHello.bind(someone, 24)() // hello, I am someone 24 years old
me.sayHello.bind(someone, ([24])() // hello, I am someone 24 years old
- 请说出至少 8 个 HTTP 状态码,并描述各状态码的意义。
答:
HTTP状态码共分为5种类型:
- 1**: 信息,服务器收到请求,需要请求者继续执行操作
- 2**: 成功,操作被成功接收并处理
- 3**:重定向,需要进一步的操作以完成请求
- 4**:客户端错误,请求包含语法错误或无法完成请求
- 5**: 服务器错误,服务器在处理请求的过程中发生了错误
100:继续。客户端应继续其请求
200:请求成功。一般用于GET与POST请求
201:已创建。成功请求并创建了新的资源
202:已接受。已经接受请求,但未处理完成
301:永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
305:使用代理。所请求的资源必须通过代理访问
400:客户端请求的语法错误,服务器无法理解
404:服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
- 请写出一个 HTTP post 请求的内容,包括四部分。
其中
第四部分的内容是 username=ff&password=123
第二部分必须含有 Content-Type 字段
请求的路径为 /path
答:
POST /path HTTP/1.1
Host: www.baidu.com
User-Agent: curl/7.54.0
Accept: */*
Content-Length: 24
Content-Type: application/x-www-form-urlencoded
username=ff&password=123
- 请说出至少三种排序的思路,这三种排序的时间复杂度分别为
- O(n*n)
- O(n log2 n)
- O(n + max)
答: - 冒泡排序:每次比较两个相邻的数字,小数放前面,大数放后面,这样一轮下来小的数字就拍在了前面(大的数字位置在后面确定),如此重复,直到所有的数字排完
- 快速排序:选择一个数作为”基准”。小于”基准”的元素,移到”基准”的左边;大于”基准”的元素,移到”基准”的右边。
对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。 - 计数排序:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。
- 一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?
答:
- DNS域名解析
地址栏输入的域名不是资源所在的真实位置,域名只是IP地址的一个映射,域名解析的过程
实际是将域名还原为IP地址的过程。DNS域名解析有两种方法,分别是迭代查询和递归查询。- TCP连接
通过DNS域名解析后,获取到了服务器的IP地址,便会开始建立一次连接,主要通过TCP三次握手
进行连接。
三次握手图片- HTTP请求
在确认与服务器建立连接后,便会发送一个HTTP请求,HTTP请求的报文主要包括请求行,
请求头,请求正文。- 处理请求返回HTTP响应
服务器在收到浏览器发送的HTTP请求之后,会将收到的HTTP报文封装成HTTP的Request对象,
并通过不同的Web服务器进行处理,处理完的结果以HTTP的Response对象返回,主要包括状态码,
响应头,响应报文三个部分。- 页面渲染
- 浏览器会解析HTML/SVG/XHTML产生一个DOM Tree,解析CSS产生CSS规则树,
解析Javascript,主要是通过DOM API和CSSOM API来操作DOM Tree和CSS Rule Tree。- 解析完成后,浏览器引擎会通过DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree。
- 最后通过调用操作系统Native GUI的API绘制。
- 关闭连接
在页面元素传输完成后,会选择关闭连接,此时用到的是TCP四次挥手
四次握手图片
- 如何实现数组去重?
假设有数组 array = [1,5,2,3,4,2,3,1,3,4]
你要写一个函数 unique,使得
unique(array) 的值为 [1,5,2,3,4]
也就是把重复的值都去掉,只保留不重复的值。
要求:
不要做多重循环,只能遍历一次
请给出两种方案,一种能在 ES 5 环境中运行,一种能在 ES 6 环境中运行(提示 ES 6 环境多了一个 Set 对象)
答:
1.indexOf
var array = [1,5,2,3,4,2,3,1,3,4];
function unique(array) {
var res = [];//存储数组
for (var i = 0, len = array.length; i < len; i++) {
var current = array[i];
if (res.indexOf(current) === -1) { //确定res里面没有该值
res.push(current)
}
}
return res;
}
console.log(unique(array));
2.利用空哈希存储到键值
function unique(array) {
var res = [];
var json = {};
for(var i = 0; i <array.length; i++) {
if(!json[array[i]]) {
res.push(array[i]);
json[array[i]] = 1;
}
}
return res;
}
var arr = [1,5,2,3,4,2,3,1,3,4];
console.log(unique(arr));
3.ES6 Set 对象
var array = [1,5,2,3,4,2,3,1,3,4];
function unique(array) {
return Array.from(new Set(array)); //或者return ([...new Set(array)])
//用Array.from()或者...(展开操作符)将Set对象转换为Array
}
console.log(unique(array));