前端——面试(熊猫优选)

1.自我介绍
2.什么时候开始接触前端?
3.如何学习一门新技术?
4.怎么学习前端?
5.选择前端的原因?

  • 前端写出来之后直接就能看到,更有成就感。
  • JavaScript的编程风格我很喜欢,尤其是对于异步编程更好理解
  • node.js,微信小程序等框架,让前端经过一定的学习后也可以进行移动端开发。
  • 大学接触的编程语言很多,个人接触下来觉得JS是自己比较感兴趣的。

6.你觉得前端人员应该掌握哪些知识?

  • 前端基础:HTML,浏览器,CSS,JS
  • 前端核心:ajax, 服务端语言
  • 前端的流行框架和模块化开发
  • 计算机基础:了解计算机网络,数据库等

7.你觉得前端人员应该具备哪些特点?

  • 扎实的前端编程技术
  • 具有合作精神,良好的交流沟通能力
  • 理解系统整体的编程,与后端的交互等

8.你了解我们公司吗?
9.有了解react吗?他们的一个区别?

  • React:依赖组件 单向数据绑定 模板.jsx
  • Vue:依赖组件 属于MVVM模式,双向数据绑定 模板.vue

10.让你实现一个框架如何实现?
11.前端与后端的区别?

  • 前端:客户端开发,在应用程序和网站屏幕上看到的所有内容都属于前端
  • 后端:服务端开发,在后端服务器和浏览器或应用程序之间存储网站、应用数据和中间媒介的服务器都属于后端。
  • 区别
前端后端
前端 Web 开发人员需要精通 HTML,CSS 和 JavaScript。后端开发人员应该拥有数据库,服务器,API 等技能
前端开发人员团队设计网站的外观,并通过测试不断修改后端开发人员团队开发软件,并构建支持前端的数据库架构
除非网站是一个简单工作的静态网站,否则不能单独提供前端服务后端服务可以作为 BaaS(后端即服务)独立提供
前端开发人员的目标是确保所有用户都可以访问该网站或应用,并在所有视图中做出响应 —— 移动和桌面后端开发人员的目标是围绕前端构建程序,并提供所需的所有支持,并确保站点或应用始终正常运行

12.如何实现promise
我们根据 Promise 的执行顺序,手动实现一个 Promise 。

  • 顺序
    • 先执行 MyPromise 构造函数;
    • 注册 then 函数;
    • 此时的 promise 挂起, UI 非堵塞,执行其他的同步代码;
    • 执行回调函数。
  • 代码
    • 首先,我们知道promise有三种状态,pending、resolve、reject定义三个变量,
    • 然后,定义myPromise函数,内部有两个函数reject和resolve,状态都是从pending转变
    • 其次,注册.then函数,判断两个参数是否为函数类型(如果不是函数,就创建一个函数赋值给对应的参数)
    • 最后,执行回调函数
// 三种状态 
const PENDING = "pending"; 
const RESOLVE = "resolve"; 
const REJECT = "reject"; 
// promise 函数 
function MyPromise(fn){ 
	const that = this; // 回调时用于保存正确的 this 对象 
	that.state = PENDING; // 初始化状态 
	that.value = null; // value 用于保存回调函数(resolve/reject 传递的参数 ) 
	that.resolvedCallbacks = []; // 用于保存 then 中的回调 
	that.rejectedCallbacks = []; // 用于保存 catch中的回调
	// resolve 和 reject 函数 
	function resolve(value) { 
		if(that.state === PENDING){ 
			that.state = RESOLVE; 
			that.value = value; 
			that.resolvedCallbacks.map(cb => cb(that.value)); 
		} 
	}
	function reject(value) { 
		if (that.state === PENDING) { 
			that.state = REJECT 
			that.value = value 
			that.rejectedCallbacks.map(cb => cb(that.value)) 
		} 
	}
	// 实现如何执行 Promise 中传入的函数 
	try {
		fn(resolve, reject) 
	} catch (e) { 
		reject(e) 
	} 
}
// 实现 then 函数 
MyPromise.prototype.then = function(onResolved, onRejected) { 
	const that = this; 
	// 判断两个参数是否为函数类型(如果不是函数,就创建一个函数赋值给对应的参数) 
	onResolved = typeof onResolved === 'function' ? onResolved : v => v; 
	onRejected = typeof onRejected === 'function' ? onRejected : r => {throw r} 
	// 判断当前的状态 
	if (that.state === 'pending') { 
		that.resolvedCallbacks.push(onResolved) 
		that.rejectedCallbacks.push(onRejected) 
	}
	if (that.state === 'resolve') { 
		onResolved(that.value) 
	}
}
new MyPromise((resolve, reject) => { 
	setTimeout(() => { 
		resolve(1) 
	}, 0) 
	}).then(value => { 
		console.log(value) 
})

13.数组的排序实现

  • sort()

14.讲一下MVVM模式

  • MVVM分为Model、View、ViewModel三者。
  • Model:代表数据模型,数据和业务逻辑都在Model层中定义;
  • View:代表UI视图,负责数据的展示;
  • ViewModel:负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;
  • Model和View并无直接关联,而是通过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Model中同步。
    这种模式实现了Model和View的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作dom。

15.发布+订阅模式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        
    </style>
</head>
<body>

    <input type="button" id="pub1" value="第一报社"><input type="text" id="txt1" value=''> <br>
    <input type="button" id="pub2" value="第二报社"><input type="text" id="txt2" value=''> <br>
    <input type="button" id="pub3" value="第三报社"><input type="text" id="txt3" value=''> <br>

    <textarea name="" id="sub1" cols="30" rows="10"></textarea>
    <textarea name="" id="sub2" cols="30" rows="10"></textarea>
