面试干货

开始

一、对于Web性能优化,您有哪些了解和经验吗?

  1. 前端优化
  • (1)减少http请求的次数。我们知道每次发送http请求,建立连接和等待相应会花去相当一部分时间。所以在发送http请求的时候,尽量减少请求的次数,一次请求能去除的数据就不要分多次发送。
  • (2)启用浏览器缓存。当确定请求的数据不会发生变化时,能够直接读取浏览器缓存的就不要向服务器发送请求。比如我们ajax里面有一个参数能够设置请求的时候是否启用缓存,这种情况下就需要我们在发送请求的时候做好相应的缓存处理。
  • (3)css文件放在里面,js文件尽量放在页面底部。因为请求js文件是很花费时间,如果放在里面,就会导致页面的DOM树呈现需要等待js文件加载完成。这也就是为什么很多网站的源码里面看到应用的文件放在最后的原因。
  • (4)使用压缩的css和js文件。这个不用多说,网络流量小。
  • (5)如果条件允许,尽量使用CDN的方式引用文件,这样就能减少网络流量。比如我们常用的网站http://www.bootcdn.cn/
  • (6)在写js和css的语法时,尽量避免重复的css,尽量减少js里面的循环次数,诸如此类。
  1. 后端优化
  • (1)程序的优化:这是一个很大的话题,我这里就选几个常见的。比如减少代码的层级结构、避免循环嵌套、避免循环CURD数据库、优化算法等等。
  • (2)数据库优化:(由于数据库优化不是本题重点,所以可选几个主要的来说)比如启用数据库缓存、常用的字段建立索引、尽量避免大事物操作、避免Select*的写法、尽量不用in和not in这种耗性能的用法等等
  • (3)服务器优化:(这个可作为可选项)负载均衡、web服务器和数据库分离、UI和Serivice分离等等

二、MVC路由理解?

  1. 首先我们要理解MVC中路由的作用:url Routing的作用是将浏览器的URL请求映射到特定的MVC控制器动作。
  2. 当我们访问http://localhost:8080/Home/Index这个地址的时候,请求首先被UrlRoutingModule截获,截获请求后,从Routes中得到与当前请求URL相符合的RouteData对象,将RouteData对象和当前Url封装成一个RequestContext对象,然后从Requestcontext封装的RouteData中得到Controller名字,根据Controller名字,通过反射创建控制器对象,这个时候才真正被激活,最后去执行控制器里面对应的action。

三、谈谈你觉得做的不错的系统,大概介绍下用到哪些技术?

就拿我之前做过的一个项目为例来简单说明一下吧。项目分为客户端和服务端,客户端分为BS客户端和CS客户端,BS客户端采用MVC5.0的框架,CS客户端是Winform项目,服务端使用WebApi统一提供服务接口,考虑以后可能还要扩展手机端,所以服务接口的参数和返回值使用通用的json格式赖传递数据。由于不同的客户端调用的WebApi服务,这里就存在跨域的问题,我们使用cors来解决,只有指定来源的请求才能成功取到数据。

  1. 服务端采用的面向接口编程,我们在软件架构的过程中,层和层之间通过接口依赖,下层不是直接给上层提供实现,而是提供接口,具体的实现以依赖注入的方式在运行时候注入进去。MEF就是实现依赖注入的一种组件。它的使用使得UI层不直接依赖与BLL层,而是依赖于中间的一个IBLL层,在程序运行的时候,通过MEF动态将BLL里面的实现注入到UI层里面去,这样做的好处是减少了层与层之间的耦合。服务端的异常里面、权限验证、日志记录等通用功能使用了AOP拦截的机制同意管理,项目中使用的是Postsharp这个组件,很好地将通用需求功能从不相关的类当中分离出来,提高代码的可维护性。
  2. BS的客户端采用jquery+bootstrap的方式,所有的页面采用流式布局,能更好适应各种不同的终端设备(PC、手机)。项目中使用了各种功能强大的bootstrap组件,能适应各种复杂的业务需求。

四、Js继承实现

参考答案:原型链继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Person(name,age){
this.name = name;
this.age = age;
}
//通过原型链给Person添加一个方法
Person.prototype.getInfo = function(){
console.log(this.name + "is" + this.age + "years old");
}

function Teacher(staffId){
this.staffId = staffId;
}

//通过prototype生命Teacher继承Person
Teacher.prototype = new Person();

var will = new Teacher(1000);
will.name = "Will";
will.age = 28;
will.getInfo();

五、谈谈你对设计模式的认识?结合你用得最多的一种设计模式说说它的使用。

