记录–一些看起来很叼难的前端面试题

  • 记录–一些看起来很叼难的前端面试题已关闭评论
  • 19 次浏览
  • A+
所属分类:Web前端
摘要

「对搜索引擎不友好,并且存在跨域问题限制」搜索引擎会屏蔽掉所有baijavascript代码du, 那么ajax载入的内容对于搜索引擎来说zhi也是透明的。建议重要的页面信dao息不要AJAX。用AJAX只是载入一些相关链接或者其他跟正文和关键词关系不是很大的东西。


这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--一些看起来很叼难的前端面试题

1.ajax最大的缺陷

「对搜索引擎不友好,并且存在跨域问题限制」

搜索引擎会屏蔽掉所有baijavascript代码du, 那么ajax载入的内容对于搜索引擎来说zhi也是透明的。建议重要的页面信dao息不要AJAX。用AJAX只是载入一些相关链接或者其他跟正文和关键词关系不是很大的东西。

如果一定要做AJAX的页面,那么至少在title以及h1、h2、h3标记处不要用AJAX。否则这个页面真正的关键词搜索引擎是看不到的。

搜索引擎对AJAX很不友好,呵呵

「ajax不支持浏览器back按钮(要实现ajax下的前后退功能成本较大)。」

「不支持浏览器“后退”和“前进“键。」

2.下面这道题的输出结果

 var foo={n:1};      (function(foo){        console.log(foo.n);        foo.n=3;        var foo={n:2};        console.log(foo.n);      })(foo);     console.log(foo.n);

A:

