闪银奇异面试

1、promise原理: https://blog.csdn.net/u014775861/article/details/78030508
2、事件环机制: 函数执行前入栈,执行后出栈。如若遇到了一些异步操作像回调函数以及ajax、setTimeout等,会先将他们交给浏览器的其他模块去执行,执行完后,会把回调函数放入到taskqueue中。当所有的call stack执行完后再开始执行task queue中的函数。 
3、事件队列: macro-task 包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。 
                    micro-task 包括:process.nextTick,  Promises , Object.observe, MutationObserver 
                    执行顺序:函数调用栈清空只剩全局执行上下文,然后开始执行所有的micro-task。当所有可执行的micro-task执行完毕之后。循环再次执行macro-task中的一个任务队列,执行完之后再执行所有的micro-task,就这样一直循环。

例子:

(function test() {
    setTimeout(function() {console.log(4)}, 0);
    new Promise(function executor(resolve) {
        console.log(1);
        for( var i=0 ; i<10000 ; i++ ) {
            i == 9999 && resolve();
        }
        console.log(2);
    }).then(function() {
        console.log(5);
    });
    console.log(3);
})()

1. 遇到setTimeout,交给其他模块执行,执行完后回调放入macro-task中 
2. 遇到Promise,立即执行里面的function,输出1。 
3. 循环开始,遇到resolve(),修改Promise状态为fulfill。继续执行,输出2。 
4. 遇到then,将回调放入micro-task中。 
5. 继续执行,输出3。 
6. call stack执行完毕了。开始执行micro-task中的回调函数,输出5。 
7. micro-task执行完毕,开始执行macro-task中的回调函数,输出4。 

8. 结束。

4、slot 插槽: 让组件拓展性更强

  1. 1.匿名slot使用

    //定义组件my-component
    <div class="myComponent">
      <slot></slot>
    </div>
    //使用方法
    <my-component>
      <p>我就是slot的替代内容,这里可以放任何标签元素,即使是一长串ul>li列表</p>
    </my-component>

    2.具名slot使用

    //定义组件my-component
    <div class="myComponent">
      <slot name="mySlot"></slot>
    </div>
    //使用方法
    <my-component>
      <p slot="mySlot">我就是这个叫mySlot的slot替代内容,这里可以放任何标签元素,即使是一长串ul>li列表,但是我是一个有名字的宝宝,所以你必须给我加上slot="mySlot",不然我就报错给你看!</p>
    </my-component>

    如果不在有slot的组件里加入任何标签,slot什么都不会显示的。

5、vue路由传值:  query    params   动态路由

            params有两种方法:https://blog.csdn.net/k491022087/article/details/70232965

            1、显示在url中

            main.js params传值是通过 :[参数值] 如path: "/home/game/:num"      

            home.vue 在home中具体的值就跟在路径后面,如 “/home/game/123”,也就是说传递给子路由的值就是 123

            game.vue 在子路由中,通过 this.$route.params.参数名来接受传递过来的值

            2、不显示在url中

             只需将上面的main.js中的定义路由改为如下样子,在子路由中通过name来给路径其一个game1的别名。

            home.vue 中router-link修改为:to="{ name:'game1', params: {num: 123} }" params中是要传递的参数,这样传递的参数就不会显示在url中。       

      6、vue生命周期https://segmentfault.com/a/1190000010336178

生命周期钩子 详细
beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
created 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用。
mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。
activated keep-alive 组件激活时调用。
deactivated keep-alive 组件停用时调用。
beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
  • created和mounted区别:挂载

7、Vuex中mutations和actions的区别

mutaions 同步 ;actions 异步

    区分 actions 和 mutations 并不是为了解决竞态问题,而是为了能用 devtools 追踪状态变化

    事实上在 vuex 里面 actions 只是一个架构性的概念,并不是必须的,说到底只是一个函数,你在里面想干嘛都可以,只要最后触发 mutation 就   行。异步竞态怎么处理那是用户自己的事情。

vuex 真正限制你的只有 mutation 必须是同步的这一点(在 redux 里面就好像 reducer 必须同步返回下一个状态一样)。同步的意义在于这样每一个 mutation 执行完成后都可以对应到一个新的状态(和 reducer 一样),这样 devtools 就可以打个 snapshot 存下来,然后就可以随便 time-travel 了。如果你开着 devtool 调用一个异步的 action,你可以清楚地看到它所调用的 mutation 是何时被记录下来的,并且可以立刻查看它们对应的状态。

