好程序员web前端学习路线大厂面试题详解

好程序员web 前端学习路线大厂面试题详解, 依赖注入原理

手动实现依赖注入实现方式

var _g lobal ={

ajax:function(){ // 申明服务,也可以说是内部类

this.get=function(){

// todo : get 方式请求数据

console.log( get is success );

};

This.post=function(){

//todo: post 方式请求数据

console.log( post is success );

}

},

// 还可以定义若干个不同的服务

init:function(_server,_fx){// 这个方法起到一个注入器的作用

var _args=[];

for(var i=0;i<_server.length;i++){

_args.push(new this[_servers[i]]);/* 这里尤为关键 必须是新 new 出来的对象 如果是预定义的对象的情况 很有可能改一处动全局的致命错误。 */

}

_fx.apply(this,_args);

}

}

 

_global.init([ ajax ],function(_ajax){

•  / * 数组中的每个元素表示服务的名称,函数中的形参顺序与数组中的顺序一致 */

_ajax.get();

_ajax.post();

console.log(this);

});

 

参考答案思路:

本题是要求 js 实现依赖注入设计模式。考察编程基础的目的。答案不唯一。

依赖注入顾名思义:有依赖关系才会注入服务。也就是需要使用的时候才会注入相关服务。

注意事项:服务不能是全局对象,必须是新实例的对象。如果是全局的对象,一是注入就显得多此一举,更重要的是有可能在多处使用,然后出现数据脏读的致命性错误。

由此可见,服务都是预定义的构造函数。

 

阿里 · 云笔试

1 、阿里云产品线十分丰富,拥有 ECS RDS 等数百款产品,每个产品都具有一些通用属性,例如: ID id ),地域( region ),名称( name ),同时每个产品又包含自己特有的属性。  ECS 拥有实例( instance )属性,可选值有 ecs.t1.small ecs.t3.small ecs.t1.large RDS 拥有数据库类型( dbType )属性,可选值有 mysql mssql PPAS 请使用你的面向对象知识,基于 ES6 语法编写 ECS RDS 两个类,并实现如下方法:  1. config() 返回一个字面量对象,可以拿到所有的成员变量。   2. buy() 返回一个 URL ,格式为   https://www.aliyun.com/buy?id=xxx®ion=xxx&name=xxx& 每个产品自己特有的成员变量

 

class   Property {

         constructor ( _identify , _region , _name ){

             this . id = _identify ;

             this . region = _region ;

             this . name = _name ;

        }

         buy (){

             var   _url = "https://www.aliyun.com/buy?" ;

             for ( let   _key   in   this ){

                 if ( this . hasOwnProperty ( _key ) && typeof ( this [ _key ])!== "object" ){

                     _url += _key + "=" + this [ _key ]+ "&" ;

                }

            }

             if ( _url . indexOf ( "&" )> 0 ){

                 return   _url . replace ( /& $ / g , "" );

            }

             return   _url ;

        }

    }

 

     class   ECS   extends   Property {

         constructor ( _identify , _region , _name ){

             super ( _identify , _region , _name );

        }

         config ( _value ){

             this . instance = _value ;

             return   this ;

        }

    }

     let   _ecs = new   ECS ( 1 , "beijing" , "ECS" );

     console . log ( _ecs . config ( "ecs.t1.small" ));

     console . log ( _ecs . buy ());

 

 

     class   RDS   extends   Property {

         constructor ( _identify , _region , _name ){

             super ( _identify , _region , _name );

        }

         config ( _type ){

             this . dbType = _type ;

             return   this ;

        }

    }

     var   _rds = new   RDS ( 2 , "beijing" , "RDS" );

     console . log ( _rds . config ( "mysql" ));

     console . log ( _rds . buy ());

 

解题 思路:

1 、根据面试题描述,数百种产品均有通用的属性,那么就选择一次定义多次使用的,能达到这种效果的而且又要求面向对象,所以优先考虑继承。把公共的属性和方法放到父类。子类实现继承即可。

2 、每个产品均有自己的特有属性,那么在调用 config 方法的时候传入配置参数,同时还要求返回一个字面两对象,还要能拿到所有属性,所以直接返回当前对象即可。

3 buy 方法要求返回 url ,此时查看 url 中都包含哪些属性,我们发现均为当前产品对象的属性。所以遍历拼接即可。

 

2 、请将编写一个函数将  [3, 5, 7, 2, 1, 8, 9, 0, 5, 23, 15, 5, 1, 5, 8] 这样的一个组件中重复的元素去除掉

 

