DotNet 经典面试题(在面试中提炼总结所出,面试的朋友必备)
.Net基础常见
什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS、CLR分别作何解释?
答:
1应用程序域可以理解为一种轻量级进程。起到安全的作用。占用资源小
2.unsafe:非托管代码。不经过CLR运行。
3.RTTI:类型识别系统。
4从值类型接口转换到引用类型装箱。从引用类型转换到值类型拆箱。,
5. 重载就是指一个方法名同,参数个数不同,返回值可以相同的方法.
6.CTS:通用语言系统。CLS:通用语言规范。CLR:公共语言运行库。
简述 private、 protected、 public、 internal 修饰符的访问权限。
答 . public : 公共成员,完全公开,没有访问限制。
private : 私有成员, 在类的内部才可以访问。
protected : 保护成员,该类内部和继承类中可以访问。
internal: 应用于类型和内嵌类型的所有成员。 只有在包含它的程序集合派生类型的代码中访问该方法
请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。
session(viewstate) 简单,但易丢失
application 全局
cookie 简单,但可能不支持,可能被伪造
Form表单传值(post,get)
input ttype="hidden" 简单,可能被伪造()
url参数简单,显示于地址栏,长度有限
this.Server.Transfer
数据库稳定,安全,但性能相对弱
ADO.net中常用的对象有哪些?分别描述一下。
Connection:连接
DataSet:数据存储器。
DataCommand:执行语句命令。
DataAdapter:数据的集合,用语填充。
.DataReader与Dataset有什么区别?
答:一个是只能向前的只读游标,一个是内存中的表。
委托声明的关键字是______?
答:delegate.
在.net中,配件的意思是?
答:程序集。(中间语言,源数据,资源,装配清单)
在.Net中所有可序列化的类都被标记为_____?
答:[serializable]
堆和栈的区别?
答:
栈:由编译器自动分配、释放。在函数体中定义的变量通常在栈上。
堆:一般由程序员分配释放。用new、malloc等分配内存函数分配得到的就是在堆上
在c#中using和new这两个关键字有什么意义,请写出你所知道的意义?
Using 引入一个名子空间,或在使用了一个对像后自动调用其IDespose,New 实例化一个对像,或修饰一个方法,表此方法完全重写此方法
概述o/r mapping 的原理
利用反射,配置 将类于数据库表映射
是否可以继承String类?
答:String类是final类故不可以继承。
.net的错误处理机制是什么
.net错误处理机制采用try->catch->finally结构,发生错误时,层层上抛,直到找到匹配的Catch为止。
try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
答:会执行,在return前执行。
short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
答:short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。
在.net(C# or vb.net)如何启动另一个程序。Process
在.net(C# or vb.net)中如何取消一个窗体的关闭
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel=true;
}
在C#中,string str = null 与 string str = “” 请尽量使用文字或图象说明其中的区别。
答:string str = null 是不给他分配内存空间,而string str = "" 给它分配长度为空字符串的内存空间。
String s = new String("xyz");创建了几个String Object? (在Java中)
答:两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。
在.net(C# or vb.net)中,Appplication.Exit 还是 Form.Close有什么不同?
答案:一个是退出整个应用程序,一个是关闭其中一个form
面向对象的语言具有________性、_________性、________性
答:封装、继承、多态。
能用foreach遍历访问的对象需要实现 ________________接口或声明________________方法的类型。
答:IEnumerable 、 GetEnumerator。
GC是什么? 为什么要有GC?
答:GC是垃圾收集器。程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()
进程和线程的区别?
答:进程是系统进行资源分配和调度的单位;线程是CPU调度和分派的单位,一个进程可以有多个线程,这些线程共享这个进程的资源。
启动一个线程是用run()还是start()?
答:启动一个线程是调用start()方法,run()方法可以产生必须退出的标志来停止一个线程。
sleep() 和 wait() 有什么区别?
答:sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级
什么叫线程同步?列举3种实现线程同步的方法。
为了确保读线程读取到的是经过修改的变量,就必须在向变量写入数据时禁止其他线程对其的任何访问,直至赋值过程结束后再解除对其他线程的访问限制。象这种保证线程能了解其他线程任务处理结束后的处理结果而采取的保护措施即为线程同步。
方法:
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
成员变量和成员函数前加static的作用?
答:它们被称为常成员变量和常成员函数,又称为类成员变量和类成员函数。分别用来反映类的状态。比如类成员变量可以用来统计类实例的数量,类成员函数负责这种统计的动作。
请详述在dotnet中类(class)与结构(struct)的异同?
答:Class可以被实例化,属于引用类型,是分配在内存的堆上的,Struct属于值类型,是分配在内存的栈上的.,访问方式和一些特征(如结构不支持继承)"有所不同。
接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
答:接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。
构造器Constructor是否可被override?
答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。
override与重载的区别
override 与重载的区别。重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要
Override 是进行基类中函数的重写。为了适应需要。
1、方法的覆盖是子类和父类之间的关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系
2、覆盖只能由一个方法,或只能由一对方法产生关系;方法的重载是多个方法之间的关系。
3、覆盖要求参数列表相同;重载要求参数列表不同。
6.C#中的接口和类有什么异同。
答:接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念!
而类是负责功能的具体实现!
在类中也有抽象类的定义,抽象类与接口的区别在于:
抽象类是一个不完全的类,类里面有抽象的方法,属性,也可以有具体的方法和属性,需要进一步的专业化。
但接口是一个行为的规范,里面的所有东西都是抽象的!
一个类只可以继承一个基类也就是父类,但可以实现多个接口
谈谈final, finally, finalize的区别。
答:
final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此 一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中 不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为 final的方法也同样只能使用,不能重载
finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会 执行,然后控制就会进入 finally 块(如果有的话)。
finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理 工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的 ,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
abstract class和interface有什么区别?
答:
声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。
C#中的委托是什么?事件是不是一种委托?有哪些特点?
委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值
委托可以把一个方法作为参数代入另一个方法。
委托可以理解为指向一个函数的引用。
是,是一种特殊的委托
委托具有以下特点:
委托类似于 C++ 函数指针,但它是类型安全的。
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以链接在一起;例如,可以对一个事件调用多个方法。
方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。
列举一下你所了解的XML技术及其应用
答:xml用于配置,用于保存静态数据类型.接触XML最多的是web Services..和config
DTD和Schema都是用于哪方面的?它们主要有什么区别?
XML即可扩展标记语言
DTD和Schema都对某一类XML文档进行约束并确定其结构的一套规则。
区别:
XML Schema是一种内容“开放”的模型,可扩展、功能强,而DTD是内容“封闭”的模型,可扩展性差;
缓存有什么作用?ASP.NET的缓存分为哪3种?应用程序缓存又分为哪4种?
作用:把访问频繁的数据以及需要大量处理时间来创建的数据存储在内存中,当用户请求这些数据时,系统直接将内存中的数据返回给用户,从而大大提高应用程序的性能。
ASD.NET的缓存分为:整页缓存、页面部分缓存和应用程序缓存
应用程序缓存分:定时缓存、滑动缓存、文件依赖缓存和数据库依赖缓存
常用的缓存 Cache 它有健全的依赖和过期策略
概述反射和序列化
反射:程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性
序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。在另一端,反序列化将从该流重新构造对象。
请简述一下用Socket进行同步通讯编程的详细步骤
1、在应用程序和远程设备中使用协议和网络地址初始化套接字
2、在应用程序中通过指定端口和地址建立监听
3、远程设备发出连接请求
4、应用程序接受连接产生通信scoket
5、应用程序和远程设备开始通讯(在通讯中应用程序将挂起直到通讯结束)
6、通讯结束,关闭应用程序和远程设备的Socket回收资源
.net Remoting 的工作原理是什么?
答:服务器端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置。
解释一下UDDI、WSDL的意义及其作用
UDDI 即统一描述、发现和集成协议, UDDI计划是一个广泛的,开放的行业计划,SOAP简单对象访问协议)规范的早期版本。
WSDL的缩写,是一个用来描述Web服务和说明如何与Web服务通信的XML语言。
什么是SOAP,有哪些应用。
答:SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的协议,是一个基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一直语言相互通信。这种相互通信采用的是XML格式的消息
常用的调用WebService的方法有哪些?
答:0.浏览器发送请求
1.使用WSDL.exe命令行工具。
2.使用VS.NET中的Add Web Reference菜单选项
简要谈一下您对微软.NET 构架下remoting和webservice两项技术的理解以及实际中的应用。
答:WS主要是可利用HTTP,穿透防火墙。而Remoting可以利用TCP/IP,二进制传送提高效率。
如何处理几十万条并发数据?
答:用存储过程或事务。
软件开发过程一般有几个阶段?每个阶段的作用?
答:需求分析,架构设计,代码编写,QA,部署
Asp.net常见
ASP.net的身份验证方式有哪些?分别是什么原理?
答:1Windwos(默认)用IIS...From(窗体)用帐户....Passport(密钥)
ASP。NET与ASP相比,主要有哪些进步?
答:asp解释形,aspx编译型,性能提高,有利于保护源码。
ASP.NET 页生命周期概述
答:页请求,开始,页初始化,加载,验证,回发事件处理,呈现,卸载
Session有什么重大BUG,微软提出了什么方法加以解决?
答:是iis中由于有进程回收机制,系统繁忙的话Session会丢失,可以用Sate server或SQL Server数据库的方式存储Session不过这种方式比较慢,而且无法捕获Session的END事件。
什么是ASP.net中的用户控件
答:用户控件就是.ascx扩展名的东西喽,可以拖到不同的页面中调用,以节省代码.比如登陆可能在多个页面上有,就可以做成用户控件,但是有一个问题就是用户控件拖到不同级别的目录下后里面的图片等的相对路径会变得不准确,需要自已写方法调整.
向服务器发送请求有几种方式?
答:get,post。get一般为链接方式,post一般为按钮方式。
<%#%>和<%%> 有什么区别?
答:表示绑定的数据源
是服务器端代码块
在Asp.net中所有的自定义用户控件都必须继承自________?
答:Control。
url重写有几种方式?
ISAPI重写
IIS重写
PageXChanger
HttpHandle和HttpModul有何区别?什么情况下用Handle,什么时候用Modul?
HttpHanders的主要目的是处理对某种特定文件或者在URL中对某个文件路径的请求,HttpHandle是HTTP请求的真正处理中心,可以针对截获的这个HTTP请求信息做一些额外的工作,或者在某下情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个过滤器的作用,而HttpModule则主要被用于在最开始的阶段处理一个请求以及在最后阶段处理一个响应。
数据库常见
DDL :数据定义语言,用于定义和管理 SQL 数据库中的所有对象的语言
常用的有Crreate 创建,Alter 修改Drop 删除 Truncate 删除表 等 对象
DML:数据操作语言,SQL中处理数据等操作统称为数据操纵语言
常用的有 Select,Insert,Update,Delete
DCL:数据控制语言,用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等
常用的有 Commit 提交,SavePoint 保存点,RollBack 回滚
SQLSERVER服务器中,给定表 table1 中有两个字段 ID、LastUpdateDate,ID表示更新的事务号, LastUpdateDate表示更新时的服务器时间,请使用一句SQL语句获得最后更新的事务号
答:Select ID FROM table1 Where LastUpdateDate = (Select MAX(LastUpdateDate) FROM table1)
写出一条Sql语句:取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的。
答:解1: select top 10 * from A where id not in (select top 30 id from A)
解2: select top 10 * from A where id > (select max(id) from (select top 30 id from A )as A)
但在工作中常用的自己写的通用分页存储过程
如果应用程序变慢,代码已优化,数据库已建索引,还有有哪些优化方案?
多使用存储过程,合理使用视图,减少多表连接,根据数据量大的情况可以考虑建数据库分区,数据仓库。
如何处理几十万条并发数据?
答:用存储过程或事务。取得最大标识的时候同时更新..注意主键不是自增量方式这种方法并发的时候是不会有重复主键的..取得最大标识要有一个存储过程来获取.
题目1为管理岗位业务培训信息,建立3个表:
S (S#,SN,SD,SA) S#,SN,SD,SA 分别代表学号、学员姓名、所属单位、学员年龄
C (C#,CN ) C#,CN 分别代表课程编号、课程名称
SC ( S#,C#,G ) S#,C#,G 分别代表学号、所选修的课程编号、学习成绩
1. 使用标准SQL嵌套语句查询选修课程名称为 税收基础 的学员学号和姓名
Select SN,SD FROM S Where [S#] IN ( Select [S#] FROM C,SC Where C.[C#]=SC.[C#] AND CN=N'税收基础')
2. 使用标准SQL嵌套语句查询选修课程编号为’C2’的学员姓名和所属单位
Select S.SN,S.SD FROM S,SC
Where S.[S#]=SC.[S#] AND SC.[C#]='C2'
3. 使用标准SQL嵌套语句查询不选修课程编号为’C5’的学员姓名和所属单位
Select SN,SD FROM S
Where [S#] NOT IN
( Select [S#] FROM SC
Where [C#]='C5')
4. 使用标准SQL嵌套语句查询选修全部课程的学员姓名和所属单位
SELECT SN, SD FROM S
WHERE S#
IN (SELECT SC.S#
FROM SC RIGHT JOIN C
ON SC.C# = C.C#
GROUP BY SC.S# --在结果集中以学生分组,分组后的 SC.C#选课数=C.C#课程数 即为全部课程
HAVING COUNT(distinct(SC.C#)) --注意:一个学生同一门课程可能有多条成绩记录,需要distinct
= ( select count(*) from C ) --注意:HAVING条件不能用COUNT(distinct(SC.C#)) = COUNT(distinct(C.C#)
)--子查询获得选修全部课程的学生学号
5. 查询选修了课程的学员人数
Select 学员人数=COUNT(DISTINCT [S#]) FROM SC
6. 查询选修课程超过5门的学员学号和所属单位 Select SN,SD FROM S
Where [S#] IN ( Select [S#] FROM SC
GROUP BY [S#]
HAVING COUNT( DISTINCT [C#] ) > 5 )
题目2,已知关系模式:
S (SNO,SNAME) 学生关系。SNO 为学号,SNAME 为姓名
C (CNO,CNAME,CTEACHER) 课程关系。CNO 为课程号,CNAME 为课程名,CTEACHER 为任课教师
SC(SNO,CNO,SCGRADE) 选课关系。SCGRADE 为成绩
1. 找出没有选修过“李明”老师讲授课程的所有学生姓名
Select SNAME FROM S
Where NOT EXISTS ( Select * FROM SC,C
Where SC.CNO=C.CNO
AND CNAME='李明'
AND SC.SNO=S.SNO)
2. 列出有二门以上(含两门)不及格课程的学生姓名及其平均成绩
Select S.SNO,S.SNAME,AVG_SCGRADE=AVG(SC.SCGRADE)
FROM S , SC ,
(Select SNO FROM SC
Where SCGRADE<60
GROUP BY SNO
HAVING COUNT(DISTINCT CNO)>=2) A
Where S.SNO=A.SNO AND SC.SNO=A.SNO
GROUP BY S.SNO,S.SNAME
3. 列出既学过“1”号课程,又学过“2”号课程的所有学生姓名
Select S.SNO,S.SNAME
FROM S,
(Select SC.SNO FROM SC,C
Where SC.CNO=C.CNO
AND C.CNAME IN('1','2')
GROUP BY SNO
HAVING COUNT(DISTINCT CNO)=2
)SC
Where S.SNO=SC.SNO
4. 列出“1”号课成绩比“2”号同学该门课成绩高的所有学生的学号
Select S.SNO,S.SNAME
FROM S,
(Select SC1.SNOFROM SC SC1,C C1,SC SC2,C C2
Where SC1.CNO=C1.CNO AND C1.NAME='1'
AND SC2.CNO=C2.CNO AND C2.NAME='2'
AND SC1.SCGRADE>SC2.SCGRADE ) SC
Where S.SNO=SC.SNO
5. 列出“1”号课成绩比“2”号课成绩高的所有学生的学号及其“1”号课和“2”号课的成绩
Select S.SNO,S.SNAME,SC.[1号课成绩],SC.[2号课成绩]
FROM S,
( Select SC1.SNO,[1号课成绩]=SC1.SCGRADE,[2号课成绩]=SC2.SCGRADE
FROM SC SC1,C C1,SC SC2,C C2
Where SC1.CNO=C1.CNO AND C1.NAME='1'
AND SC2.CNO=C2.CNO AND C2.NAME='2'
AND SC1.SCGRADE>SC2.SCGRADE) SC
Where S.SNO=SC.SNO
题目3:
======
有如下表记录:
ID Name EmailAddress LastLogon
100 test4 test4@yahoo.cn 2007-11-25 16:31:26
13 test1 test1@yahoo.cn 2007-3-22 16:27:07
19 test1 test1@yahoo.cn 2007-10-25 14:13:46
42 test1 test1@yahoo.cn 2007-11-20 14:20:10
45 test2 test2@yahoo.cn 2007-4-25 14:17:39
49 test2 test2@yahoo.cn 2007-5-25 14:22:36
用一句sql查询出每个用户最近一次登录的记录(每个用户只显示一条最近登录的记录)
SELECT a.* from users a inner join
(SELECT [Name], LastLogon=MAX(LastLogon) FROM users GROUP BY [Name]) b
on a.[Name]=b.[Name] and a.[LastLogon]=b.[LastLogon]
编程题常见
a=10,b=15,在不用第三方变量的前提下,把a,b的值互换(需要代码最短)
a=a+b; //a=10+15 ,a=25
b=a-b; //b=25-15 ,b=10
a=a-b; //a=25-10 ,b=15
规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。
public static int Foo(int i)
{
if (i <= 0)
return 0;
else if (i > 0 && i <= 2)
return 1;
else return Foo(i - 1) + Foo(i - 2);
}
请编程实现一个冒泡排序算法?
/// <summary>
/// int数组排序
/// </summary>
/// <param name="array">需要排序的int集合</param>
/// <param name="sortOrder">排序规则:true 升序,false降序</param>
public static int[] IntArraySort(int[] array, bool isSortAsc)
{
if (array == null || array.Length < 2)
{
throw new ArgumentException("数组必须不为空且数组长度大于2否则无法排序!");
}
int temp; //临时变量,保存最大,小值
for (int j = 0; j < array.Length; j++)
{
for (int i = 0; i < array.Length - j - 1; i++)
{
if (isSortAsc)
{
#region 升序开始交换
if (array[i] > array[i + 1]) // 如果 array[i] > array[i+1] ,则 array[i] 上浮一位,为升序,否则下浮一位为降序
{
temp = array[i]; //开始交换
array[i] = array[i + 1];
array[i + 1] = temp;
}
#endregion
}
else
{
#region 降序开始交换
if (array[i] < array[i + 1])
{
temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
}
#endregion
}
}
}
return array;
}
求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m
public int SumNumber(int num)
{
int Sum = 0;
for (int i = 0; i < num + 1; i++)
{
if ((i % 2) == 1)
{
Sum += i;
}
else
{
Sum = Sum - i;
}
}
return Sum;
}
获得数组最大子数组的和
public static int GetMaxChild(int[] intArr)
{
if (intArr == null || intArr.Length == 0)
{
throw new ArgumentException("传入没有内容的数组!");
}
int result = 0; // 最大和
int tempSum = 0; // 累加和
int maxNegative = intArr[0]; // 数组最大值
for (int i = 0; i < intArr.Length; i++)
{
if (tempSum <= 0)
{
tempSum = intArr[i]; // 始终保持为正,左边如果为负数则抛弃
}
else
{
tempSum += intArr[i];
}
if (tempSum > result)
{
result = tempSum; // 始终保持最大的和
}
if (intArr[i] > maxNegative)
{
maxNegative = intArr[i];
}
}
if (maxNegative < 0)
{
return maxNegative; // 所有数都为负数,只返回最大的一个数
}
return result;
}
返回阶加结果
public static int GetIntSum(int n)
{
if (n == 0)
{
return n;
}
else
{
return n + GetIntSum(n - 1);
}
}
public static bool GetIntSum(int n, ref int sum)
{
sum += n;
return (n - 1 <= 0) || (GetIntSum(n - 1, ref sum));
}
查找指定出现次数的第一个字符
/// <summary>
/// 查找指定出现次数的第一个字符
/// </summary>
/// <param name="str">需要查找的字符</param>
/// <param name="charFindCount">查找次数</param>
/// <returns></returns>
public static string FindFirstCountChar(string str, uint charFindCount)
{
#region 参数验证
if (str == null || str == string.Empty)
{
throw new ArgumentException("请输入需要查找的字符!");
}
if (charFindCount < 1)
{
throw new ArgumentException("查找字符出现的次数应大于0!");
}
#endregion
int count = 0; //字符出现的次数
for (int i = 0; i < str.Length; i++)
{
char currentChar = str[i]; //需要查找的字符
for (int j = 0; j < str.Length; j++) //在string数组中循环查找
{
if (currentChar == str[j])
{
count += 1;
}
}
if (count == charFindCount)
{
return currentChar.ToString();
}
count = 0;
}
return null;
}
产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
解法一:
解法二:最近学习Linq,写了一个Linq版的:
int[] result = Enumerable.Range(1,100).OrderBy
(n=>Guid.NewGuid()).Take(100).ToArray();
我开始写的,但后来测试随着集合项越来越大就不停做无用循环,我测试1到1000循环次数是在 2844588次左右,更大就不说了 ,效率低下
解法三:
思路: 用一个数组来保存索引号,先随机生成一个数组位置,然后把这个位置的索引号取出来,并把最后一个索引号复制到当前的数组位置,然后使随机数的上限减一,具体如:先把这100个数放在一个数组内,每次随机取一个位置(第一次是1-100,第二次是 1-99,...),将该位置的数用最后的数代替。
/// <summary>
/// 获得不重复的随机数数组
/// </summary>
/// <param name="min">取值范围:开始值</param>
/// <param name="max">取值范围:结束值</param>
/// <param name="count">数组大小</param>
/// <returns></returns>
public static int[] GetRandomDistinctIntArray(int minValue, int maxValue, int count)
{
int length = (maxValue - minValue) + 1; //取值个数
#region 参数验证
if (minValue <= 0 || maxValue < 2)
{
throw new ArgumentException("输入开始值大于0且结束值大于1!");
}
if ((maxValue - minValue) <= 0)
{
throw new ArgumentException("输入开始值和结束值之间的取值个数应大于1!");
}
if (minValue > maxValue)
{
throw new ArgumentException("输入开始值必须小于结束值!");
}
if (count > length)
{
throw new ArgumentException("数组大小必须小于或等于取值个数!");
}
#endregion
int[] intList = new int[length]; //临时数组
for (int i = 0; i < length; i++) //初始化一个顺序数组
{
intList[i] = i + minValue;
}
int[] intRet = new int[count]; //用于存储结果的数组
int n = length;
Random rand = new Random();
#region 交换元素
for (int i = 0; i < count; i++) //交换元素
{
int randomNumber = rand.Next(minValue, maxValue + 1);
int index = randomNumber - minValue; //索引值
intRet[i] = intList[index]; //把当前随机数的值放在存储结果的数组里
intList[index] = intList[--n]; //将当前随机数放到临时数组的最后面
maxValue--; //缩小取值范围
}
#endregion
return intRet;
}