阶段exam 2018-05-09

  1. 写出一个符合W3C规范的HTML文件,要求
    i. 页面标题为“我的页面”
    ii. 页面中引入一个外部CSS文件,路径为/style.css
    iii. 页面中引入另一个外部CSS文件,路径为/print.css,该文件仅在在打印时生效
    iv. 页面中引入了另一个外部CSS文件,路径为/mobile.css,该文件仅在设备宽度小于500像素时生效
    v. 页面中引入一个外部JS文件,路径为/main.js
    vi. 页面中引入另一个外部JS文件,路径为/gbk.js,文件编码为GBK
    vii. 页面中有一个SVG标签,SVG里面有一个直径为100像素的圆圈,颜色随意
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./style.css">
    <link rel="stylesheet" href="./print.css" media="print">
    <link rel="stylesheet" href="./mobile.css" media="(max-width:500px)">
    <script src="./main.js"></script>
    <script src="./gbk.js" charset="gbk"></script>
    <title>我的页面</title>
</head>
<body>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <circle cx="100" cy="100" r="50" stroke="red" fill="none">
    </svg>
</body>
</html>
  1. 移动端是怎么做适配的?
    回答要点:
    i. meta viewport
    ii. 媒体查询(参考CSS学习笔记)
    ii. 动态rem方案(参考CSS学习笔记)
  • 设置移动端自适应要添加meta标签,它可以防止手机页面模拟980像素宽度、防止用户缩放页面
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
  • 通过媒体查询可以设置满足不同查询条件时,显示不同样式(用在style标签内或者link外部CSS文件都可以),所以可以根据手机页面宽度来调整对应CSS做适配,例如
//当屏幕宽度小于500px时,背景颜色变红
<style>
  @media(max-width: 500px) {
    body {
    background: red;
    }
  }
</style>
//当屏幕宽度小于500px时,引入一个CSS文件
<link rel="stylesheet" media="(max-width:500px)" href="./style.css">
  • 首先rem等于根元素的font-size,将根元素的font-size设置成viewport的宽度时,1rem==html font-size==viewport width,我们使用rem作为长度单位就可以将一切大小按视口宽度的比例呈现,所以移动端适配可以使用动态rem方式。为了不使小数太小,使用不便,让根元素font-size的十分之一作为1rem比较合适。以下两种方式可以实现动态rem:
    i. js动态调整rem
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script>
  var pageWidth = window.innerWidth
  document.write('<style>html {font-size:'+pageWidth/10+'px;}</style>')
</script>

ii. SCSS实现动态rem
在scss文件里添加如下代码,可以实现px自动变rem

@function px($px) {
  @return $px/$designWidth*10 + rem;
}
$designWidth: 640;//设计稿宽度
.child{
  width: px(320);
  height: px(160);
  margin: px(40) px(40);
  border: 1px solid red;
  float: left;
  font-size: 1.2em;
}

