记录-.Net工程师面试题总结(1)
1、重载和重写有什么区别,各有什么作用
重写:指在子类中重复定义父类方法,存在有继承关系的父子关系,在 .Net中,只有以virtual和absract标记的虚方法和抽象方法才能被重写,在基类中的方法必须有修饰符virtual,而在子类的方法中必须指明override
重载(Overloading):指在同一个类中存在多个同名的方法,参数列表和返回值类型不同。
重写方法的规则:
1、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
2、返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
3、访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4、重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。
重载的规则:
1、必须具有不同的参数列表;
2、可以有不同的返回类型,只要参数列表不同就可以了;
3、可以有不同的访问修饰符;
4、可以抛出不同的异常
2、virtual、abstract、sealed的各自的作用
virtual关键字用于修改方法或属性的声明,在这种情况下,方法或属性被称做虚成员。可由派生类中的重写里面改变
sealed由它修饰的类或方法将不能被继承或是重写,sealed关键字的作用: 在类声明中使用sealed可防止其它类继承此类;在方法声明中使用sealed修饰符可防止扩充类重写此方法
abstrct修饰类不可被实例化,抽象类只能声明引用,不能创建对象
3、简单介绍const、static、readonly、volatile关键词的作用和区别
const:静态常量,已经被static修饰过,不能再修饰
static:静态的修饰类
readonly:动态常量,可以被static修饰,static readonly和const很相似
volatile:是变量修饰符,volatile 关键字指示一个字段可以由多个同时执行的线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的 值。volatile 修饰符通常用于由多个线程访问但不使用 lock 语句对访问进行序列化的字段
4、简单介绍MVC中几种过滤器类型
拦截器(Interceptor):
Action(net mvc 自带)
Result(net mvc 自带)
Exception(net mvc 自带)
先过滤掉一些不要的请求-拦截检查用户的数据进行验证,做前期数据处理-传给Action
使用的方法是在Action上写 [ResultFillters]
拦截器的作用:代码复用,拦截器可以被复用
启动的条件是:当进入控制器之前的操作
职责单一:厨师只负责炒菜,不用管前期的所有事,变质叫一声.
拦截器通过IHttpModeule接口来实现
用于场景:支付中心。
过滤器(Filter):
如在配置一些东西的时候使用,如过滤掉低俗文字,危险字符,在请求控制器之前发生作用。
也可以过滤一些url,如不是登录接口的地址请求就都过滤掉。
顺序:过滤器-拦截器-Action
5、JS中Apply和Call的区别
Apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
Call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
Call与 Apply的相同点:
(1)、方法的含义是一样的,即方法功能是一样的;
(2)、第一个参数的作用是一样的;
Call与 Apply的不同点:
(1)、Call可以传入多个参数;
(2)、Apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入
存在的意义:
实现(多重)继承
6、JS中的闭包的作用,以及遇到的常见的使用场景
概念:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
用途:
1、读取函数内部的变量
2、让这些变量的值始终保持在内存中。不会再f1调用后被自动清除。
3、方便调用上下文的局部变量。利于代码封装。
原因:f1是f2的父函数,f2被赋给了一个全局变量,f2始终存在内存中,f2的存在依赖f1,因此f1也始终存在内存中,不会在调用结束后,被垃圾回收机制回收。
特点:
- 作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
- 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
用途的场景:
1、匿名自执行函数
2、结果缓存
3、封装
4、实现类和继承
7、什么是拆箱和装箱
装箱是将值类型转化为引用类型的过程;拆箱是将引用类型转化为值类型的过程
int i = 10;
object o = i;//装箱
int j = (int)o;//拆箱
缺点:
占用内存和Cpu
8、Vachar和char有什么区别
char是一种固定长度的类型,varchar则是一种可变长度的类型。
char类型中如:char(10)如果只暂用了3个字节,那么剩下没占用的则用空格字符补足
vachar是用到多少就是多少
char最多能存放255字符
vachar最多能存放65532个字符
char存取速度比vachar快,但是是以空间换取时间
char的存储方式是对英文字符占用1个字节,对汉字占用两个字节,而varchar的存储方式是对每个英文字符占用2个字节,汉字也占用2个字节;
9、String 和StringBuilder有什么不同?
String:不可变字符序列
StringBuilder :可变字符序列
如在字符拼接时,用String会不断的在内存中创建新的字符串对象,分配新的空间,如果是进行字符串的拼接就用StringBuilder,如果只是创建新的对象则可以使用String
如string s="1234";
console.writeline(s);
s+="789";
console.writeline(s);
输出结果为:1234 1234789
其中第一个输出的是1234,但是第二个其实是创建了一个新的内存,指向新的内存地址,其中堆中存在两个字符串,虽然只引用了第二个,但是第一个1234其实还是存在内存中
String不删除的并且保留的原因:String 是引用类型,如String s="1234";string Str="1234"; 其中str指向的是s。确保内存有效利用
StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
多线程操作字符串缓冲区下操作大量数据 StringBuffer;
单线程操作字符串缓冲区下操作大量数据 StringBuilder。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
运行速度:StringBulider>StringBuffer>String
10、有用过事务吗,对事务的理解
在关系型数据库中,可以由一条SQL组成,也可以由几天SQL组成
特性
一致性(consistency):张三和李四的钱数总和保持不变。
原子性(Atomicity):张三的钱减少和李四的钱增多要同时进行。
持久性(durability):最终这些数据的改变要保存在数据库中
隔离性(isolation):在事务完全执行成功之前,不对其他的事务产生影响,也不会受到其他事务的影响
数据库的事务:
1、他能够为数据库操作提供了一个从失败恢复到正常状态的方法
2、当多个应用程序并发访问数据库时,能够在这些应用程序提供一个隔离方法,能够防止各个应用之间的操作互相干扰
系统的事务:
3、对业务进行一系列的操作时,要么全部执行,要么全部不执行
使用场景可以在:在进行对三个表进行修改数据时,已修改完第一个表数据,在对第二个表数据进行修改时,突然断电,则可以使用事务。
11、值类型和引用类型的区别
string是属于引用类型。int属于值类型
1.值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的
地址。
2.值类型存取速度快,引用类型存取速度慢。
3.值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用
12、手写ajax的javascript代码
function Test(){
var val=1;
$ajax({
type:"get";
url:"login";
async:ture;
data:"value+=":val;
dataType:json;
success:function(data){
}
error:function(data){
}
})
}
13、手写冒泡排序
public static void ArraySort()
{
int[] Arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
int t = 0;
//从小到大排序
for (int i = 0; i < Arr.Length - 1; i++) //总共需要N-1趟
{
for (int j = 0; j < Arr.Length - 1 - i; j++) //每趟总共需要(N-1-趟数)次比较
{
if (Arr[j] > Arr[j + 1])
{
t = Arr[j];
Arr[j] = Arr[j + 1];
Arr[j + 1] = t;
}
}
}
foreach (int i in Arr)
{
Console.Write(i + ",");
}
}
public static void Main()
{
ArraySort();
}
14、ref 与out有什么不同?
ref型参数时,传入的参数必须先被初始化。
out型参数时,必须在方法中对其初始化
out适合在需要return多个返回值时,ref用在被调用方法修改调用者的引用时。
ref穿进去的参数在函数内部可以直接使用,而out需要在方法中初始化才能使用
ref有出有进,而out只出不进
15、委托和事件关系是什么,为什么要使用委托
委托提供了封装方法的方式,事件是某动作已经发生的说明,事件是建立在委托之上的
程序运行时同一个委托能够调用不同的方法,只要改变他的引用方法就可以,因此委托调节器用的方法不是在编译之时决定的,而是程序在运行之中确定的。
16、接口和类有什么不同和相同点
不同点:
不能直接实例化接口,而类可以
接口只包含了方法和属性,不包含实现的方法
接口可以多继承,而类只能单继承
类有分部类的概念,定义可在不同的源文件之间进行拆分
表达的含义不同,接口主要是定义一种规范,统一的调用方法,约束类,类的方法功能的实现和集合
相同点:
接口和类和结构都可以从多个接口继承
接口类似抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员
接口和类都可以包含事件、索引器、方法和属性
17、为什么要尽量使用DataReader而不是DataSet
因为DataReader一直占用着Sqlconnection,任何对sqlconnnection的操作都会使得DataReader异常,因为每次只加载一条数据,占用的内存少
Dataset是一次性将所有的数据全部加载出来,存在内存中。占用的内存大,比DataReader灵活,因为可以动态添加行、列,数据,。和对数据库进行回传更新的操作。
18、泛型的各个意思
class A<T>where T:new()
where表明对类型变量T的约束关系
where T:A 表示数据类型变量是继承于A的,或者是A的本身
where T :new() 指明创建T的实例时应该使用的够着函数
T就是指一个占位符
19、面向对象的思想是什么
继承:子类继承父类的所有数据和操作
封装:用抽象的数据类型和基于数据的操作封装在一起,数据被保护在封装的抽象数据类型中
多态:一个程序中同名但是不同方法的共存情况,有两种形式:重载和重写
20、堆和栈的区别,堆和栈的区别
堆:程序运行期间动态分配的内存空间,存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象)
栈:编译期间就分配好的内存,栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量)
栈的生命周期一般很短,用完就释放,而堆存放的实体会被垃圾回收机制不定时的回收
21、斐波那契数列,计算第三十个的值
F(n-1)+F(n+1)
第三十是832040
public static Fn(int i)
{
if(i<=0)
{
return 0;
}
else if(i>0&&i<=2){return 1}
else{return F(i-1)+F(i+1)}
}
}
22、数据库表连接有哪些方法,有什么区别
Left(左) join 和Right(右) join都叫外连接,因为可能出现对应不上的数据,根据right和left来将数据记录下来,并将对应的领一张表的字段做置空处理
如:select *from table1 left join table2 on table1.id=table2.id;
left join(左连接)table的数据全部查询出来,table2符合table1.id=table2.id的有数据,没有的为null
right join(右链接)和left join 相反
inner join (等值连接):只有查出table1.id=table2.id的数据
23、数据库表的引擎myisam和innodb的区别
Innodb:是一种支持事务性的引擎,提供了提交、回滚、崩溃恢复的事务安全储存引擎,所有内容储存在一个或多个文件中,支持Oracle的。锁机制
优点是:提供了事务控制的能力,当一组命令全部执行成功,或者任何一个命令错误时所有命令的结果被回退
缺点是:速度慢,占用的磁盘空间大
myisam:是一种非事务性引擎,提高检索的和存储的速度,和全文搜索引擎,可以用Full text索引,适合数据查询频繁的应用,一个表分为了三个文件-存储定义,储存的数据,粗存的索引。
优点是:读取的速度快,不占用大量资源。
缺点是:1、不支持事务2、容错率不好,磁盘崩溃后,数据就没了
24、什么时候用到GET,什么时候用到Post
GET方法会产生很长的URL,可能会超过游览器限制的URL的长度,不安全,别人可以看到参数
在做数据的查询一般用GET,从服务器上获取数据
POST一般是表单提交,在进行数据的增删改时一般用POST,向服务器发送数据
25、谈谈怎么使用的Redis,和怎么判断缓存的数据是否更新,以及看缓存有什么作用
缓存一般缓存的是不常变得数据,也不能始终保证和数据库是始终一致的
缓存的优点是减少对数据库的查询和操作
缓存的缺点不能完全保证和数据库的数据一致
使用的步骤是:判断缓存中是否有数据,有则用缓存的数据没有则从数据库中查询并修改更新缓存中的数据
缓存速度快的原因是:存内存操作,单线程操作,非阻塞的I/O多路复用机制(就是一个快递员一辆车,依次去取客户的包裹)
Redis的过期策略:
定时删除:设置定时器,检查key,每100ms将随机检查(如果全部检查,Redis会卡死)
惰性删除:在请求某个key的时候,redis会检查是否过期,如果过期就会删除。
定时删除+惰性删除不用的原因是:定期删除么删除的key,也没有去请求,内存会越来越高。则需要使用内存淘汰机制(没内存就报错,或者没内存就删除最近少用的key,没内存随机删除key)
26、使用MVC,以及对MVC的理解
MVC分为三层:
V=View视图展现层
C=Controller用户交互层,处理从Model中获取的数据返回给View
M=Model处理业务逻辑,Model又横跨BLL和DAL层。
优点:
1、各司其职互不干扰。三层中那一层的需求发生变化,只需要改动相应层中的代码而不会影响到其他层中的代码
2、有利于分工,做页面,做业务的做业务,做底层的做底层
缺点:
1、对模型数据的低效率访问,视图调用多次可能才会获得足够显示的数据,对没有变化而数据做了不必要的访问,损害操作性能
27、对ES的理解是什么,怎么用ES的(ES7,去掉了Type分组)
是一个基于Lucene 的开源搜索引擎,本质上是一个分布式的数据库,允许多台电脑运行多个ES
有着索引-节点-集群概念 ,一组节点组成一个集群,索引中单条记录叫做 Document文档,多个Document组成一个索引,每个document是JSON格式。有着分片的概念,默认为5,主副分片,相当于负载均衡,会自动根
据负载均衡控制路由,进入其它分片进行查询,某个分片的数据有问题后,也可通过其他节点去恢复。
可以安装分词器,如IK分词
获得数据的方法是GET请求连接根据指定的查询条件得到对应的Json数据(HTTP请求)
建立索引之前先建立Mapping映射,相当于数据库的字段结构
28、数据库的分区和分表
分区:如按照时间分区,如2018-2019是一个区。就是将一个表的数据分成N个区块,逻辑上是由一个表组成,实际上是N个物理区块组成
分表:将一张表按照一定的规则去分解成N个独立储存空间的实体表,如某个表按照TYPE类型1/2/3/4/5分为五个表
优先考虑分区,然后分表。
分区之后数据还是存在于一个表中,但是分表则是将一个表根据某个字段去分成N个表,这样就减少了每个表的数据量,加快了查询速度和读写速度
分库则是将数据存储在不用服务器
29、truncate和delect、drop有什么区别
delect执行的删除是每次从表中删除一行,并将此删除的操作作为事务记录在日志中,以便回滚
truncate则是一次性的删除表中所有数据,不会记录日志,不可回滚,删除过程中不会激活与表有关的删除触发器,执行速度快
drop删除整个表
truncate只能针对table
delect可以操作table和view
速度上为drop>truncate>delect
30、什么是接口
接口简单理解就是一种约定,使得实现接口的类或结构在形式上保持一致
接口一般分为两种。
一、程序内部的接口:方法和方法之间,模块和模块之间的交互。如登录和发帖,发帖必须登录,则发帖需要调用登录的接口。
二、系统对外部的接口:如从别的的网站需要获取对方的资源或者信息,对方不会开放数据库,则对方会提供一个查询数据的方法出来获取指定的数据,如购物网站需要调用微信或者支付宝的支付接口。
接口分为两种类型:
api接口:http协议,通过路径区分,请求和内容都是key-value格式,返回的内容一般是json格式,方式有get和post方法,较常用。
webservice接口:是soap协议通过http传输,请求和返回的都是xml格式