亲测: 如果在mutation中做了异步操作,在dev-tools中会立即打印一个snapshot,而此时异步操作还没有执行完,此时的snapshot的信息是错误的。

而在action中做异步操作dev-tools会等等异步操作执行完才去打印mutation的一个snapshot,这样便于我们回查time-travel,查看在某个mutation里的变化。

8、jQuery和vue的区别
         jq是一个工具库操作dom对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于,可以更方便的选取和操作DOM对象,而数据和界面是在一起
         vue是超轻量级框架操作数据对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。
9、对vue组件化的理解
    vue中的组件是一个自定义标签, Vue.js的编译器为它添加了特殊功能。 vue也可以扩展原生的html元素, 封装可重用的代码

组件的基本组成:样式结构、行为逻辑、数据

组件化开发的好处:提高开发效率、方便重复使用、简化调试步骤、提升整个项目的可维护性、便于协同开发

10、怎么防止跨域攻击(CSRF)https://blog.csdn.net/xuaman/article/details/54340290

CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的

CSRF的防御可以从服务端客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。

     (1).Cookie Hashing(所有表单都包含同一个伪随机值):在表单里增加Hash值,以认证这确实是用户发送的请求。 然后在服务器端进行Hash值验证

            (2).验证码

            (3).One-Time Tokens(不同的表单包含一个不同的伪随机值)

11、web前端攻击及防御措施   https://blog.csdn.net/vivian_jay/article/details/58667283

一、XSS

1、Reflected XSS   2、Stored XSS   3、DOM-based XSS

防御措施:

  1. 对所有用户提交内容进行可靠的输入验证,包括对URL、查询关键字、HTTP头、POST数据等,仅接受指定长度范围内、采用适当格式、采用所预期的字符的内容提交,对其他的一律过滤。
  2. 实现Session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查,以防功能被第三方网站所执行。
  3. 确认接收的的内容被妥善的规范化,仅包含最小的、安全的Tag(没有javascript),去掉任何对远程内容的引用(尤其是样式表和javascript),使用HTTP only的cookie。
  4. 使用HTTPS

二、 CSRF

防御措施

  1. 验证 HTTP Referer 字段 ;
  2. 在请求地址中添加 token 并验证 ;
  3. 在 HTTP 头中自定义属性并验证
  4. 正确使用GET,POST和Cookie;
  5. 在非GET请求中增加伪随机数;

三、SQL注入

防御措施

  1. 采用sql语句预编译和绑定变量,是防御sql注入的最佳方法。采用JDBC的预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。

  2. 使用正则表达式来过滤一些sql关键字,如or、where等。

四、cookie窃取和session劫持

五、钓鱼攻击【重定向攻击】

防御措施 

对所有的重定向操作进行审核,以避免重定向到一个危险的地方.

  1. 常见解决方案是白名单,将合法的要重定向的url加到白名单中,非白名单上的域名重定向时拒之;
  2. 重定向token,在合法的url上加上token,重定向时进行验证.

六、Http Heads攻击

防御措施 

过滤所有的response headers,除去header中出现的非法字符,尤其是CRLF。

七、拒绝服务攻击【DoS】

防御措施 

对于SYN flood:启用SYN Cookie、设置SYN最大队列长度以及设置SYN+ACK最大重试次数。

八、文件上传攻击

分类

  1. 文件名攻击:上传的文件采用上传之前的文件名,可能造成客户端和服务端字符码不兼容,导致文件名乱码问题;文件名包含脚本,从而造成攻击.
  2. 文件后缀攻击:上传的文件的后缀可能是exe可执行程序,js脚本等文件,这些程序可能被执行于受害者的客户端,甚至可能执行于服务器上.因此我们必须过滤文件名后缀,排除那些不被许可的文件名后缀.
  3. 文件内容攻击:IE6有一个很严重的问题 , 它不信任服务器所发送的content type,而是自动根据文件内容来识别文件的类型,并根据所识别的类型来显示或执行文件.如果上传一个gif文件,在文件末尾放一段js攻击脚本,就有可能被执行.这种攻击,它的文件名和content type看起来都是合法的gif图片,然而其内容却包含脚本,这样的攻击无法用文件名过滤来排除,而是必须扫描其文件内容,才能识别。

防御措施

  1. 文件上传的目录设置为不可执行。
  2. 判断文件类型。在判断文件类型的时候,可以结合使用MIME Type,后缀检查等方式。因为对于上传文件,不能简单地通过后缀名称来判断文件的类型,因为攻击者可以将可执行文件的后缀名称改为图片或其他后缀类型,诱导用户执行。
  3. 对上传的文件类型进行白名单校验,只允许上传可靠类型。
  4. 上传的文件需要进行重新命名,使攻击者无法猜想上传文件的访问路径,将极大地增加攻击成本。
  5. 限制上传文件的大小。
  6. 单独设置文件服务器的域名。

