Skip to content

Latest commit

 

History

History
282 lines (238 loc) · 10.7 KB

前端面试笔试题(2).md

File metadata and controls

282 lines (238 loc) · 10.7 KB

前端笔试面试题

HTML && CSS

清除浮动有哪些方式?比较好的方式是哪一种?
(Q1)
  (1)父级div定义height。
  (2)结尾处加空div标签clear:both。
  (3)父级div定义伪类:after和zoom。
  (4)父级div定义overflow:hidden。
  (5)父级div定义overflow:auto。
  (6)父级div也浮动,需要定义宽度。
  (7)父级div定义display:table。
  (8)结尾处加br标签clear:both。

(Q2) 比较好的是第3种方式,好多网站都这么用。

box-sizing常用的属性有哪些?分别有什么作用?

(Q1)
  box-sizing: content-box | border-box | inherit

(Q2)
  content-box:宽度和高度分别应用到元素的内容框,在宽度和高度之外绘制元素的内边距和边框(元素默认效果)。
  border-box:元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。
  通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。

为什么要使用CSS sprites

CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,
再利用CSS的“background-image”,“background-position”的组合进行背景定位,
这样可以减少很多图片请求的开销,因为请求耗时比较长;
请求虽然可以并发,但是如果请求太多会给服务器增加很大的压力。

BFC规范(块级格式化上下文:block formatting context)的理解?

W3C CSS 2.1 规范中的一个概念,它是一个独立容器,决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。 一个页面是由很多个 Box 组成的,元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box,会参与不同的 Formatting Context(决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染, 也就是说BFC内部的元素和外部的元素不会互相影响。

触发 BFC的条件,常见如下:

  1. float的值不为none。(不推荐)
  2. overflow的值为auto,scrollhidden
  3. display的值为table, table-cell, table-caption, inline-block中的任何一个。
  4. position的值不为 relativestatic。(不推荐)

JavaScript

用Javascript获取页面元素的位置

转自 阮一峰文章专栏

js有哪些内置对象?

数据封装类对象:Object、Array、Boolean、Number 和 String<br>
其他对象:Function、Arguments、Math、Date、RegExp、Error

ajax 有那些优缺点?如何解决跨域问题?

(Q1)
优点:
    (1)通过异步模式,提升了用户体验.
    (2)优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用.
    (3)Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。
    (4)Ajax可以实现动态不刷新(局部刷新)
缺点:
    (1)安全问题 AJAX暴露了与服务器交互的细节。
    (2)对搜索引擎的支持比较弱。
    (3)不容易调试。
(Q2)jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面。

JavaScript原型,原型链 ? 有什么特点?

(1)原型对象也是普通的对象,是对象一个自带隐式的 `__proto__` 属性,原型也有可能有自己的原型,
如果一个原型对象的原型不为null的话,我们就称之为原型链。
(2)原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链。

GET和POST的区别,何时使用POST?

GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符
POST:一般用于修改服务器上的资源,对所发送的信息没有限制。
GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,
也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。
然而,在以下情况中,请使用 POST 请求:
无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠。

请解释一下 JavaScript 的同源策略

概念:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。
它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。
这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。
指一段脚本只能读取来自同一来源的窗口和文档的属性。
为什么要有同源限制?
我们举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,
当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,
这样用户名,密码就轻松到手了。

Flash、Ajax各自的优缺点,在使用中如何取舍?

Flash适合处理多媒体、矢量图形、访问机器;对CSS、处理文本上不足,不容易被搜索。
Ajax对CSS、文本支持很好,支持搜索;多媒体、矢量图形、机器访问不足。
共同点:与服务器的无刷新传递消息、用户离线和在线状态、操作DOM

什么是闭包?

闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),
因而这些变量也是该表达式的一部分。闭包的特点:
(1)作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
(2) 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。
而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。
当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

WEB 安全

XSS(Cross Site Script): 跨站脚本攻击

XSS 攻击是指攻击者在网站上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式。 分为 3类:反射型(非持久型)、存储型(持久型)、基于DOM

  • 反射型 反射型 XSS 只是简单地把用户输入的数据 “反射” 给浏览器,这种攻击方式往往需要攻击者诱使用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。
  • 存储型 存储型 XSS 会把用户输入的数据 “存储” 在服务器端,当浏览器请求数据时,脚本从服务器上传回并执行。这种 XSS 攻击具有很强的稳定性。
  • 基于DOM 基于 DOM 的 XSS 攻击是指通过恶意脚本修改页面的 DOM 结构,是纯粹发生在客户端的攻击。

XSS 攻击的防范:

  • HttpOnly 防止劫取 Cookie
  • 输入、输出检查

CSRF(Cross Site Request Forgery): 跨站请求伪造

一种劫持受信任用户向服务器发送非预期请求的攻击方式。通常情况下,CSRF 攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。

CSRF 攻击的防范:

  • 验证码
  • 验证 Referer Check
  • 添加 token 验证

其他

线程与进程的区别

一个程序至少有一个进程,一个进程至少有一个线程。 线程的划分尺度小于进程,使得多线程程序的并发性高。 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。 但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。 但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

常见排序

  • 冒泡排序
function bubbleSort(arr) {
  var len = arr.length
  for(let i = 0; i < len - 1; i++) {
    for(let j = 0; j < len - 1 - i; j++) {
      if(arr[j] < arr[j + 1]) {
        var temp = arr[j + 1]
        arr[j + 1] = arr[j]
        arr[j] = temp
      }
    }
  }
  return arr
}
  • 选择排序
function selectSort(arr) {
  var len = arr.length
  var minIndex, temp
  for(var i = 0; i < len - 1; i++) {
    minIndex = i
    for (var j = i + 1; j < len; j ++) {
      if (arr[j] < arr[minIndex]) {
        minIndex = j
      }
    }
    temp = arr[i]
    arr[i] = arr[minIndex]
    arr[minIndex] = temp
  }
}
  • 快速排序
function quickSort(arr) {
  var len = arr.length
  if (len <= 1) {
    return arr
  }
  var priotIndex = Math.floor(len / 2)
  var priot = arr.splice(priotIndex, 1)[0]
  var left = []
  var right = []
  for (var i = 0; i < arr.length ; i++) {
    if (arr[i] < priot) {
      left.push(arr[i])
    } else {
      right.push(arr[i])
    }
  }
  return quickSort(left).concat(priot, quickSort(right))
}
  • 插入排序
function insertSort(arr) {
  var len = arr.length
  var preIndex, current
  for(var i = 1; i< len; i++) {
    preIndex = i - 1
    current = arr[i]
    while(preIndex >= 0 && arr[preIndex] > current) {
      arr[preIndex + 1] = arr[preIndex]
      preIndex--
    }
    arr[preIndex + 1] = current
  }
  return arr
}
  • 归并排序
function mergeSort(arr) {
  var len = arr.length
  if (len < 2) {
    return arr
  }
  var middle = Math.floor(len / 2)
  var left = arr.slice(0, middle)
  var right = arr.slice(middle)
  return merge(mergeSort(left), mergeSort(right))
}

function merge(left, right) {
  var result = []
  while(left.length && right.length) {
    if (left[0] <= right[0]) {
      result.push(left.shift())
    } else {
      result.push(right.shift())
    }
  }
  if (left.length) {
    result = result.concat(left.reverse())
  }
  if (right.length) {
    result = result.concat(right.reverse())
  }
  return result
}