小知识点:

  1. 在 SCSS 里使用 PX2REM
  • npm config set registry [https://registry.npm.taobao.org/](https://registry.npm.taobao.org/ "null")
  • touch ~/.bashrc
  • echo 'export >SASS_BINARY_SITE="[https://npm.taobao.org/mirrors/node-sass"'](https://npm.taobao.org/mirrors/node-sass%22' "null") >> ~/.bashrc
  • source ~/.bashrc
  • npm i -g node-sass
  • mkdir ~/Desktop/scss-demo
  • cd ~/Desktop/scss-demo
  • mkdir scss css
  • touch scss/style.scss
  • start scss/style.scss
  • node-sass -wr scss -o css
  1. 页面默认字体大小(font-size)为16px;Chrome有默认最小字号12px,设置比12px小的话也会自动变成12px。
  2. rem 可以与其他单位同时存在,像border、font-size这样很小的可以就用px而不用rem。
  1. CSS3如何实现圆角矩形和阴影?
  • 圆角用 border-radius属性
    语法border-radius: 1-4 length|% / 1-4 length|%;
    圆角的半径可以用(数值+单位)或百分比确定,值为4个时,分别表示左上角、右上角、右下角、左下角;值为3个时,分别表示左上角、右上角和左下角、右下角;值为2个时,分别表示左上角和右下角、右上角和左下角;值为1个时,四个角相同。
  • 阴影用 box-shadow属性
    语法box-shadow: h-shadow v-shadow blur spread color inset;
含义
h-shadow 必选,水平阴影,可正负值。
v-shadow 必选,垂直阴影,可正负值。
blur 可选,模糊距离。
spread 可选,阴影大小。
color 可选阴影颜色。
inset 可选,从外层阴影(开始时)改变阴影内侧阴影。
  1. 什么是闭包?闭包的用途?
  • 如果一个函数用到了它范围外的变量,那么这个函数+这个变量就叫闭包。(芳芳的定义)
  • 闭包就是能够读取其他函数内部变量的函数,在JavaScript中就是“定义在一个函数内部的子函数”,是连接函数内部和外部的桥梁。(阮一峰的定义)
  • 闭包的用途:一是可以读取函数内部的变量;二是记住诞生环境,让这些变量始终保持在内存中;三是封装对象的私有属性和私有方法。

示例1-读取函数内部变量

function f1() {
 var n = 900
 function f2() {
   console.log(n)
 }
 return f2
}
var result = f1()
result()//900

示例2-保留外层函数的内部变量

function createIncrementor(start) {
 return function() {
   return start+=1
 }
}
var inc = createIncrementor(5)
console.log(inc())//6
console.log(inc())//7
console.log(inc())//8,每一次调用都是在上一次调用的基础上进行计算

示例3-封装对象的私有属性和私有方法

function Person(name) {
 var age
 function setAge(n) {
   age = n
 }
 function getAge() {
   return age
 }
 return {
   name: name,
   setAge: setAge,
   getAge: getAge 
 }
}
var p1 = Person('Jack')
p1.setAge(18)
p1.getAge()
console.log(p1.getAge())//18
//函数Person的内部变量age通过闭包getAge和setAge,变成返回对象p1的私有变量。
  1. call、apply、bind的用法是什么?
  • JavaScript提供call、apply、bind三个方法来切换/固定this的指向。
  • call方法可以指定函数内部this的指向(即函数执行时所在的作用域),然后在指定的作用域种调用该函数。
var obj = {}
var f = function () {
  return this
}
f(obj) === window//true
f.call(obj) === obj//true

call方法的参数应该是个对象,如果为空、null、undefined则默认传入全局对象,如果是一个原始值,会自动转成对应的包装对象再传入call。

  • apply与call非常相似,不同之处在于提供参数方式,call()使用的是若干个参数的列表,而apply()使用的是一个包含若干参数的数组(或类数组对象)
  • bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。
//创建绑定函数
this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域

// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81

bind()的用法还有以下:
i. 使一个函数拥有预设的初始参数,初始参数在this之后,且在传入参数之前的位置。
ii. 配合set Timeout。
iii. 快捷调用。例如将类数组对象转换成真正的数组:

// 1.使用apply方法
function fun1() {
  var slice = Array.prototype.slice;
  return slice.apply(arguments);
}
fun1(1,2,3);//[1,2,3]

// 2.使用call(或apply)和bind方法一起
function fun2() {
  var unboundSlice = Array.prototype.slice;
  // 把函数的call方法绑定在数组slice方法上,之后再给call方法传递参数,这里call换成apply也可以。
  var slice = Function.prototype.call.bind(unboundSlice);
  return slice(arguments);
}
fun2(1,2,3);//[1,2,3]
  1. 有哪些HTTP状态码和意义?
状态码 含义
1xx 不常用
200 请求成功,请求所希望的响应头或数据体会随此响应返回。
204 服务器成功处理了请求,但不需要返回任何实体内容。
301 被请求资源已永久移动到新位置
302 请求资源临时搬到新的位置
400 1.语义有误,当前请求无法被服务器理解;2.请求参数有误。
401 当前请求需要用户验证。
403 服务器已经理解请求,但拒绝执行。
404 请求失败,请求资源未在服务器上发现。
500 服务器出错,无法处理请求。
503 临时性服务器维护或过载,无法处理请求。
  1. 写出一个HTTP post请求的内容,包括四部分。
    其中
    i. 第四部分的内容是username=ff&password=123
    ii. 第二部分必须包含Content-Type字段
    iii. 请求的路径为/path
  • curl -X POST -d "username=ff&password=123" -s -v -- "http://www.baidu.com"

POST /path HTTP/1.1
Host: www.baidu.com
User-Agent: curl/7.55.0
Accept: /
Content-Length: 24
Content-Type: application/x-www-form-urlencoded

username=ff&password=123

  1. 说出至少三种排序的思路,这三种排序的时间复杂度分别为O(n*n)、O(n log2 n)、O(n+max)
  • 时间复杂度O(n*n),冒泡排序、插入排序
    冒泡排序思路:假设是要从小到大排序,就将要排序的数组,从下标0的数开始往后比较相邻的两个数,小的放前面、大的放后面,一轮下来最大的数就冒到最后面了,接下来每轮继续重复比较和换序,除了后面已确定位置的数,直到没有需要比较的数为止,也是轮数为(数组长度-1)轮为止。
  • 时间复杂度O(n log2 n),快速排序、堆排序
    快速排序思路:假设是要从小到大排序,在要排序的数组中任意选一个数,将其他所有数与这个数比较,小的都放其前面,大的都放其后面,再分别在这两部分中采用同样方法进行排序,直到每个部分都没有数可以比较
  • 时间复杂度O(n+max),基数排序:
    基数排序思路:准备10个桶,编号0,1,2...9,按个位数分配入桶(个位数为0的进0号桶,个位数为1的进1号桶),全部入桶后按桶的编号依次取出(同一个桶先入的数先取出),完成一趟排序,接着依次按十位数、百位数逐步到最高位的数字重复以上分配入桶、取出步骤(没有高位的该位数视为0)。
  • 排序可视化:https://visualgo.net/bn/sorting
  1. 一个页面从输入URL到页面加载显示完成,这个过程中都发生了什么?
  • i. 分析URL。URL包括几个部分:协议、网络地址、资源路径;协议是网络数据交换的规则、标准或约定的集合,譬如HTTP、FTP协议;网络地址可以是域名或者IP地址,可以包括端口号。
    ii. 域名解析。如果地址不是IP地址,通过DNS进行域名解析,将域名解析成对应的IP地址。解析过程:浏览器搜索自己的DNS缓存——>搜索操作系统种的DNS缓存——>搜索操作系统的hosts文件——>发送域名到本地域名服务器查询——>向根域名服务器查询——> 向顶级域名服务器查询,找到IP地址返回给浏览器,浏览器将IP地址缓存。
    iii. 如果地址不包含端口号,根据协议确定一个默认端口,譬如HTTP默认80端口。
    iv. 建立连接。向获得的IP地址的端口建立连接——三次握手:
    (1)主机向服务器发送建立连接的请求;
    (2)服务器收到请求后发送同意连接的信号;
    (3)主机收到同意连接信号后,再次向服务器发送确认信号;建立连接。
    v. 浏览器发起HTTP请求。HTTP请求包括请求方法、资源路径、协议/版本、相关内容等。
    vi. 服务器接收并返回响应。HTTP响应包括协议/版本、状态码、状态解释、要下载的内容等。
    vii. 浏览器下载相应内容,渲染、显示页面。
    viii. 断开连接——四次挥手:
    (1)主机向服务器发送断开连接的请求;
    (2)服务器收到请求后发送同意断开的信号;
    (3)服务器向主机发送断开通知;
    (3)主机收到断开通知后,断开连接,并再次向服务器发送确认信号,服务器收到信号后断开连接。

IP地址:IP协议为互联网上的每个网络和每台主机分配的一个逻辑地址,相当于门牌号。
DN域名:IP地址由四个数字组成,中间有点号连接,比较难记容易输错,所以用有意义的字母、数字组合代替纯数字IP,这个就叫域名。例如百度域名www.baidu.com,比它的IP220.181.112.224好记很多。
DNS域名系统:每个域名对应一个或多个提供相同服务器的IP地址,只有知道服务器IP地址才能建立连接,这就需要DNS把域名解析成IP地址。

  1. 如何实现数组去重?
    假设有数组array=[1,5,2,3,4,2,3,1,3,4],写出一个函数unique,使得unique(array)的值为[1,5,2,3,4]。要求:
    i. 不要做多重循环,只能遍历一次
    ii. 请给出两种方案,一种能在ES5环境中运行,一种能在ES6环境中运行(提示:ES6环境中多了一个Set对象)
//ES5中
function unique(array) {
  var newArray = []
  var hash = {}
  for(var i = 0;i < array.length;i++) {
    if(!hash[array[i]]) {
      newArray.push(array[i])
      hash[array[i]] = 1
    }
  }
  return newArray
}
var array = [1,5,2,3,4,2,3,1,3,4]
console.log(unique(array))
//ES6中
function unique(array) {
  return [...new Set(array)]
}
var array = [1,5,2,3,4,2,3,1,3,4]
console.log(unique(array))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容