前端笔试题1

HTML/CSS

题1: 

1.使用CSS 让该节点不可见,方法越多越好。

使用CSS 让节点不可见的方法有以下几种:

  • 把 visibility 属性设置为 hidden,这样元素框不会被绘制,但仍然占据布局空间https://developer.mozilla.org/zh-CN/docs/Web/CSS/visibility
  • 把 display 属性设置为 none,这样元素框不会被显示,也不会占据布局空间https://www.runoob.com/css/css-display-visibility.html
  • opacity 属性设置为 0,这样元素框会变成完全透明,但仍然可以响应事件。

  前端笔试题1_第1张图片 

 题2:

2.在哪些场景下用过 position 的哪些值,它们分别有什么特性?

你好,这是Bing。

根据搜索结果,我发现position属性有以下五个值:

  • static:默认值,元素按照正常的文档流进行排列,不受其他定位属性的影响
  • relative:相对定位,元素相对于自己原来的位置进行偏移,但仍然占据文档流中的位置
  • absolute:绝对定位,元素脱离文档流,相对于最近的非static定位的祖先元素进行定位
  • fixed:固定定位,元素脱离文档流,相对于浏览器窗口进行定位,不随滚动条移动31。
  • sticky:粘性定位,元素在滚动时切换为固定定位,相对于最近的滚动祖先和包含块进行定位

前端笔试题1_第2张图片 前端笔试题1_第3张图片

前端笔试题1_第4张图片

JavaScript

题3:

3. 什么是单线程?什么是单线程昇步?

单线程和单线程异步的区别是:

  • 单线程是指一个程序或一个进程只能同时执行一个任务,不能同时处理多个任务。
  • 单线程异步是指单线程程序在遇到耗时的操作(如网络请求,定时任务等)时,不会等待其完成,而是继续执行后续的代码,当耗时的操作完成后,再通过回调函数或事件通知单线程程序进行处理。

单线程异步的优点是可以提高程序的效率和响应速度,避免阻塞代码的执行。单线程异步的缺点是代码的逻辑和顺序会变得复杂,需要注意回调地狱和错误处理等问题。

 题4:

	// 4. The output of the following program is
		var fn =[]
		for (var i = 0; i < 10; i++) {
			fn[i] = function (param){
			console.log(i + param)
			}
		}
		fn [5](5)
		var data = {a: 10, b: 20}
		console.log('第'+i+'条数据:'+data)

前端笔试题1_第5张图片

这段代码的输出是:

15
第10条数据:[object Object]

这是因为var声明的变量会发生变量提升(hoisting),而且没有块级作用域(block scope),所以i的值在循环结束后是10,而不是5。所以,当调用fn[5](5)时,打印出的是i + param,即10 + 5 = 15。然后,打印出'第'+i+'条数据:'+data,即’第10条数据:’ + ‘[object Object]’。如果想要打印出5 + 5 = 10,可以使用let声明变量,它会创建块级作用域,每次循环都会创建一个新的变量。

题5:

	// 5. The output of the following program is
		console.log(1)
		setTimeout(() => {
			console.log(2)
		}, 0)
		console.log(3)
		new Promise((resolve, reject) => {
		console.log(4)
		resolve()
		}).then(() => {
		console.log(5)
		}, () => {
		console.log(6)
		})
		console.log(7)

前端笔试题1_第6张图片

这段代码的输出是:

1
3
4
7
5
2

这是因为JavaScript是单线程的,它会先执行同步代码,然后再执行异步代码。异步代码又分为微任务(microtask)和宏任务(macrotask),微任务的优先级高于宏任务。setTimeout是一个宏任务,Promise.then是一个微任务。所以,同步代码会按照顺序打印出1、3、4、7,然后微任务队列中的Promise.then会打印出5,最后宏任务队列中的setTimeout会打印出2。

 题6:

// 5. The output of the following program is
			const a=[1,1,1,1,1]
			for (let i = 0; i< 5; i++) {
				for (let j = 0; j < i; j++) {
					a[i] = a[i]+ a[j]
				}
			}
			for (let i = 0; i < 5; i++){
			console.log(a[i])
			}

前端笔试题1_第7张图片

 这段代码的输出是:

1
2
4
8
16

这是因为这段代码实现了一个斐波那契数列(Fibonacci sequence),它的规律是每一项都等于前两项之和。所以,a[1] = a[0] + a[0] = 1 + 1 = 2,a[2] = a[1] + a[0] = 2 + 1 = 4,以此类推。

 题7:

// 7.写出①所在的 while循坏的作用;补全②的代码。
			// isSymmetry 用来判断正整数n是否是一个对称数,例:12321是对称数,而123不是
			function isSymmetry (n) {
			let i=n 
			let j=0
			// ①
			while (i) {
			j=j*10+i%10
			i=parseint(i/10)
			// return ②
			console.log(isSymmetry (12321)) // true 
			console.log(isSymmetry (1231)) // false

这段代码的①所在的while循环的作用是将n的每一位反转,得到一个新的数j。例如,如果n是12321,那么j就是12321;如果n是1231,那么j就是1321。

补全②的代码的一种可能方法是:

return j === n

这样就可以判断j和n是否相等,如果相等,说明n是一个对称数,返回true;如果不相等,说明n不是一个对称数,返回false。

 题8:

// 8. 把数组倒序輸出(不是排序)(不能用内置方法)
			const arr = ['name', 'first', '5', 7, 4, '2', 9]

一种把数组倒序输出的方法是:

const arr = ['name', 'first', '5', 7, 4, '2', 9]
let len = arr.length // 获取数组长度
for (let i = len - 1; i >= 0; i--) { // 从后往前遍历数组
  console.log(arr[i]) // 输出每一项
}

这样就可以得到以下输出:

9
2
4
7
5
first
name
``

题9:

// 9(过一面必做题)数组中的重复项最多出现N次。(时间复杂度越低得分越高)
			原题9.1:
			outputNth([1, 1, 1, 11], 2) // return[1,1])(按原数组出现的先后返回,合并到一起)
			outputNth([20,37,20,20, 21],2)//return [20,20,37,21](按原数组出现的先后返回,合并到一起)
			原题9.2:
			如果要求outputNth([20,37,20,20,21],2)//return [20,37,20,21]呢?(按原数组出现的先后返回)
			题9.1: function outputNth (array.n){
			题9.2:function outputNth (array, n){}请预估自己的时间复杂度:}请预估自己的时间复杂度:

这两道题都可以用一个哈希表(hash table)来记录每个元素出现的次数,然后遍历数组,根据不同的要求输出结果。具体的代码如下:

题9.1:

function outputNth(array, n) {
  let hash = {} // 创建一个空的哈希表
  let result = [] // 创建一个空的结果数组
  for (let num of array) { // 遍历数组中的每个元素
    if (hash[num]) { // 如果哈希表中已经有这个元素
      hash[num]++ // 将其出现次数加一
    } else { // 如果哈希表中没有这个元素
      hash[num] = 1 // 将其出现次数设为一
    }
    if (hash[num] <= n) { // 如果这个元素出现次数小于等于n
      result.push(num) // 将其加入结果数组
    }
  }
  return result // 返回结果数组
}

题9.2:

function outputNth(array, n) {
  let hash = {} // 创建一个空的哈希表
  let result = [] // 创建一个空的结果数组
  for (let num of array) { // 遍历数组中的每个元素
    if (hash[num]) { // 如果哈希表中已经有这个元素
      hash[num]++ // 将其出现次数加一
    } else { // 如果哈希表中没有这个元素
      hash[num] = 1 // 将其出现次数设为一
    }
    if (hash[num] === n) { // 如果这个元素出现次数等于n
      result.push(num) // 将其加入结果数组
    } else if (hash[num] < n) { // 如果这个元素出现次数小于n
      result.push(num) // 将其加入结果数组
      result.push(null) // 同时在后面加入一个空值,用来占位,方便后面删除多余的元素
    }
  }
  return result.filter(item => item !== null) // 返回结果数组,并过滤掉空值
}

这两道题的时间复杂度都是O(n),因为只需要遍历一次数组,哈希表的查找和插入操作都是常数时间。

题10: 

前端笔试题1_第8张图片

 前端笔试题1_第9张图片

 

可以参考一下:

// 定义一个栈类
class Stack {
  // 构造函数,初始化一个空数组作为栈
  constructor() {
    this.items = []
  }

  // 入栈操作,将元素添加到栈顶
  push(element) {
    this.items.push(element)
  }

  // 出栈操作,将栈顶元素移除并返回
  pop() {
    return this.items.pop()
  }

  // 查看栈顶元素,不改变栈
  peek() {
    return this.items[this.items.length - 1]
  }

  // 判断栈是否为空
  isEmpty() {
    return this.items.length === 0
  }

  // 获取栈的大小
  size() {
    return this.items.length
  }

  // 清空栈
  clear() {
    this.items = []
  }

  // 打印栈中的元素
  print() {
    console.log(this.items.toString())
  }
}

// 创建一个栈对象
let stack = new Stack()

// 测试入栈操作
stack.push(5)
stack.push(8)
stack.push(11)
stack.push(15)

// 测试打印操作
stack.print() // 输出 [5,8,11,15]

// 测试出栈操作
console.log(stack.pop()) // 输出 15
console.log(stack.pop()) // 输出 11

// 测试查看操作
console.log(stack.peek()) // 输出 8

// 测试其他操作
console.log(stack.isEmpty()) // 输出 false
console.log(stack.size()) // 输出 2

// 测试清空操作
stack.clear()
console.log(stack.isEmpty()) // 输出 true

这就是完整的代码,你可以运行一下看看效果。希望这能帮助你理解栈这种数据结构。

 

你可能感兴趣的:(前端面试笔试,前端,javascript,开发语言)