12、28种设计模式

1.   简单工厂模式:定义:用一个单独的类完成创建对象的过程,即工厂类。理解:生产对象的工厂,由参数生成相应的对象,容易扩展,扩展的同时不需要也不影响现有功能。

2.   策略模式:定义:它定义了算法家族,分别封装起来,让它们直接可以互相替换,此模式让算法的比啊好,不会影响到使用算法的客户。理解:可以理解为“受保护的简单工厂模式”,把简单工厂模式封装起来,通过协调类调用工厂,对客户端完全屏蔽工厂。

3.   单一职责原则:定义:就一个类而言,应该仅有一个引起它变化的原因。理解:类的职责单一化,减少类的负担。

4.   开放-封闭原则:定义:软件实体(类、模块、函数等等)应该可以扩展,但是不可更改。理解:对修改封闭,对扩展开放。解决方法是抽象,用抽象是隔离变化。

5.   依赖倒转原则:定义:高层模块不应该依赖于底层模块,两个都应该依赖于抽象。抽象不应该依赖细节,细节应该依赖抽象。理解:依赖倒转原则是“封闭-开放”原则实现的方针、指导思想。

6.   里氏代换原则:定义:子类型必须能够替换掉他们的父类型。理解:以抽象类或接口为父类,在使用时,以父类类型的“对象变量”作为参数,这样就可以接受任何一个继承抽象类或者实现接口的类的子类(的实例),相当于子类代换了父类,利用多态,可以完美实现“修改封闭,扩展开放”。

7.   装饰模式:定义:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。理解:把人和服饰分离,即高层模块不应该依赖底层模块,通过服饰抽象类(接口),很好的进行了分离,人使用接口,扩展时实现接口,体现了依赖于抽象的原则。

8.   代理模式:定义:为其他对象提供一种代理以控制对这个对象的访问。理解:无,非常简单。

9.   工厂方法模式:定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。理解:把工厂看成一个接口,让工厂的每个创建对象的功能去实现这个接口,去创建不同的对象,通过抽象,分解了工厂,从而封闭了修改,添加工厂新成员只需添加实现接口的类即可。但是这样无形的把判断创建哪个对象的压力(职责)放在了客户端,使客户端变得复杂,不是很好的办法。

10.   原型模式:定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。理解:原型模式就是实现ICloneable接口,实现这个接口唯一的Clone方法克隆自己。需要重点理解MenberwiseClone方法。理解后可知:浅复制就是克隆本身,完全遵从MenberwiseClone方法的规则(克隆新对象,字段复制,引用只复制引用),即外层对象克隆,内层对象引用。而深复制是增加了处理手段,让内层类实现ICloneable接口,在外层类创建对象(new)时,内层类克隆自己,实现内层类的分离。

11.   模版方法模式:定义:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。理解:当子类中重复与不重复的代码混杂时,把重复的代码搬到父类,不重复的(特有的)用虚方法或抽象方法延迟到子类中实现。在父类中定义一个整体的骨架方法,通过这个方法把父类的实现和子类的实现整合在一起完成功能。

12.   迪米特法则:定义:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。理解:减少无关类直接的耦合,方便修改。

13.   外观模式:定义:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。理解:把一系列具有一定联系的子系统功能整合到外观类的一个方法中,复杂的交互都由外观类完成,客户端只需要调用外观类的方法即可。外观类就像一个形象良好的接口,供客户端简洁的调用。

14.   建造者模式:定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。理解:把一系列稳定的、普遍的、复杂的装配过程放在指挥类中完成,定义抽象父类,用多态去创建不同的子类(产品),用户只需要调用指挥类并指定产品即可。把复杂的装配隔离到指挥类。

15.   观察者模式:定义:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(通知者)。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。理解:当一个对象变动时要通知其他不定个数的对象。变动的类相当于通知者,被通知的类相当于观察者。可以用集合实现,双方都依赖于抽象(通知者有抽象通知者,观察者有抽象观察者,这样会很容易扩展)。也可以用委托,大大减少耦合(观察者必须指定通知者,也就是让谁通知)。

