【基础知识】
(一)简述private,protected,public,internal修饰符的访问权限。
- private:私有成员,在类的内部可以访问。
(private关键字是一个成员访问修饰符。私有访问是允许的最低访问级别。私有成员只有在声明他们的类和结构体中才是可访问的。)
- protected:保护成员,该类内部和继承类中可以访问。
(protected关键字是一个成员访问修饰符。受保护成员在他的类中可访问并且可由派生类访问。有关protected与其他访问修饰符的比较,仅当访问通过派生类类型发生时,基类的受保护成员在派生类中才是可访问的。)
- public:公共成员,完全公开,没有访问权限。
(public关键字是类型和类型成员的访问修饰符。公共访问是允许的最高访问级别。对访问公共成员没有限制。)
- internal:在同一命名空间内可以访问。
(internal关键字是类型和类型成员的访问修饰符。只有在同一程序集的文件中,内部类型或成员才是可访问的。)
(二)重写(覆盖)和重载的区别
区别:
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同,参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。
A、方法重载是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不是完全相同。
B、方法重写是存在子父类之间的,子类定义的方法与父类中的方法具有相同的方法名字,相同的参数列表和相同的返回类型。
注意:
(1)子类不能重写父类中的final方法。
(2)子类中必须重写父类中的abstract方法。
重写方法的规则:
1、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
2、返回的类型必须与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
3、访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4、重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:
父类的一个方法申明了一个检查异常IOException,在重写这个方法时就不能抛出exception,只能抛出IOException的子类异常,可以抛出非检查异常。
重载的规则:
必须具有不同的参数列表。
可以有不责骂的返回类型,只要参数列表不同就可以。
可以有不同的访问修饰符。
可以抛出不同的异常。
(三)编程实现一个冒泡排序算法
//冒泡排序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 测试
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
int a = 0;
int[] num = new int[] {19,1,38,49,85,16,867,282 };
for (int i = 0; i < num.Length - 1; i--)
{
for (int j = 0; j < num.Length - 1 - i; j++)
{
if(num[j]>num[j+1])
{
a = num[j];
num[j] = num[j + 1];
num[j + 1] = a;
}
}
}
foreach (int number in num)
{
Console.WriteLine(number+"");
}
Console.ReadKey();
}
}
}
(四)string str=null和string str=""的区别
String str=null
这句含义是定义一个字符串,变量str,字符串内容为空值。
String str=“”
定义一个String类型的变量str,并为其赋值。
区别:
- “”分配了内存;null没有分配内存
- “”是一个字符串(String),他在内存中是存在的,而null是一个空对象,在内存中是不存在的。
- “”占内存,在内存中会分配一个空间
string str=null和string str=""的区别
(五)什么是sql注入 怎么防止sql注入
SQL注入是一种将SQL代码添加到输入参数中,传递到SQL服务器解析并执行的一种攻击手法。SQL注入攻击就是输入参数未经过滤,直接拼接到SQL语句中,解析执行,达到预想之外的行为。
SQL注入是如何产生的?
- web开发人员无法保证所有的输入都已经过滤
- 攻击者利用发送给SQL服务器的输入数据构造可执行代码
- 数据库未做相应的安全配置(对web应用设置特定的数据库账号,而不使用root或管理员账号,特定数据库账号给予一些简单操作的权限,回收一些类似drop的操作权限)
(六)进程和线程的区别
1、进程是资源分配的最小单位,线程是程序执行的最小单位。
2、进程有自己的独立地址空间,每启动一个进程,系统就会为他分配地址空间,建立数据表来维护代码段,堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
3、线程之间的通信更方便,同一进程下的线程共享全局变量,静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。
4、但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另一个进程造成影响,因为进程有自己独立的地址空间。
(七)堆和栈的区别
程序的内存分配:
由C/C++编译的程序占用的内存分为以下几部分:
1、栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意他与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(static(静态区)):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。
4、文字常量区:常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区:存放函数体的二进制代码。
(八)C#中接口的定义和命名规则
接口定义使用Pascal规则,且必须以大写“I”开头。接口名称要有意义,中间不要有下划线“_”等字符。如果类实现了接口,名称尽量和接口相同,只是省略“I”字符。
(九)接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可以继承实体类?
1、接口可以继承接口么?
可以,用extends关键字,而且支持多重继承。
2、抽象类可以继承接口么?
可以实现,用implements关键字。
3、抽象类可以继承实体类么?
可以,抽象类中可以有实体方法,即可以继承实体类。
(十)C#中try catch finally基本结构
1、try:将预见可能引发异常的代码包含在try语句块中。
2、catch:如果发生了异常,则转入catch的执行。
3、finally:finally可以没有,也可以只有一个。无论有没有发生一次,他总会在这个异常处理结构的最后运行。即使在try块内用return返回了,在返回前,finally总是要执行,这以便让你有机会能够在异常处理最后做一些清理工作。如关闭数据库连接等。
注意:如果没有catch语句块,那么finally块就是必须的。
(十一)什么是触发器?
触发器是一种特殊的存储过程,他在试图更改触发器所保护的数据时自动执行。他被定义为在对表或视图发出update,insert,delete语句时自动执行,在有数据修改时自动强制执行其业务规则。