.NET C# 八股文 代码阅读(一)

.NET C# 八股文 代码阅读(一)

目录

  • .NET C# 八股文 代码阅读(一)
    • 1 两种获10000个数的方式,哪种效率更高?为什么?
    • 2 请说出以下代码AB谁先打印,AB打印的值分别为多少?
    • 3 关于值类型与引用类型、装箱与拆箱,以下代码会输出什么?
    • 4 关于变量作用域,以下代码会输出什么?

1 两种获10000个数的方式,哪种效率更高?为什么?

// 方式一:
List<int> ints = new List<int>();
for (int i = 0; i < 10000; i++)
{ints.Add(i);
}
// 方式二:
float[] floats = new float[10000];
for (int i = 0; i < 10000; i++)
{floats[i] = i;
}

方式二,因为List会不断扩容,扩容时会反复拷贝造成性能损耗

2 请说出以下代码AB谁先打印,AB打印的值分别为多少?

static int GetInt()
{int i = 10;try{return i;}finally{i = 11;Console.WriteLine("第B处 i= " + i);}
}static void Main(string[] args)
{int i = GetInt();Console.WriteLine("第A处 i= " + i);
}
// 输出:
// 第B处 i= 11
// 第A处 i= 10

步骤如下:

  1. 定义局部变量 i 并赋值为 10。
  2. 进入 try 块,准备返回 i 的值,即 10。
  3. 在返回之前,进入 finally 块,将 i 赋值为 11,并打印 "第B处 i= " + i
  4. 返回值已经在 try 块中确定为 10,即使在 finally 块中修改了 i 的值,也不会影响返回值。

finally 块的特点是不论 try 中是正常返回还是异常抛出,它总会在 try 块的返回语句执行前执行,但它对已经确定的返回值不会有影响。因此,GetInt 方法的返回值仍然是 10。

class Test
{public int i = 10;
}static Test GetObj()
{Test t = new Test();try{return t;}finally{t.i = 11;Console.WriteLine("第B处 i= " + t.i);}
}static void Main(string[] args)
{Test t = GetObj();Console.WriteLine("第A处 i= " + t.i);
}
// 输出:
// 第B处 i= 11
// 第A处 i= 11

因为 GetObj 返回的是一个 Test 对象,是引用类型,所以返回的实际上是一个指向 Test 实例的地址;

所以在 try 返回之前,在 finally 中对这个对象进行了修改,而 try 返回之后,Main 中再根据这个地址找到这个 Test 实例,自然也是 finally 修改之后的实例。

这两种情况的不同实际上是对 “赋值” 与 “修改” 的混淆,如果想依旧实现与上面 GetInt 相同的输出,代码应该改成如下:

class Test
{public int i = 10;
}static Test GetObj()
{Test t = new Test();try{return t;}finally{t = new Test();t.i = 11;Console.WriteLine("第B处 i= " + t.i);}
}
static void Main(string[] args)
{Test t = GetObj();Console.WriteLine("第A处 i= " + t.i);
}
// 输出:
// 第B处 i= 11
// 第A处 i= 10

3 关于值类型与引用类型、装箱与拆箱,以下代码会输出什么?

interface IA
{public int id { get; set; }public string name { get; set; }public int[] children { get; set; }
}struct A : IA
{public int id { get; set; }public string name { get; set; }public int[] children { get; set; }
}
class B
{public int id { get; set; }public string name { get; set; }public int[] children { get; set; }
}static void DoA (A a)
{a.id=6;a.name="Bob";a.children[0]=7;
}
static void DoB (B b)
{b.id=6;b.name="Bob";b.children[0]=7;
}static void Main(string[] args)
{var a = new A();a.name = "Alick";a.children = new int[] { 1, 2, 3 };DoA(a);Console.WriteLine($"a  - name: {a.name}, id: {a.id}, children0: {a.children[0]}");IA ia = a;DoIA(ia);Console.WriteLine($"ia - name: {ia.name}, id: {ia.id}, children0: {ia.children[0]}");Console.WriteLine($"a  - name: {a.name}, id: {a.id}, children0: {a.children[0]}");var b = new B();b.name = "Alick";b.children = new int[] { 1, 2, 3 };DoB(b);Console.WriteLine($"b  - name: {b.name}, id: {b.id}, children0: {b.children[0]}");
}
// 输出:
// a  - name: Alick, id: 0, children0: 7
// ia - name: Bob, id: 6, children0: 7
// a  - name: Alick, id: 0, children0: 7
// b  - name: Bob, id: 6, children0: 7

