.NET基础面试题整理
存储数据和指令,对于应用程序授予或拒绝相应的权限,并启动管理应用程序的执行,剩余内存的在分配。由于所有.net应用程序
都是在.net framework上面执行,所以开发人员只需考虑与.net framework打交道,而不必关系和底层操作系统上面的实现
包括CLR和BCL
CLI平台在符合标准的前提下应该具有什么行为。包含了:运行时(CLR),公共中间语言(CIL),公共类型系统(CTS),
公共语言规范(CLS),元数据(Metadata),框架(framework)
结构是值类型:值类型在栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,通过使用结构可以创建更多的值类型
类是引用类型:引用类型在堆上分配地址堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋值只是复制引用
注:1.虽然结构与类的类型不一样,可是他们的基类型都是对象(object),c#中所有类型的基类型都是object
2.虽然结构的初始化也使用了New 操作符可是结构对象依然分配在堆栈上而不是堆上,如果不使用“新建”(new),那么在初始化所有字段之前,字段将保持未赋值状态,且对象不可用
类:完全可扩展的,除非显示的声明sealed 否则类可以继承其他类和接口,自身也能被继承注:虽然结构不能被继承 可是结构能够继承接口,方法和类继承接口一样
结构: 没有默认的构造函数,但是可以添加构造函数没有析构函数没有 abstract 和 sealed(因为不能继承)不能有protected 修饰符可以不使用new 初始化在结构中初始化实例字段是错误的
类: 有默认的构造函数 有析构函数 可以使用 abstract 和 sealed 有protected 修饰符
必须使用new 初始化
堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些 大多数情况下该类型只是一些数据时,结构时最佳的选择
类:String Object Delegate 接口 等等 包含了大量的逻辑对象,表现抽象
2). 结构表示如点、矩形和颜色这样的轻量对象,例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低。
3). 在表现抽象和多级别的对象层次时,类是最好的选择
4). 大多数情况下该类型只是一些数据时,结构时最佳的选择
栈内存无需我们管理,也不受GC管理。当栈顶元素使用完毕,立马释放。而堆则需要GC(Garbage collection:垃圾收集器)清理
2)可能,当在类中定义一个结构类型时,该结构就分配在堆上
优势:(1)可重用性(2)类型安全,在参数化的类中只有成员明确希望的数据类型才可以使用(3)性能:避免了从Object的强制转换和值类型的装箱(4)减小了内存消耗:避免装箱也就不在需要消耗堆上的内存。
执行时的行为:泛型也是对象,泛型类的“类型参数”变成了元数据;CLR会在需要的时候构造利用它们的类。一个泛型类经过编译好之后和普通的类并没有什么区别。编译的结果只有元数据和CIL。基于值类型的泛型实例化:CLR会讲指定的类型参数放到CIL中合适的位置,从而创建一个具体化的泛型类型。所以CLR会为没个新的参数值创建具体的泛型类型
基于引用类型的实例化:CLR会创建一个具体化的泛型类型。以后,每次用一个引用类型参数来说实例化一个构造好的类型时,并在CIL中用Object引用替换类型参数,CLR都会重用以前生成好的泛型版本
Dictionary<T>:表示键值对的集合
Queue<T>:队列 Stack<T>: 栈
购物车用Dictionary模拟,OA中获取员工列表等数据的时候,返回值是泛型的
(2)throw会保留堆栈信息。throw ex 不会。当然,如果你抛出新的异常之前设置innerException的话,可以通过innerException的堆栈访问原有的堆栈。
(3)靠异常才能发现错误的,通过try catch finally来捕获异常。如果是未预料到的则不处理(内存不足,删除文件)直接报错更容易发现错误catch块从最具体到常规排列
2.Dictionary是hashtable的泛型版本,用来存储键值对的.例如:sortlist,stack等
相同点:都不能被直接实例化,都通过继承实现其抽象方法
不同点:
(1) 接口支持多继承;抽象类不能实现多继承。
(2) 接口只能定义行为;抽象类既可以定义行为,还可能提供实现。
(3) 抽象类允许包含实现的virtual成员,所以能为派生类成员提供一个默认的实现,而接口所有的成员自动成为virtual成员,而且不能包含任何实现
使用字符串时有什么需要注意的地方?为什么说StringBuilder比较高效?
当拼接两个字符串时,系统先是把两个字符串写入内存,接着删除原来的String对象,然后创建一个String对象,并读取内存中的数据赋给该对象。这一来二去的,耗了不少时间。而使用System.Text命名空间下面的StringBuilder类就不是这样了,它提供的Append方法,能够在已有对象的原地进行字符串的修改,简单而且直接。
在连接多个字符串时,它无论何时都比直接相加更高效吗?
不一定,在1000个字符以内效果一样,达到10000时StringBuilder类的效率会显著提升
如何高效地进行数组复制?“二维数组”和“数组的数组”有什么区别?
数组复制的方法:for CopyTo() 静态CopyTo() Clone
委托可以理解为指向一个函数的指针。
匿名方法:就是没有实际方法声明的委托实例。或者说,它们的定义是直接内嵌在代码中的。
Lambda表达式:是比匿名方法更加简洁的一种匿名函数语法
委托和事件没有可比性,因为委托是类型,事件是对象,下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。事件是用来阉割委托实例的,类比用一个自定义类阉割List。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能= 。事件内部就是一个private的委托和add、remove两个方法。
C#本质论,SQL Server2008实战,数据结构,ASP.NET揭秘,Javascript深入浅出
2)website不分namespace,webapplication有namespace
3)website为了兼容asp转过来的开发人员习惯
4)没有技术上的区别,调试习惯不同
5)website为每个编译为一个dll,webapplication生成一个dll
6)不利于工程开发,比如代码出错不容易发现
Post:传递的值隐藏在http报文中,URL中看不到,刷新页面会弹出提示对话框如果
24.Cookie
缺点:不能存储过多的信息,安全性差
针对互联网的优化:图片服务器和主站域名不一样
2)在减少使用列的同时,考虑减少行,使用where子句
3)只在需要的时候用order by
4)避免在from,where和having子句中隐式数据类型的转换
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Sort
{
public class Sort
{
///<summary>
/// 插入排序--稳定排序
///</summary>
///<param name="list"></param>
public static void InsertSort(List<int> list)
{
int j, tmp;
for (int i =1; i < list.Count; i++)
{
j = i;
tmp = list[i];
while (j >0&& tmp <= list[j -1])
{
list[j] = list[j -1];
j--;
}
list[j] = tmp;
}
}
///<summary>
/// 希尔排序
///</summary>
///<param name="list"></param>
public static void ShellSort(List<int> list)
{
int j, tmp;
int h =3;
while (h>0)
{
for (int i = h; i < list.Count; i++)
{
tmp = list[i];
j = i;
while ((j > h -1) && tmp < list[j - h])
{
list[j] = list[j - h];
j -= h;
}
list[j] = tmp;
}
h = (h -1) %3;
}
} ///<summary>
/// 冒泡排序--稳定排序
///</summary>
///<param name="list"></param>
public static void BubbleSort(List<int> list)
{
if (list ==null|| list.Count <1)
{
return;
}
int tmp;
for (int i =0; i < list.Count -1; ++i)
{
bool flag=false;
for (int j = list.Count -1; j >i+1; j--)
{
if (list[j] > list[j +1])
{
tmp = list[j];
list[j] = list[j +1];
list[j +1] = tmp;
flag=true;
}
if(flag==false)
{
return;
}
}
}
}
///<summary>
/// 选择排序--直接选择排序
///</summary>
///<param name="list"></param>
public static void SelectSort(List<int> list)
{
int min, tmp;
for (int i =0; i < list.Count; i++)
{
min = i;
for (int j = i +1; j < list.Count; j++)
{
if (list[j] < list[min])
{
min = j;
}
}
if (i != min)
{
tmp = list[i];
list[i] = list[min];
list[min] = tmp;
}
}
} ///<summary>
/// 堆排序
///</summary>
///<param name="list"></param>
public static void HeapSort(List<int> list)
{
int n = list.Count;
for (int i = n/2-1; i >=0; i--)
{
Sift(list, i, n -1);
}
for (int i = n -1; i >=1; i--)
{
int tmp = list[0];//取堆顶元素
list[0] = list[i];//让堆中最后一个元素上移到堆顶位置
list[i] = tmp;//此时list[i]已不在堆中,用于存放排好序的元素
Sift(list, 0, i -1);//重新调整堆
}
} private static void Sift(List<int> list, int low, int high)//建堆过程
{
//i为欲调整子树的根结点的索引号,j为这个结点的左孩子
int i = low, j =2* i +1;
int tmp = list[i];//记录双亲结点的值
while (j<=high)
{//如果左孩子小于右孩子,则将欲交换的孩子结点指向右孩子
if (j < high && list[j] < list[j +1])
{
j++;//j指向右孩子
}
if (tmp < list[j])//如果双亲结点小于它的孩子结点
{
list[i] = list[j];//交换双亲结点和它的孩子结点
i = j;//以交换后的孩子结点为根,继续调整它的子树
j =2* i +1;//j此时代表交换后的孩子结点的左孩子
}
else//调整完毕
{
break;
}
}
list[i] = tmp;//使最初被调整的结点放入正确的位置
} ///<summary>
/// 归并排序--稳定排序
///</summary>
///<param name="list"></param>
///<param name="low"></param>
///<param name="high"></param>
public static void MergeSort(List<int> list, int low, int high)
{
if (low < high)
{
int mid = (low + high) /2;
MergeSort(list, low, mid);
MergeSort(list, mid +1, high);
Merge(list, low, mid, high);
}
} private static void Merge(List<int> list, int low, int mid, int high)
{//listTmp为临时存放空间,存放合并后的数据
List<int> listTmp =new List<int>(high - low +1);
int i = low, j = mid +1, k =0;//k为listTmp的下标
while (i <= mid && j <= high)
{
listTmp[k++] = (list[i] < list[j]) ? list[i++] : list[j++];
}
while (i <= mid)
{
listTmp[k++] = list[i++];
}
while (j <= high)
{
listTmp[k++] = list[j++];
}
for (i = low, k=0; i <= high;i++,k++ )
{
list[i] = listTmp[k];
}
} ///<summary>
/// 快速排序
///</summary>
///<param name="list"></param>
public static void QuickSort(List<int> list)
{
QuickSort(list, 0, list.Count -1);
}
public static void QuickSort(List<int> list, int low, int high)
{
if (low < high)
{
int i = low, j = high, tmp = list[i];
while (i < j)
{
while (i < j && list[j] >= tmp)
{
j--;
}
list[i] = list[j];
while (i < j && list[i] <= tmp)
{
i++;
}
list[j] = list[i];
}
list[i] = tmp;
QuickSort(list, low, i -1);
QuickSort(list, i +1, high);
}
}
}
}
.NET基础面试题整理的更多相关文章
- python基础面试题整理---从零开始 每天十题(01)
最近在弄flask的东西,好久没写博客的,感觉少了点什么,感觉被别人落下好多,可能渐渐的养成了写博客的习惯吧.也是自己想学的东西太多了(说白了就是基础太差了,只是know how,不能做到konw w ...
- python基础面试题整理---从零开始 每天十题(02)
书接上回,我们继续来说说python的面试题,我在各个网站搜集了一些,我给予你们一个推荐的答案,你们可以组织成自己的语言来说出来,让我们更好的做到面向工资编程 一.Q:说说你对zen of pytho ...
- python测试工程师高端基础面试题整理
面试总括篇 技术技能 开发语言:python 数据库:mysql 操作系统;linux 网络协议基础 测试技能:自动化(UIselenium+接口)+性能 业务知识 测试工程师执业规划 初级--> ...
- 2017常见的50道java基础面试题整理(附答案)
1.作用域public,private,protected,以及不写时的区别 答: 区别如下: 2.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是 ...
- Python基础面试题整理
基础 Python中lambda是什么意思 Python中的pass是什么意思 作为解释型语言,Python如何运行 什么是Python的单元测试 在Python中unittest是什么 如何将数字转 ...
- 【转】Java学习---Java Web基础面试题整理
[原文]https://www.toutiao.com/i6592359948632457731/ 1.什么是Servlet? 可以从两个方面去看Servlet: a.API:有一个接口servlet ...
- python基础面试题整理---从零开始 每天十题(04)
一.Q:如何用Python来进行查询和替换一个文本字符串? A:可以使用sub()方法来进行查询和替换,sub方法的格式为:sub(replacement, string[, count=0]) re ...
- python基础面试题整理---从零开始 每天十题(03)
一.Q:用Python输出一个Fibonacci数列?(斐波那契额数列) A:我们先来看下代码 #!/usr/bin/env python # -*- coding: utf-8 -*- def fi ...
- Java Web基础面试题整理
Tomcat的缺省端口是多少,怎么修改 tomcat默认缺省端口是8080 修改方法: 找到Tomcat目录下的conf文件夹 进入conf文件夹里面找到server.xml文件 打开server.x ...
随机推荐
- 深入理解javascript原型和闭包(2)——函数和对象的关系
上文(理解javascript原型和作用域系列(1)——一切都是对象)已经提到,函数就是对象的一种,因为通过instanceof函数可以判断. var fn = function () { }; co ...
- PerfMon.exe通过命令管理计数器
通过PerfMon命令可以管理计数器,添加删除调整等等. 例1:Logman:在本地和远程系统上,管理和调度性能计数器和事件跟踪日志. master..xp_cmdshell 'logman quer ...
- 如何快速上手使用STM32库函数
一.背景 如前文所述,利用标准库函数的好处在于,可以快速开发,不用去对着数据手册,小心翼翼的一位一位的配置那些繁复的寄存器,因为这些工作意法半导体已经找了一些顶级的工程师帮你做了,杰作既是其库函数.当 ...
- UI第十一节——UIActivityIndicatorView
- (void)viewDidLoad { [super viewDidLoad]; // 创建一个UIActivityIndicatorView,大小是固定的 UIActi ...
- PHP上传(单个)文件示例
通过 PHP,可以把文件上传到服务器. 创建一个文件上传表单 允许用户从表单上传文件是非常有用的. 请看下面这个供上传文件的 HTML 表单: <html> <body> &l ...
- Asp.Net Core--基于角色的授权
翻译如下: 当创建身份时,它可以属于一个或多个角色,例如Tracy可以属于管理员和用户角色,而Scott可以仅属于用户角色. 如何创建和管理这些角色取决于授权过程的后备存储. 角色通过ClaimsPr ...
- MySQL SQL Mode及相关问题
MySQL可以运行于不同的SQLMode下,Mode定义了MySQL应支持的SQL语法.数据校验等. 一.Mode会影响到日期类型.字符串类型等的插入操作.其中多种模式影响了对某些特殊字符如何理解的问 ...
- iOS开发——高级篇——流水布局UICollectionViewFlowLayout的基本使用
之前看到过的一篇文章 对collectionView的使用总结的非常好:“iOS6新特征:UICollectionView介绍” 流水布局在现在的应用中很常见了,简单的研究了下,实现下面的功能 那我这 ...
- python——连接MySQL数据库
都是照着说明文档来的,主要是为了以后忘记了能快一点想起来. 1. 连接 安装MySQL的时候,自动按照了Python的模块,如果没有的话,也可以在官网下载. 看什么都不如看代码来得快: import ...
- servlet 之request
request对象中其他功能 一.转发和包含 转发==>用于一个servlet和一个jsp合作处理 servlet用于处理逻辑.jsp用于显示 ...