天津网站建设品牌推广,做食品怎样选网站,无极在线招聘招工最新招聘,博物馆网站建设说明C#中的数值类型 堆和栈
值类型的数据被保存在栈#xff08;stack)上#xff0c;而引用类型的数据被保存在堆#xff08;heap#xff09;上#xff0c;当值类型作为参数传递给函数时#xff0c;会将其复制到新的内存空间中#xff0c;因此在函数中对该值类型的修改不会影…C#中的数值类型 堆和栈
值类型的数据被保存在栈stack)上而引用类型的数据被保存在堆heap上当值类型作为参数传递给函数时会将其复制到新的内存空间中因此在函数中对该值类型的修改不会影响原始值类型。
拆箱和装箱是什么
装箱是指将值(int double)类型转换为对应的引用(object)类型从内存角度上来说是将栈中的内容迁移到堆上 拆箱就是把引用转成值类型把堆中的内容转移到栈上去
int i3;
objcet oi;//装箱
i(int)o //拆箱值和引用类型在变量赋值时的区别是什么
值类型变量赋值会创建一个新的拷贝而引用类型变量赋值会创建一个新的引用指向同一个对象。
委托和事件在使用上的区别是什么
事件相对与委托来说事件在外部使用时只能使用 -
有两个接口IA和IB他们中有一个同名方法Test()
一个类同时继承这两个接口应该如何处理他们的同名方法
显式实现接口IA.Test()
IB.Test()在C#中数据类型分为值类型和引用类型 值类型结构体、枚举 引用类型类、接口、数组、委托
请说明C#中的List是如何扩容的
当 List 需要扩容时它会创建一个新的更大的内部数组并将现有元素复制到新数组中然后使用新数组替换旧数组
请说说你认为C#中 和 Equals 的区别是什么
Equals继承自Object一般用于比较对象内容是否相等而在不重载的前提下如果是值类型更倾向于比较值是否相等引用倾向于比较地址是否相等运算效率也不同Equals比较的内容多所以效率会差一点
浅拷贝和深拷贝的区别可以举例说明
浅拷贝只拷贝指针C引用C拷贝完的数据修改了原数据也会修改但是深拷贝就是拷贝了一份新的修改并不会影响原数据
上面两种获10000个数的方式哪种效率更高为什么 方式2因为List会不断扩容扩容时会反复拷贝造成性能损耗 请说出以下代码AB谁先打印AB打印的值分别为多少
void Start(){int iGetInt();Debug.Log(第A处 i i);}static int GetInt(){int i10;try{return i;}finally{i11;Debug.Log(第B处 i i);}}不论try块中的代码是否抛出异常finally块中的代码都会被执行 先输出B11然后输出A10
public class CsharpLearing : MonoBehaviour
{void Start(){Test tGetObj();Debug.Log(第A处 i t.i);}static Test GetObj(){Test tnew Test();try{return t;}finally{t.i11;Debug.Log(第B处 i t.i);}
}
}class Test{public int i10;
}这里和上面不一样先输出B11然后输出A11
这两段程序输出不同的原因是因为Getint返回的是值类型而getObj返回的是引用类型
泛型的约束有哪几种
值类型约束引用类型约束公共无参数构造函数类约束接口约束另一个泛型约束
什么是闭包举例说明
闭包是指有权访问另一个函数作用域中变量的函数用lambda或匿名方法实现可以捕获不属于其作用域的值
C#中内存泄漏
静态引用如果一个静态对象长时间存活且占用大量内存并且该对象不会被释放或重置可能导致内存泄漏不使用的引用对象没有置null委托或事件没有解除注册
请说明字符串中
string str null string str “” string str string.Empty 三者的区别 str null 在堆中没有分配内存地址 str “” 和 string.Empty 一样都是在堆内存中分配了空间里面存储的是空字符串 string.Empty是一个静态只读变量
对string和StringBuilder我们应该如何选择 string是不可变的意味着一旦创建了字符串对象就无法更改其内容。任何对字符串的修改都会创建一个新的字符串对象。线程更安全 StringBuilder是可变的可以通过对其进行操作来修改其内容而不必创建新的对象。这使得在需要频繁修改字符串时使用StringBuilder比使用string更高效。线程不安全 string在每次拼接时都会产生垃圾 而StringBuilder在拼接时是在原空间中进行修改不会产生垃圾会自动帮助我们扩容 所以当字符串需要频繁修改拼接时我们使用StringBuilder
.Net跨语言原理
.Net制定了了CLI公共语言基础结构的规则 只要是按照该规则设计的语言在进行.Net相关开发时 编译器会将源代码C#、VB等等编译为CIL通用中间代码。 也就是说不管什么语言进行开发最终都会统一规范变为中间代码 最终通过CLR公共语言运行时或者称为.Net虚拟将中间代码翻译为对应操作系统的原生代码机器码 在操作系统Windows上运行
C# 中的Action和Func是什么Unity 中的UnityAction是什么他们有什么区别
Action和Func是System命名空间下 C#为我们提供的两个写好的委托 Action本身是一个无参无返回值的委托 对应的Action泛型委托支持最多16个参数
Func本身是一个无参有返回值的委托 对应的Func泛型委托支持最多16个参数并且有返回值
UnityAction是UnityEngine.Events命名空间下 Unity为我们提供的写好的委托 UnityAction本身是一个无参无返回值的委托 对应的UnityAction泛型委托支持最多4个参数
程序阅读 public void Dosomething (A a){a.id6;a.nameBob;a.children[0]7;}void Start(){var anew A();a.nameAlick;a.childrennew int[]{1,2,3};Dosomething(a);Debug.Log(a.namea.ida.children[0]);}输出Alick07
请问以上这三行代码运行后在堆上会分配几块内存 两块 123一块 1234一块
C#中如何让一个类不能再被其他类所继承
使用密封关键字sealed修饰该类
C#中使用泛型的好处是什么
1.可以为不同类型对象的相同行为进行通用处理提升代码复用率 2.避免装箱拆箱提升性能
C#中元组对于我们的作用是什么 可以在不用写数据结构类的情况下 利用元组处理多返回值或者临时数据的集合
请简述GC垃圾回收产生的原因并至少说出避免GC发生的三种方式
GC产生的原因是 避免堆内存溢出而产生的回收机制 当不再使用的堆内存占用达到一定上限时将会进行垃圾回收
避免方式 1.尽量减少new对象尽量复用对象可使用缓存池 2.用StringBuilder替换String避免字符串拼接时产生垃圾 3.公共对象用静态声明
如果我们想为Unity中的Transform类添加一个自定义的方法应该如何处理
通过C#的拓展方法相关知识点进行添加
请说出using关键字的两个作用
1.引入命名空间 2.安全使用引用对象
C#中Dictionary不支持相同键存储如果想要一个键对应多个值如何处理 程序阅读 全是10当委托最终执行时他们使用的i都是for循环中声明的i此时的i已经变成了10
如果我想要输出1~10怎么办
使用一个临时变量接当前值
内存抖动指什么
内存抖动指短时间内有大量的对象被创建或者被回收的现象 频繁的内存抖动会造成 GC 频繁运行造成卡顿
C#中new关键字的作用至少说出3种
创建新对象子类函数声明时加上new关键字可以隐藏掉父类方法泛型约束时使用new关键字表示需要无参构造
回调函数指什么一般在什么时候使用至少说出3种使用场景
异步编程异步逻辑执行完毕后再执行回调函数事件中心UI界面中的空间逻辑回调比如按钮点击
csharp里面有一个常用的接口叫做IDispose它的作用是
IDispose接口是 C# 中用于手动释放资源的机制 通过显式调用 Dispose() 方法来实现资源的释放避免资源泄漏和浪费 它允许对象在不再需要时显式地释放资源而不依赖于垃圾回收器的自动内存管理
csharp有垃圾回收机制把一个对象设置为空的时候系统会帮我们回收它和接口IDispose有什么关系吗为什么会存在两个做析构事情的东西呢
C#中的垃圾回收机制只会回收托管堆上分配的对象。 对于非托管资源以及其它需要显示释放的资源垃圾回收是无法自动处理的因为这些资源不属于托管堆因此垃圾回收器无法自动识别和回收。这种情况下我们就需要显示的手动释放这些资源了。 而IDispose接口就提供了一种通用的机制来进行资源清理主要用于释放非托管资源。
非托管资源
文件句柄在操作系统中打开的文件等数据库链接与数据库服务器简历的链接网络链接比如Socket的连接对象unsafe关键词中使用的指针
属性和字段
属性一般可以用来封装字段
属性相对字段来说属性具有封装性允许对字段进行封装提供更多的控制和逻辑。 相比直接访问字段来说属性允许我们在字段访问的过程汇总添加验证、计算等逻辑
属性还可以在其中对set和get设置不同的访问级别使得字段的读取和写入可以收到更精细的控制
抽象类中的虚函数和抽象函数是否必须在子类中重写
虚函数的重写是可选的当需要在子类中修改逻辑时可以选择重写 抽象函数必须重写
里氏替换
当我们使用里式替换原则用父类容器装载子类对象时 我们通过该父类容器调用其中的一个虚函数执行的逻辑是父类中的还是子类中的逻辑呢
Father Eat
Son Father
Son EatFather f new Son();
f.Eat();若子类没有重写虚函数那么执行的逻辑会是父类中的逻辑若子类重写了虚函数那么执行的逻辑会是子类中的逻辑是否执行父类中逻辑主要看子类重写时是否利用了base执行父类逻辑
C#使用var声明临时变量相比用指定变量类型声明临时变量在最终执行时是否会增加性能消耗
var i 10;
float f 5.5f;不会var在编译时会被推断为正确的类型所以在运行时不会引入额外的性能开销。 相当于在编译阶段var就会被翻译为指定的类型。
var声明临时变量只会影响代码的可读性和可维护性(双刃剑)
我们可以使用C#中的迭代器来做什么至少说出两点
foreach协同程序
工厂模式在游戏开发中一般用来做什么
对象实例化 对于需要频繁创建的对象比如角色、敌人、道具、特效、音效等等工厂模式可以将实例化逻辑封装到一个工厂类中提供统一方法给外部调用
C#中如何在函数中返回多个返回值至少说出3种方法
数组等容器结构体或类自定义数据结构out参数元组
int[,] strArray new int[3, 4]这个语句创建了多少个int对象string[,] strArray new string[3, 4]这个语句创建了多少个string对象
12个0个
避免装箱拆箱的方案有哪些
用泛型使用里氏替换原则
什么是闭包为什么说闭包可能会带来内存泄漏
闭包可能会捕获并持有外部作用域变量的引用。 这些引用会导致外部作用域的对象持续存在即使它们不再需要。
C#中在字符串前面加一个符号或者$符号有什么作用
符号让转义字符失效 $符号插值字符串可以在字符串中加入 {变量名} 插入变量值
C#中提供了序列化和反序列化2进制数据的公共类BinaryFormatter为什么我们一般还要自己去实现序列化和反序列化2进制数据的方法
BinaryFormatter跨平台方面不好自己写更容易进行加密处理节约空间BinaryFormatter会包含一些除数据以外的额外信息
异或加密的原理是什么请简要说明
异或加密是一种简单的对称加密算法。原理就是基于异或运算相同为0不同为1。 异或加密时会有一个固定的密钥 想要加密的数据与该密钥进行异或运算得到加密后的数据 加密后的数据再和密钥进行异或运算得到原数据解密后的数据
举例 假设原数据为1010 密钥为1100 加密后的数据为1010^1100 0110
解密数据0110^1100 1010
程序阅读
public FatherFatherint Test()
{return new SonSonint();
}
这个写法是否正确不正确会报错 因为SonSon并不是FatherFather的子类型 如果要修改 我们可以返回 return new SonFather();
C#类中的函数是否占用内存空间
占用但是它不再我们通常说的堆栈中 而是存储在内存中的文本段Text Segment 它是存储可执行程序的代码的内存段
C#中的函数是何时被加载到内存中的呢
CLR公共语言运行时会按需加载程序集和其中的类型和成员 程序执行到需要调用某个类的函数时 CLR 会负责将该函数的 IL 代码编译成本机代码 并将其加载到 Text Segment 中 一旦函数的代码被加载到内存中它通常会一直存在于内存中直到程序退出
C#函数中一般会声明一些临时变量当函数被加载内存中后所占的内存空间是否包含函数中的这些临时变量
不会包含。 函数中的临时变量不管是值类型还是引用类型都是在函数执行期间动态分配的。 这些临时变量会在堆栈中进行内存分配 栈上的内存由CLR动态管理用完会被销毁 堆上的内存有GC垃圾回收机制统一进行管理
C#中委托的本质是什么它是如何存储函数的
委托的本质是一个类当我们声明一个委托时相当于声明了一个类。 它会默认继承System.MulticastDelegate类多播委托类 而这个System.MulticastDelegate类 又继承Delegate类委托类 这些父类当中的一些方法就是当我们对委托进行操作时真正会调用的内容
通过这些父类中的方法我们其实可以简单推测出 委托中存储函数的本质是通过一个委托类对象来存储对象的引用或者静态类的类型 然后再记录一个函数的名字。 但是实际上在内部会根据这些信息定位到 1.函数的引用函数的内存地址 2.函数所在对象的引用如果是实例方法
而当我们进行 操作时其实C#内部会调用父类中的Combine结合方法 在底层帮助我们声明一个新的委托对象来记录对应函数的相关信息
C#中事件的本质是什么
我们在使用事件的时候往往是在类中声明成员变量时 当我们声明一个事件时本质就是对委托进行私有访问限制的封装 事件的本质其实就是委托
C#中如何在函数中返回多个返回值至少说出3种方法
数组等容器结构体或类自定义数据结构out参数元组
抽象类中的虚函数和抽象函数是否必须在子类中重写
子类中 虚函数的重写是可选的当需要在子类中修改逻辑时可以选择重写 抽象函数必须重写 当我们使用里式替换原则用父类容器装载子类对象时
我们通过该父类容器调用其中的一个虚函数执行的逻辑是父类中的还是子类中的逻辑呢
Father Eat
Son Father
Son EatFather f new Son();
f.Eat();若子类没有重写虚函数那么执行的逻辑会是父类中的逻辑若子类重写了虚函数那么执行的逻辑会是子类中的逻辑是否执行父类中逻辑主要看子类重写时是否利用了base执行父类逻辑
C#使用var声明临时变量相比用指定变量类型声明临时变量在最终执行时是否会增加性能消耗
不会var在编译时会被推断为正确的类型所以在运行时不会引入额外的性能开销。 相当于在编译阶段var就会被翻译为指定的类型。
C#中属性(Property)和字段(Field)的区别是什么
属性一般可以用来封装字段
属性相对字段来说属性具有封装性允许对字段进行封装提供更多的控制和逻辑。 相比直接访问字段来说属性允许我们在字段访问的过程汇总添加验证、计算等逻辑
属性还可以在其中对set和get设置不同的访问级别使得字段的读取和写入可以收到更精细的控制
Unity Shader中深度测试是在做什么
深度测试用于确定哪些像素应该被绘制到屏幕上并决定它们的可见性。 深度测试的主要目标是解决遮挡关系确保前面的对象覆盖后面的对象从而正确呈现场景
Unity Shader中某片元通过了深度测试但是没有开启深度写入该片元的颜色信息是否写入到颜色缓冲区
会写入颜色缓冲区 因为深度写入和颜色写入是两个独立的操作 只要通过了深度测试不管是否写入深度缓冲区 该片元的颜色信息都会写入到颜色缓冲区中
C#中在什么情况下会选择使用接口什么情况下会选择使用抽象类
接口 1.不同对象的共同行为 2.需要多继承时
抽象类 1.同类对象的共同行为 2.共享成员变量
C#托管内存都有哪些
比如我们平时声明的 unsafe语句块中的指针成员数据库链接对象Socket通讯对象文件流等对象都存在非托管内存需要我们自己释放
C#中new关键字的作用至少说出3种
创建新对象子类函数声明时加上new关键字可以隐藏掉父类方法泛型约束中使用new关键词表示需要无参构造