代码分析

  1. 结构体 A 和接口 IA

    • 结构体 A 实现了接口 IA

    • A 声明变量时,是一个值类型,因此在传递给方法时会进行值复制。

    • IA 声明变量时,会进行装箱(boxing),使其变成对象,因此在传递给方法时传递的是引用。

  2. B

    • B 是一个引用类型,因此在传递给方法时会传递引用。
  3. DoA 方法

    • DoA 直接操作结构体 A

    • 由于 A 是值类型,传递给 DoA 时会创建一个副本。

    • 修改副本的 idname 不会影响原来的 A,但修改数组(引用类型)的内容会影响原数组。

    • namestring 类型,也是引用类型,但对 string 类型的修改都会创建新的字符串,所以相当于是赋予了新的引用地址,并没有修改 name 原来的字符串实例。

  4. DoIA 方法

    • DoIA 操作的是接口 IA

    • 虽然传递的是实现了 IA 的结构体 A,但是接口会装箱(boxing)这个结构体,使其变成对象。

    • 装箱后的修改,会影响装箱后的对象,但不会影响原来的结构体实例。

  5. DoB 方法

    • DoB 操作的是类 B

    • 由于 B 是引用类型,传递的是引用,方法中的修改会影响原对象。

4 关于变量作用域,以下代码会输出什么?

Action action = null;
for (int i = 0; i < 10; i++)
{action += () => Console.WriteLine(i);
}
action.Invoke();
// 输出:
// 0
// 0
// 0
// 0
// 0
// 0
// 0
// 0
// 0
// 0

分析代码:

  1. 定义一个空的 Action 委托:

    Action action = null;
    
  2. 使用 for 循环添加匿名方法到 action

    for (int i = 0; i < 10; i++)
    {action += () => Console.WriteLine(i);
    }
    

    在每次循环中,都会将一个新的匿名方法(Lambda 表达式)添加到 action 委托中,这个匿名方法会打印变量 i 的值。

  3. 调用 action 委托:

    action.Invoke();
    

由于 Lambda 表达式捕获的是变量 i 的引用,而不是它的当前值,当 action.Invoke() 被调用时,for 循环已经完成,变量 i 的值已经变成了 10。因此,所有的匿名方法在被执行时,都会打印当前 i 的值,也就是 10。

Action action = null;
for (int i = 0; i < 10; i++)
{int localI = i; // 引入一个新的局部变量action += () => Console.WriteLine(localI);
}
action.Invoke();
// 输出:
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

这样每个匿名方法都会捕获自己的 localI 变量,这个变量在每次循环迭代时都有自己唯一的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/30253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django框架数据库ORM查询操作

Django框架在生成数据库的models模型文件后&#xff0c;旧可以在应用中通过ORM来操作数据库了。今天抽空试了下查询语句。以下是常用的查询语句。 以下查询需要引入django的Sum&#xff0c;Count&#xff0c;Q模块 from django.db.models import Sum,Count,Q 导入生成的mode…

【CPP】直接选择排序、堆排序

目录 1.选择排序1.1简介1.2代码1.3分析 2.堆排序2.1简介2.2代码2.3分析 1.选择排序 1.1简介 思路&#xff1a;遍历一遍&#xff0c;选出最大值和最小值的下标&#xff0c;然后与第一个和最后一个数字交换位置。 1.2代码 1.3分析 最好复杂度&#xff1a;O(N^2) 最差复杂度&am…

振动分析-5-基于CNN的机械故障诊断方法

参考基于CNN的机械故障诊断方法 CNN之图像识别 预训练模型迁移学习&#xff08;Transfer Learning&#xff09; 基于卷积神经网络&#xff08;CNN&#xff09;的深度迁移学习在声发射&#xff08;AE&#xff09;监测螺栓连接状况的应用 参考基于CNN的机械故障诊断所面临的困难和…

win 打包java项目为exe一键部署,包括mysql和redis

需求&#xff1a;打包springboot项目在win系统下执行&#xff0c;并且要一键部署和开机启动 把所需的程序放在同一个文件夹 1.jdk文件夹&#xff1a;自己去下载&#xff0c;jdk8的话拿jre目录好了 2.mysql文件夹&#xff1a;是8.0.36版&#xff0c;270M精简版了 3.redis文件夹…

Python限制输入的数范围:如何避免程序崩溃

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 有时候用户可能会输入一些不符合预期的数值&#xff0c;导致程序崩溃或者产生错误的结果。为了避免这种情况&#xff0c;需要对用户输入的数值进行限制&#xff0c;确保它们在合理的范围内。本文将介绍如何在Python中…

windows桌面运维----第七天

1、运维有哪些方面选择&#xff1a; 1&#xff0c;桌面运维&#xff08;以windows为主&#xff0c;砸个水晶头诸如此类&#xff09; 2&#xff0c;通讯运维&#xff08;电话&#xff09; 3&#xff0c;网络运维&#xff0c;包括&#xff0c;路由&#xff0c;交换&#xff0c;防…

Microsoft AI Day:支持开放合作,普及技术应用,推进行业企业智慧化创新

微软在北京举办以“共创AI创新&#xff0c;智启无限可能”为主题的Microsoft AI Day活动&#xff0c;集中展示了在生成式智能技术加速发展普及的过程中&#xff0c;微软取得的最新技术突破与进展&#xff0c;并同步更新了在Microsoft Build 2024全球开发者大会上发布的一系列Az…

[归档]YOLOv8l在rk3588上量化后的细节