var foo = {n:1}; (function(foo){            //形参foo同实参foo一样指向同一片内存空间,这个空间里的n的值为1     var foo;               //重复声明,无效。     console.log(foo.n);    //输出1     foo.n = 3;             //形参与实参foo指向的内存空间里的n的值被改为3     foo = {n:2};           //形参foo指向了新的内存空间,里面n的值为2.     console.log(foo.n);    //输出新的内存空间的n的值 })(foo); console.log(foo.n);        //实参foo的指向还是原来的内存空间,里面的n的值为3.

3.进程主要组成部分包括

  • ①程序。作用:描述进程要完成的功能。
  • ②数据。作用:程序在执行时所需要的数据和工作区。
  • ③ PCB。作用:包含进程的描述信息和控制信息。它是进程存在的唯一标志。 进程控制块

4.一个简单的计算机网络 3 个主要组成部分是

计算机网络通常由三个部分组成,它们是「资源子网(一系列主机)、通信子网和通信协议」.所谓通信子网就是计算机网络中负责数据通信的部分;资源子网是计算机网络中面向用户的部分,负责全网络面向应用的数据处理工作;而通信双方必须共同遵守的规则和约定就称为通信协议,它的存在与否是计算机网络与一般计算机互连系统的根本区别。所以从这一点上来说,我们应该更能明白计算机网络为什么是计算机技术和通信技术发展的产物了。

5.如果让你来设计一个批处理多道系统,首先要考虑的是

「吞吐量,系统效率」

多道批处理系统有两个特点:

  1. 多道:系统内可同时容纳多个作业。这些作业放在外存中,组成一个后备队列,系统按一定的调度原则每次从后备作业队列中选取一个或多个作业进入内存运行,运行作业结束、退出运行和后备作业进入运行均由系统自动实现,从而在系统中形成一个自动转接的、连续的作业流。
  2. 成批:在系统运行过程中,不允许用户与其作业发生交互作用,即:作业一旦进入系统,用户就不能直接干预其作业的运行。
  • 多道批处理系统的优点:资源利用率大幅提升,系统吞吐量增大
  • 缺点:用户响应时间长,没有交互功能

  • 分时操作系统解决了人机交互功能,但不能处理一些紧急任务
  • 实时操作系统的特点:及时性和可靠性
  • 分布式操作系统的特点:分布性和并行性, 系统中各个计算机地位相同,任何工作都可以分布在这些计算机上,由它们并行,协同完成

6.已知一个二叉树的后序遍历的结果为 AEFDHZMG, 那么它的中序遍历可能为()前序遍历可能为()

记录--一些看起来很叼难的前端面试题

 树结构如图,思路为:

记录--一些看起来很叼难的前端面试题

  • 寻找共同项,分别对比AB和CD
  • 得到大致结构——
  • 前序遍历:GDA _ _ MHZ
  • 中序遍历:ADEF _ _ _ Z
  • 后序遍历:AEFDHZMG
  • 然后画个图往里填空就行

7.数据链路层主要功能包括()

记录--一些看起来很叼难的前端面试题

「流量控制」涉及对链路上的帧的发送速率的控制,以使接收方有足够的缓冲空间来接收每一个帧。基本方法是由接收方控制发送方发送数据的速率,常见的方式有两种:「停止-等待协议和滑动窗口协议。」

两个结点之间如果规定了数据链路层协议,就可以检测出这些差错,然后把收到的错误信息丢弃,这就是「差错控制」功能。通常利用编码技术进行差错控制,主要有两类:「自动重传请求(ARQ)和前向纠错(FEC)」。在ARQ方式中,接收端检测出差错时,就设法通知发送端重发,直到接收到正确的码字为止。在FEC方式中,接收端不但能发现差错,而且能确定二进制数码的错误位置,从而加以纠正。因此,差错控制主要分为检错编码和纠错编码

8.请描述一下 cookies , sessionStorage 和 localStorage 的区别

记录--一些看起来很叼难的前端面试题

9.请列举 html5 本地存储( localStorage )相关 api ,并实现 getAll 方法,获取本地存储

链接:https://www.nowcoder.com/questionTerminal/4fa885ec00f347db8e7217475f731fc7 来源:牛客网

  • setItem(key,value) 添加数据
  • getItem(key) 根据key获取值
  • key(index) 根据索引获取key
  • removeItem(key) 根据key删除一条数据
  • clear() 清空数据
  • length:获取总数据的长度

getAll()这个方法我没太明白想获取什么,所以我采用了key()和getItem()方法结合获取键值对

function() {     for (let i = 0; i < localStorage.length; i++) {         let key = localStorage.key(i)         let value = localStorage.getItem(key)         console.log(key + ":" + value)     } }

10.JS中substr与substring的区别

JS中substr与substring的区别

js中substr和substring都是截取字符串中子串,非常相近,可以有一个或两个参数。

语法:substr(start [,length]) 第一个字符的索引是0,start必选 length可选

substring(start [, end]) 第一个字符的索引是0,start必选 end可选

相同点:当有一个参数时,两者的功能是一样的,返回从start指定的位置直到字符串结束的子串

var str = "hello Tony";  str.substr(6);  //Tony  str.substring(6); //Tony

不同点:有两个参数时

(1)substr(start,length) 返回从start位置开始length长度的子串

“goodboy”.substr(1,6);   //oodboy

【注】当length为0或者负数,返回空字符串

(2)substring(start,end) 返回从start位置开始到end位置的子串(「不包含end」)

“goodboy”.substring(1,6);  //oodbo

注】:

(1)substring 方法使用 start 和 end 两者中的较小值作为子字符串的起始点

(2)start 或 end 为 NaN 或者负数,那么将其替换为0

str是字符串时str.substring(start,end)和str.slice(start,end)完全等价; str是数组时str.slice(start,end)还可以继续用,str.substring(start,end)就不行了。

11.JS 截取地址栏指定字符后的内容

一、获取地址栏路径

var url = window.location.href;

二、截取指定字符后的内容

/**   * 截取指定字符后的内容   * @param url 路径   * @param parameter 字符   */ function getCaption(url,parameter) {     var index = url.lastIndexOf(parameter);     url = url.substring(index + 1, url.length);     return url; }

三、调用方法及结果

示例:

var url="http://www.baidu.com?123"; var a = getCaption(url, "?");

输出结果:123

12.以下代码的运行结果是

var game='4399' game.substring(2,1) console.log(game)

这里有两个坑,第一个是start<stop的话,会自动交换这两个参数,第二个是substring对原数组不会改变。

13.JS的重定向有哪些

location.assign("http://www.baidu.com"); location.href="http://www.baidu.com";  window.location="http://www.baidu.com"; top.location="http://www.baidu.com"; self.location="http://www.baidu.com";  window.location.href="http://www.baidu.com";

14.谈谈你对虚拟DOM原理的理解?

什么是Virtual DOM

Virtual DOM是对DOM的抽象,本质上是JavaScript对象,这个对象就是更加轻量级的对DOM的描述.

为什么需要Virtual DOM

既然我们已经有了DOM,为什么还需要额外加一层抽象?

首先,我们都知道在前端性能优化的一个秘诀就是尽可能少地操作DOM,不仅仅是DOM相对较慢,更因为频繁变动DOM会造成浏览器的回流或者重回,这些都是性能的杀手,因此我们需要这一层抽象,在patch过程中尽可能地一次性将差异更新到DOM中,这样保证了DOM不会出现性能很差的情况.

其次,现代前端框架的一个基本要求就是无须手动操作DOM,一方面是因为手动操作DOM无法保证程序性能,多人协作的项目中如果review不严格,可能会有开发者写出性能较低的代码,另一方面更重要的是省略手动DOM操作可以大大提高开发效率.

最后,也是Virtual DOM最初的目的,就是更好的跨平台,比如Node.js就没有DOM,如果想实现SSR(服务端渲染),那么一个方式就是借助Virtual DOM,因为Virtual DOM本身是JavaScript对象.

15.怎么利用img进行xss攻击

这个问题,我有点蒙蔽,我以为是 转发图片给上当者,然后就攻击了,网上找了答案,果不其然,我想错了

因为最近在学习web安全,出于好奇,尝试对CSDN进行了XSS注入,没想到真的成功了。

操作步骤:

直接找一篇博客,在底下评论

<img src="pic.gif" alt="记录--一些看起来很叼难的前端面试题" οnerrοr="javascript:this.src='/noPic.gif';" alt="pic" />

因为CSDN做了简单的转义,他会将注入的标签,去掉闭合性,也就是会把我注入的内容处理为:

<img src="pic.gif" alt="记录--一些看起来很叼难的前端面试题" οnerrοr="javascript:this.src='/noPic.gif';" alt="pic">

这样,注入的标签就失去了他的闭合性了,对一些普通的攻击就进行了防御,但是onerror事件是专门针对js出错的,所以,标签闭合性被破坏刚好触发了这个事件,所以,他会被执行,执行之后将img标签的src属性替换成我们想要的属性,然而我注入的这个地址,故意又是一个不能访问的地址,于是,就反复的触发这个onerror事件,最终导致浏览器堆栈溢出了。

说明:如果图片存在,但网络很不通畅,也可能触发 onerror。

解决方法:

- 1、用html转义,将<>转义成转义符,这样标签就编程了文本了(QQ空间的做法)   - 2、使用jsoup白名单过滤掉onerror关键字,让他不要在前台显示(这种更安全,因为转义还有可能被绕过)

16.使用一个辅助栈进行栈元素排序

设计思路

依次从栈中弹出元素,依次压入辅助栈。

如果弹出的元素比辅助栈的元素小,就将辅助栈的元素依次弹出并压入原栈,将这个较小的元素压入辅助栈,再递归。

如果弹出的元素比辅助栈的元素大,直接压入辅助栈,直至原栈为空。

记录--一些看起来很叼难的前端面试题

 代码实现

public static void sortStack(Stack<Integer> stack) {   Stack<Integer> help = new Stack<Integer>();      while(!stack.isEmpty()) {       int temp = stack.pop();       while(!help.isEmpty()&&help.peek()<temp) {   //只有当pop出来的元素值比help栈顶元素大,才会将help中的元素移回stack        stack.push(help.pop());       }       help.push(temp);    //其他不管是help为空,还是pop出来的元素值比help栈顶小,都是一律push。所以合并写一个就可以,不用再if写情况了      }            while(!help.isEmpty()) {     //最后将反序的help压回stack,顺序就对了       stack.push(help.pop());      }  } 

本文转载于:

https://juejin.cn/post/6854573209552568328

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--一些看起来很叼难的前端面试题