16.   抽象工厂模式:定义:提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类。理解:简单工厂模式----工厂方法模式(抽象工厂来分离工厂功能)----抽象工厂模式(细化抽象,把每一个分开的小工厂继续细化,再分成不同的方法(接口方法),创建该工厂的又一个分支,实现当前工厂下的多功能。)。反射理解:反射就是可以动态的创建不同类的实例,把创建实例从编译时改成运行时。可以在工厂模式中替换switch、if等分支语句。反射要求以字符串的形式传入要实例化的类,所以可以用变量代替,大大的增加了灵活性。

17.   状态模式:定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。理解:当程序运行时需要不断地判断某一条件(状态),然后根据条件去执行不同的动作,就可以考虑用状态模式。状态模式可以消除庞大的分支判断,把不同状态的转移逻辑和每个状态的动作转移到抽象状态类的子类。让每个子类决定下一个状态(每个子类都进行判断,满足则执行自己功能,不满足则转向下一个类,直到得到处理或者链结束。每个子类只需要知道下一个类是哪个即可,无需知道整个链式结构)。

18.   适配器模式:定义:将一个类的接口转换成客户希望的另外一个接口。此模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。理解:通过一个翻译类(适配器类)把一个类的接口转化为另一种形式,通过调用这个翻译类的期望接口来间接调用另一个类。

19.   备忘录模式:定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。理解:备忘录模式把数据保存在箱子类中(体现了数据保存在对象外),然后通过备忘录管理类去访问箱子。在主类保存时,新建一个箱子类实例,保存数据,并把该箱子的实例交给管理类托管,恢复时调用管理类托管的箱子即可。

20.   组合模式:定义:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。理解:核心思想就是树枝类和树叶类。树枝可以分支(遍历),而树叶不可以。可以把树叶理解为“功能终端”,具体功能实现者,而树枝就是可以遍历其包含枝、叶的分支者。树枝或树叶隶属于哪个树枝就加入那个树枝的集合,通过递归即可达到效果。

21.   迭代器模式:定义:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。理解:无,较简单。

22.   单例模式:定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。理解:保证一个类只有一个实例,这个责任要放到这个类,而不应该让别的类决定。方法是把类的构造方法改成私有,确保外界无法通过new实例化,然后提供一个公有的静态的方法去创建实例。把保护实例的责任放在这个方法中(虽然构造方法私有,但是类内部还是可以访问的。创建成功后用这个公共静态方法返回,供调用者使用。这样做的好处是客户端只需要使用该类即可,至于是否实例化、如何实例化由类自己负责,减轻了客户端的压力,减少耦合。)。

23.   桥接模式:定义:将抽象部分与它的实现部分分离,使他们都可以独立的变化。理解:把混杂在一起的抽象分离出来,让它们单独实现。然后通过合成/聚合重新整合在一起。这样可以减少类之间的耦合,使结构松散,避免庞大的继承体系,增强复用性。体现在代码中就是把复杂的继承关系化为“方法-参数”,“部分”对象作为“整体”的方法的参数,通过参数聚合在一起(刚才讲到的是聚合,个人认为合成应该不是靠参数,应该是一种“你中有我,我中有你”的强耦合结构)。

24.   命令模式:定义:将一个请求封装为一个对象,从而使你可用不同的请问对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。理解:通过服务员类对请求者和执行者进行解耦合。

25.   职责链模式:定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。理解:把具有一定职责(处理能力)的类抽象成一个抽象父类,父类中包括了设置上级的方法和抽象处理方法。在客户端设计好上级关系,然后调用最低以及的对象处理事务,当该类无法处理时,会自动调用它的上一级的处理方法,直到可以处理为止。好处是通过设置上级把职责对象串在一起,每个部分知道上级是谁即可,无需了解整个链的结构,而且请求者只需调用最底层的职责对象即可,最终被哪个对象处理请求者不知道也无需知道。一切都是自动进行的。

26.   中介者模式:定义:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。理解:中介者承担了一切复杂通信,在关注对象中要指定中介类,在中介类中要包含所有的关注对象。通过关注对象的方法去调用中介者的协调方法,客户端不直接与中介类交互。

27.   享元模式:定义:运用共享技术有效地支持大量细粒度的对象。理解:通过usingsystem.Collections 引用Hashtable类来管理对象。给每个类一个标识(key),通过key来判断对象是否存在,存在直接按key返回,不存在则创建,然后通过Add方法加入Hasthtable类对象中,注意必须指定key。

28.   解释器模式:定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。理解:解释器模式就是用“迷你语言”来表现程序要解决的问题,以迷你语言写成“迷你程序”来表现具体的问题。

29.   访问者模式:定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。理解:能力有限,暂未理解该模式。




猜你喜欢

转载自blog.csdn.net/qq_40695958/article/details/80046924