</body>
<script>
    // 发布者
    var Publish = function(name) {
        this.name = name;
        this.subscribers = []; //接受所有的订阅者(每一个元素是函数类型fn的数组)
    }
    // Publish类的实例对象发布消息的方法
    Publish.prototype.deliver = function(news) {
        var publish = this;
        this.subscribers.forEach(function(fn) {
            // 把新消息发给一个订阅者
            fn(news, publish);
        });
        // 链式编程
        return this;
    }

    // 具体的一个订阅者去订阅报纸的方法
    Function.prototype.subscribe = function(publish) {
        var suber = this; //当前订阅者
        // 数组的some : 遍历数组中的元素,执行一个函数,有一个返回true、,整体返回true
        // 检查当前这个人是不是已经订阅过了
        var isExists = publish.subscribers.some(function(item) {
            return item === suber;
        });
        if (!isExists) {
            publish.subscribers.push(suber);
        }
        // 链式编程
        return this;
    }

    // 取消订阅的方法
    Function.prototype.unsubscribe = function(publish) {
        var suber = this;
        // filter  返回一个新数组, 
        // 去掉suber
        publish.subscribers = publish.subscribers.filter(function(item) {
            return item !== suber;
        });
        return this;
    }
    var pub1 = new Publish('第一报社');
    var pub2 = new Publish('第二报社');
    var pub3 = new Publish('第三报社');
    // 定义 2个订阅者
    var sub1 = function(news) {
        document.getElementById('sub1').innerHTML += arguments[1].name + '~~~' + news + '\n';
    }

    var sub2 = function(news) {
        document.getElementById('sub2').innerHTML += arguments[1].name + '~~~' + news + '\n';
    }

    // 执行订阅方法
    sub1.subscribe(pub1).subscribe(pub2).subscribe(pub3);
    sub2.subscribe(pub1).subscribe(pub2);

    // 事件绑定
    document.getElementById('pub1').onclick = function() {
        pub1.deliver(document.getElementById('txt1').value)
    }

    document.getElementById('pub2').onclick = function() {
        pub2.deliver(document.getElementById('txt2').value)
    }

    document.getElementById('pub3').onclick = function() {
        pub3.deliver(document.getElementById('txt3').value)
    }
    sub1.unsubscribe('pub1');
</script>
</html>

16.节流和防抖

  • 节流:一定的间隔时间内只执行一次,如果这个单位时间内触发多次函数,只有一次生效。 滚动事件,鼠标点击事件
  • 防抖:事件被触发n秒后再执行回调,n秒内又被触发则重新计时

17.接触移动端吗?
18.em rem区别

  • em:当使用em单位时,像素值将是em值乘以使用em单位的元素的字体大小。em 单位转为像素值,取决于他们使用的字体大小。 此字体大小受从父元素继承过来的字体大小,除非显式重写与一个具体单位。 一般用于按钮、菜单、标题等有自己字体大小
  • rem:当使用rem单位,他们转化为像素大小取决于页根元素的字体大小,即 html 元素的字体大小。 根元素字体大小乘以你 rem 值。rem 单位翻译为像素值是由 html 元素的字体大小决定的。 此字体大小会被浏览器中字体大小的设置影响,除非显式重写一个具体单位。 一般用于媒体查询

19.判断一个字符串是否是回文

  • str.split(‘’).reverse().join(‘’);
  • 二分法:left right left < mid &&right >mid

20.$nextTick

  • JS的运行机制:JS执行是单线程,它基于事件循环,主要过程如下:
    • 所有的同步任务都在主线程上执行,形成一个执行栈
    • 主线程之外,还存在一个“任务队列”,只要异步任务有运行结果,在“任务队列中防止一个事件”
    • 一旦“执行栈”中的所有同步代码执行完毕,系统就会读取“任务队列”,异步任务结束等待状态,进入执行栈,开始执行在这个过程中,主线程的执行过程就是一个tick,所有的异步结果都通过“任务队列”调度。分为微任务和宏任务,每一个宏任务之后,都要清空所有的微任务。
  • 任务分类
    • 宏任务macro task 有 setTimeout、MessageChannel、postMessage、
      setImmediate
    • 微任务micro task 有 MutationObsever 和 Promise.then
  • 异步更新队列:
    • 可能你还没有注意到,Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
    • 如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。
    • 然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。
    • Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。
  • vue 的 nextTick 方法的实现原理:
    • vue 用异步队列的方式来控制 DOM 更新和 nextTick 回调先后执行
    • microtask 因为其高优先级特性,能确保队列中的微任务在一次事件循环前被执行完毕
    • 考虑兼容问题,vue 做了 microtask 向 macrotask 的降级方案

21.如何将.vue文件变成.html文件渲染

  • .vue—编译之后变为渲染函数—渲染虚拟DOM树(跟踪依赖关系)—渲染真实DOM

22.你遇到的最大挑战?完成之后你的成就感?

  • 在学习前端的过程中,遇到比较大的挑战是学习JS时,之前学习就像Java就是面向对象编程,但是JS是基于面向对象,有对象这个概念,又不完全是面向对象编程,没有class这个概念,关于继承与原型链一开始很难理解,最后通过查资料,看视频和前端人员博客等,搞清楚整个的一个发展规范,最后深入理解JS的这种编程思想。

23.你有什么想问我的?

  • 定期会有技术分享交流会吗?
  • 如果我有幸入职,对于我这个岗位,您对我3-5年的职业规划的建议是什么?
  • 请问贵公司对于员工有什么职业发展方面的培训吗?
  • 感谢您这次对我的面试,请问我的经历和能力,有哪些是不符合公司预期的吗?或者您觉得我有哪些方面需要加强呢?
  • 团队成员有多少人呢,前端人员大概有多少?
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值