归档备查。这是我第一个成功进行量化的模型&#xff1a; D RKNN: [17:53:26.729] Network Layer Information Table D RKNN: [17:53:26.729] ----------------…

人力资源招聘社会校企类型招聘系统校园招聘小程序

校企社会人力资源招聘小程序&#xff1a;开启高效招聘新时代 &#x1f680;开篇&#xff1a;打破传统&#xff0c;开启招聘新篇章 在快速发展的现代社会&#xff0c;人力资源招聘已经成为企业和学校共同关注的重要议题。为了更高效、便捷地满足双方的招聘需求&#xff0c;一款…

第58章SOCKET:TCP/IP网络基础

58.1 互联网 互联网会将不同的计算机网络连接起来并允许位于网络中的主机相互之间进行通信。互联网的目标是隐藏不同物理网络的细节以便向互联网中的所有主机呈现一个统一的网络架构&#xff0c;TCP/IP已经成了使用最为广泛的协议套件了&#xff0c; 术语Internet被用来指将全球…

【架构师】听说CDN服务把公司账户余额干趴了?我不服

最近老是看到八卦消息 说是某系统用了cdn的加速服务&#xff0c;某些学员一晚上学员几千个小时&#xff08;真好学&#xff09;&#xff0c;结果一晚上就欠费&#xff0c;又是几千大洋没了&#xff0c;吓的我赶紧上链接&#xff08;呸&#xff0c;上控制台看看&#xff09; 关于…

如何通过安全基线做到网络准入

企业在选择网络准入设备时&#xff0c;应当遵循以下步骤和考虑因素&#xff1a; 明确需求 确定组织对网络准入控制的具体需求&#xff0c;包括控制的设备类型、用户数量、网络规模及安全策略等。考虑是否有特定的合规性要求 研究产品功能 研究不同准入设备的功能和特性&…

【网络安全学习】使用Kali做信息收集-01-<域名信息主机信息>

1.收集开源情报 开源情报(Open Source Intelligence&#xff0c;OSINT)是指从各种公开的渠道中寻找和获取有价值的信息 如&#xff1a;互联网、媒体、社交网络、公共数据库等开源情报具有以下特点&#xff1a; - 丰富性&#xff1a;开源情报涵盖了各种类型和领域的信息 - 可…

关于归一化能量与归一化功率(连续与离散+1)

前言&#xff1a; ① 周期信号 与 直流信号 都是功率信号 ②一个信号可以既不是能量信号也不是功率信号&#xff0c;但不可能既是能量信号又是功率信号 归一化能量 对于一个连续时间信号 ( x(t) )&#xff0c;归一化能量 ( E ) 的定义为&#xff1a; E lim ⁡ T → ∞ ∫ −…

macOS聚集搜索功能开启与关闭

按下command空格弹出 使用搜索 关闭搜索 sudo mdutil -a -i off 启用搜索 sudo mdutil -a -i on

深信服科技:2023网络安全深度洞察及2024年趋势研判报告

2023 年&#xff0c;生成式人工智能和各种大模型迅速应用在网络攻击与对抗中&#xff0c;带来了新型攻防场景和安全威胁。漏洞利用链组合攻击实现攻击效果加成&#xff0c;在国家级对抗中频繁使用。勒索团伙广泛利用多个信创系统漏洞&#xff0c;对企业数据安全与财产安全造成了…

【AI】生成式AI服务器最低配置

【背景】 考虑数据安全&#xff0c;又想用AI赋能企业内部的日常工作&#xff0c;答案只有一个&#xff0c;本地部署。 UI采用open-web-ui&#xff0c;模型用Ollama管理&#xff0c;在局域网做成SAAS服务。要组一个服务器&#xff0c;提供部门内部最多30个的API并发。以下为反复…

【Python Cookbook】S02E12 字符串的连接及合并 ‘ ‘.join()

目录 问题解决方案讨论 问题 如果我们想要将很多小的字符串合并成为一个大的字符串&#xff0c;怎么办&#xff1f; 解决方案 如果只是想连接一些字符串&#xff0c;一般使用 操作符即可。 a "is Chicago" b "not Chicago" print(a " " …

[创业之路-117] :制造业企业的必备管理神器-ERP-是什么?企业经营管理与EPR的主要功能模块与全流程

目录 一、什么是EPR 1.1 跨企业的供应链思想 1.2 EPR的概念&#xff1a;企业资源管理计划 1.2.1 助力企业管理各种资源&#xff1a;人、财、物&#xff08;机、料、法、环&#xff09; 1.2.2 助力企业有效管理 1.2.3 效率的提升 1.4 应用领域 二、ERP的功能模块 三、E…

【docker】docker启动neo4j,并配置内存

注意下&#xff1a;--volume宿主机目录:/data 和 --publish宿主机port:7474 --publish宿主机port:7687 docker run -d \ --publish9801:7474 --publish9802:7687 \ --env NEO4J_AUTHneo4j/passwd \ --volume/opt/docker/data/vol-data/neo4j4.2:/data \ --restart always \ --…