function   splice (){

         var   _arr =[ 3 , 5 , 7 , 2 , 1 , 8 , 9 , 0 , 5 , 23 , 15 , 5 , 1 , 5 , 8 ];

         for ( var   i = 0 ; i < _arr . length ; i ++){

             for ( var   n = i + 1 ; n < _arr . length ; n ++){

                 if ( _arr [ i ]=== _arr [ n ]){

                     _arr . splice ( n --, 1 ); // 因为元素数量减少了,如果向前挪动一个下标 3 个以上的连续重复的元素会有遗漏

                }

            }

        }

         console . log ( _arr );

    }

     splice ();

 

参考答案思路

数组去重是比较常规的面试题 主要考察一个知识点数组的 splice 方法的使用。但是阿里出这个题个人认为他更注意的是你的认真态度,或者思维缜密性。因为在题中并没有连续 3 个重复的数字。在注释那一行我写的很清楚,这题的不用 n 结果也是对的。但是连续出现三个数字的话,你会发现不能完全清除重复的数字。

 

3 、编写一个递归函数查询 tree 给定节点的祖先链(包含给定节点),

     要求:  

    1 、要求查出祖先链后函数立即返回,不再继续递归遍历后面的节点  

    2 、函数要有一个参数来指定 tree 的节点的主键名  

    3 、使用示例代码中的 options 作为 tree 结构的参考

 

const   options  = [

        {

             id:   'zhejiang' ,

             text:   'Zhejiang' ,

             children:  [

                {

                     id:   'hangzhou' ,

                     text:   'Hangzhou' ,

                     children:  [

                        {

                             id:   'xihu' ,

                             text:   'West Lake'

                        }

                    ]

                }

            ]

        },

        {

             id:   'jiangsu' ,

             text:   'Jiangsu' ,

             children:  [

                {

                     id:   'nanjing' ,

                     text:   'Nanjing' ,

                     children:  [

                        {

                             id:   'zhonghuamen' ,

                             text:   'Zhong Hua Men'

                        }

                    ]

                }

            ]

        }

    ];

     function   recursion ( _primary , _options ){

         var   _parent = null ;

         for ( var   i = 0 ; i < _options . length ; i ++){

             if ( _options [ i ]. id !== _primary ){

                 if (! _options [ i ]. children ){

                     return   null ;

                }

                 _parent = recursion ( _primary , _options [ i ]. children );

                 if ( _parent ){

                     _parent . push ( _options [ i ])

                     return   _parent ;

                }

            } else {

                 return  [ _options [ i ]];

            }

        }

    }

     console . log ( recursion ( zhonghuamen" , options ));

 

参考答案思路:

题目要求需要递归,那么就考察我们对递归算法的了解。根据给定的节点主键查询父路径,那么首先我们要找到主键所在的位置,然后一路返回,此题的难度主要在于,当找到后立即停止,而不能继续浪费查询。在这一点上如果直接无条件 return 的话,第一个对象递归完就回结束递归。

 

4 将类似以下 JSON 表示的树状结构(可以无限层级)

     通过 parseDOM 函数(使用 document.createElement document.createTextNode appendChild 等方法)

     生成一颗 DOM 树(返回一个 element 元素)

 

const   JsonTree  = {

         "tagName" :   "ul" ,

         "props" :  {

             "className" :   "list" ,

             "data-name" :   "jsontree"

        },

         "children" :  [

            {

                 "tagName" :   "li" ,

                 "children" :  [{

                     "tagName" :   "img" ,

                     "props" :  {

                     "src" :   "//img.alicdn.com/tps/TB1HwXxLpXXXXchapXXXXXXXXXX-32-32.ico" ,

                     "width" :   "16px"

                    }

                }]

            },

            {

                 "tagName" :   "li" ,

                 "children" :  [{

                     "tagName" :   "a" ,

                     "props" :  {

                         "href" :   "https://www.aliyun.com" ,

                         "target" :   "_blank"

                    },

                     "children" :   " 阿里云 "

                }]

            }

        ]

    };

 

     function   parseDOM ( jsontree ){

         const  { tagName , props , children } = jsontree ;

         const   element  = document . createElement ( tagName );

         // 请实现过程

         //....

         for ( let   _key   in   props ){

             element [ _key ]= props [ _key ];

        }

         if ( children  && typeof ( children )=== "object" ){

             for ( let   i = 0 ; i < children . length ; i ++){

                 element . appendChild ( parseDOM ( children [ i ]));

            }

        } else {

             if ( children ){

                 element . appendChild ( document . createTextNode ( children ));

            }

        }

         return   element ;

    }

     document . getElementsByTagName ( “body" )[ 0 ]. appendChild ( parseDOM ( JsonTree ));

参考答案思路:

首先这个面试题很切合实际,在日常的开发过程中经常会遇到这种类型的数据。主要考我们对递归算法的熟练程度。具体的知识点就是题中列出的 3 DOM 操作的知识。

参考答案的思路是把每次创建完成的节点添加到父元素中。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69913892/viewspace-2655585/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/69913892/viewspace-2655585/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值