主要考点:不用多说,这题考的就是对设计模式的理解。一般为了简单可能会要求你写一个单例模式,注意最好是写一个完整点的,考虑线程安全的那种。然后会让你说说你在项目中什么情况下会用到这种模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Singleton
{
// 定义一个静态变量来保存类的实例
private static Singleton uniqueInstance;

// 定义一个标识确保线程同步
private static readonly object locker = new object();

// 定义私有构造函数,使外界不能创建该类实例
private Singleton()
{
}

/// <summary>
/// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
/// </summary>
/// <returns></returns>
public static Singleton GetInstance()
{// 双重锁定只需要一句判断就可以了
if (uniqueInstance == null)
{
lock (locker)
{
// 如果类的实例不存在则创建,否则直接返回
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}

====单例模式确保一个类只有一个实例==,并提供一个全局访问点,它的使用场景比如任务管理器整个系统中应该只有一个把,再比如操作文件的对象,同一时间我们只能有一个对象去操作文件吧。最重要的,比如我们项目中用得非常多的功能→日志记录,在一个线程中,记录日志的对象应该也只能有一个吧。单例模式的目的是为了保证程序的安全性和数据的唯一性。或者你也可以结合你使用的其他设计模式来说明。==


六、js数组去重方法?

答:

方法一:

双层循环,外层循环元素,内层循环时比较值

如果有相同的值则跳过,不相同则push进数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Array.prototype.distinct = function(){
var arr = this,
result = [],
i,
j,
len = arr.length;
for(i = 0; i < len; i++){
for(j = i + 1; j < len; j++){
if(arr[i] === arr[j]){
j = ++i;
}
}
result.push(arr[i]);
}
return result;
}
var arra = [1,2,3,4,4,1,1,2,1,1,1];
arra.distinct(); //返回[3,4,2,1]

方法二:利用splice直接在原数组进行操作

双层循环,外层循环元素,内层循环时比较值

值相同时,则删去这个值

注意点:删除元素之后,需要将数组的长度也减

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Array.prototype.distinct = function (){
var arr = this,
i,
j,
len = arr.length;
for(i = 0; i < len; i++){
for(j = i + 1; j < len; j++){
if(arr[i] == arr[j]){
arr.splice(j,1);
len--;
j--;
}
}
}
return arr;
};
var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,];
var b = a.distinct();
console.log(b.toString()); //1,2,3,4,5,6,56

优点:简单易懂

缺点:占用内存高,速度慢

方法三:利用indexOf以及forEach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array.prototype.distinct = function (){
var arr = this,
result = [],
len = arr.length;
arr.forEach(function(v, i ,arr){ //这里利用map,filter方法也可以实现
var bool = arr.indexOf(v,i+1); //从传入参数的下一个索引值开始寻找是否存在重复
if(bool === -1){
result.push(v);
}
})
return result;
};
var a = [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,1,23,1,23,2,3,2,3,2,3];
var b = a.distinct();
console.log(b.toString()); //1,23,2,3

七、怎么判断字符串是否存在某个字符?

答:

1
2
3
4
5
6
7
mycollenction.indexOf(i);

//i:要判断的字符

//mycollenction:整个字符串

//返回值:-1表示不存在,>-1代表i出现的位置,从0开始。

八、字符转数组,数组转字符

答:

1、数组转字符串
需要将数组元素用某个字符连接成字符串,示例代码如下:

1
2
3
var a, b;
a = new Array(0,1,2,3,4);
b = a.join("-"); //"0-1-2-3-4"

2、字符串转数组

实现方法为将字符串按某个字符切割成若干个字符串,并以数组形式返回,示例代码如下:

1
2
 s = "abc,abcd,aaa"= s.split(",");
var s1 = "helloworld"

注:JSON.parse() 方法用于将一个 JSON 字符串转换为对象。json.stringfy()将对象、数组转换成字符串;

九、flex属性

答:

1
2
3
4
5
6
7
flex-grow	一个数字,规定项目将相对于其他灵活的项目进行扩展的量。
flex-shrink 一个数字,规定项目将相对于其他灵活的项目进行收缩的量。
flex-basis 项目的长度。合法值:"auto"、"inherit" 或一个后跟 "%"、"px"、"em" 或任何其他长度单位的数字。
auto 与 1 1 auto 相同。
none 与 0 0 auto 相同。
initial 设置该属性为它的默认值,即为 0 1 auto。请参阅 initial。
inherit 从父元素继承该属性。请参阅 inherit。

十、div水平居中、垂直居中

答:

方案一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
div绝对定位水平垂直居中【margin:auto实现绝对定位元素的居中】,

兼容性:,IE7及之前版本不支持

    div{
width: 200px;
height: 200px;
background: green; position:absolute;
left:0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
}

方案二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

div绝对定位水平垂直居中【margin 负间距】 这或许是当前最流行的使用方法。

div{
width:200px;
height: 200px;
background:green; position: absolute;
left:50%;
top:50%;
margin-left:-100px;
margin-top:-100px;
}
注:vertical-align:middle;//用于行元素



羊肉串:一行垂直居中显示

签子:

.vertical-head{


display:inline-block;

width:1px;

height:100%;

vertical-align:middle;

}



肉:

.vertical-body{


display:inline-block;

vertical-align:middle;

}

十一、移动端怎么布局?

答:

方法一:用流式布局,px做css单位,在大屏小屏自动适应,我之前一直用这种方法,适合于简单的页面,比如说列表页,写法比较简单,不用考虑太多

缺点是:

1.页面虽然展示正常,却不是等比缩放,在高清屏上难免看起来怪怪的(px换算统一除以2,在dpr是2.5或者3上看起来偏小)

方法二:用rem布局.

rem:css单位,相对于网站根元素,即根据html元素的font-size来计算大小,比如说html的font-size大小为50px,一个div的width为1rem,则div的width大小为50px,所以在不同屏上,只要我们动态的算出html的大小,则可起到一改俱改的效果,实现等比例放大缩小,因为html的font-size是等比算出来的.

十二、CSS3 transform 属性

答:该属性允许我们对元素进行旋转、缩放、移动或倾斜。

十三、元素渐入渐出

答:animation 属性是一个简写属性,用于设置六个动画属性:

1
2
3
4
5
6
7
8
9
10
11
animation-name

animation-duration

animation-timing-function

animation-delay

animation-iteration-count

animation-direction

 本篇
面试干货 面试干货
开始一、对于Web性能优化,您有哪些了解和经验吗? 前端优化 (1)减少http请求的次数。我们知道每次发送http请求,建立连接和等待相应会花去相当一部分时间。所以在发送http请求的时候,尽量减少请求的次数,一次请求能去除的数据就不
2019-11-08
下一篇 
工作中遇到的一些问题 工作中遇到的一些问题
开始1、名称为纯英文数字等不换行问题1234span { word-wrap: break-word; word-break: break-all;} 2、各浏览器关于渐变色的适配123456789.mai
2019-11-08
  目录