C#面试问题61-80

66. What is reflection?

反射是一种机制,它使我们能够编写可以检查应用程序中所 用类型的代码。例如,调用名称与给定字符串相等的方法,或者列出属于给定 对象的所有字段及其值。

在 Convert 方法中,我们根本不知道处理的是什么类型。我们无法将 "obj"强制转换为任何具体的类型,因为类型可能会有所不同。而且,要实现我们 想要的功能,我们不仅需要属性的值(如果我们有比 System.Object 更具体的类型, 就可以访问这些值),还需要属性的名称,但在运行时这是无法获取的。

What are the downsides of using reflection? 使用反射会对性能产生相对较大的影响。此外,它会使代码难以理解和 维护。它还可能诱使一些程序员在运行时"破解"某些代码,例如访问私有 字段,这可能会导致意外的结果和难以理解的错误

68. What is serialization?

序列化是将对象转换为可存储在内存中或通过网络传输的格式的过程。例 如,对象可以被转换为包含 JSON 或 XML 的文本文件,或者转换为二进制 文件。

What are the uses of serialization? 它可用于通过网络发送对象,或者将对象存储在文件中以便日后重建,甚至 可以将对象存储在数据库中------例如,每当用户对某个对象进行更改时,都 保存该对象的一个"快照",这样我们就能记录更改的历史记录

Serializable 属性的作 用是什么?

cs 复制代码
[Serializable]
public record Person

此属性表明类的实例可以使用 BinaryFormatter 或 SoapFormatter 进行序列化。对 于 XML 或 JSON 序列化则无需此属性。BinaryFormatter 将对象序列化为二进制 格式(简单来说,就是一串 0 和 1),而 SoapFormatter 则序列化为 SOAP 格式, 这种格式与 XML 有些类似。

What does the Serializable attribute do? 此属性表明类的实例可以使用 BinaryFormatter 或 SoapFormatter 进行序列化。对于 XML 或 JSON 序列化,此属性并非必需

What is deserialization? 反序列化是序列化的相反过程:它是利用文件的内容重新创建 对象

69. What is pattern matching?

How can we check if an object is of a given type, and cast to it this type in the same statement? 我们可以使用模式匹配来实现这一点。例如,我们可以这样写:"如果 obj 是字符串 text"。这样,只有当 obj 是字符串类型时,我们才会将其转换为名 为 text 的字符串变量

79. What is caching?

如果该值尚未缓存,我们需要以某种方式获取它。 对于 PeopleController 来说,它会从存储库中读取。但我们不能这样做: 缓存类是泛型的,它不仅必须适用于从特定存储库读取的人员对象,还必 须适用于其他任何对象。换句话说,我们还必须提供一种通用机制来读取 将要存储在缓存中的值。最简单的解决方案是将一个 Func 传递给 Get 方法。 此 Func 将返回一个类型为 TValue 的对象。由 Get 方法的调用方提供具体 的读取方法。在我们的例子中,PeopleController将使用缓存,并向 Get 方 法传递一个从数据库读取 Person 对象的函数

cs 复制代码
using Microsoft.Extensions.Caching.Memory;

var peopleController = new PeopleController(
    new PeopleRepositoryMock());

var john = peopleController.GetByName("John", "Smith");
john = peopleController.GetByName("John", "Smith");
john = peopleController.GetByName("John", "Smith");

Console.ReadKey();

//还添加了非空约束。字典的键绝不能为 null。
class Cache<TKey, TValue> where TKey: notnull
{
    private readonly Dictionary<TKey, TValue> _cachedData = new();

    //首先,它应该将一个键作为参数:
    public TValue Get(TKey key, Func<TValue> getValueForTheFirstTime)
    {
        if (!_cachedData.ContainsKey(key))
        {
            _cachedData[key] = getValueForTheFirstTime();
        }

        //如果字典中已存储给定键对应的值,则应直接返回该值:
        return _cachedData[key];
    }
} 

class PeopleController
{
    //我们希望可以通过提供名字和姓氏来检索它们。所以也许最好的选择是一个字典,
    //其中由两个字符串组成的元组(分别代表名字和姓氏)作为键,Person 对象作为值。
    private readonly Cache<(string, string), Person?> _cache = new();
    private readonly IRepository<Person> _peopleRepository;

    public PeopleController(IRepository<Person> peopleRepository)
    {
        _peopleRepository = peopleRepository;
    }

    public Person? GetByName(string firstName, string lastName)
    {
        //Get 方法的第一个参数是键,在我们的例子中是一个包含名和姓的 ValueTuple。
        //第二个参数是一个函数,用于从存储库中检索具有这些姓名的 Person 对象。
        return _cache.Get(
            (firstName, lastName),
            () => _peopleRepository
                .GetByName(firstName, lastName)
                .FirstOrDefault());
    }

    private readonly MemoryCache _memoryCache =
        new MemoryCache(new MemoryCacheOptions());

    //alternatively we can use the Microsoft's MemotyCache
    public Person? GetByNameMemoryCache(string firstName, string lastName)
    {
        return _memoryCache.GetOrCreate(
            (firstName, lastName),
            cacheEntry => _peopleRepository
                .GetByName(firstName, lastName)
                .FirstOrDefault());
    }
}

internal interface IRepository<T>
{
    IEnumerable<Person> GetByName(string firstName, string lastName);
}

record Person(string FirstName, string LastName);

class PeopleRepositoryMock : IRepository<Person>
{
    public IEnumerable<Person> GetByName(string firstName, string lastName)
    {
        if (firstName == "John" && lastName == "Smith")
        {
            return new[] { new Person("John", "Smith") };
        }
        throw new NotImplementedException();
    }
}

What are the benefits of using caching? 如果反复通过相同的键检索数据,缓存可以提升性能。它不仅有助于从外部 数据源检索数据,甚至对于本地计算的数据也有帮助,尤其是当计算本身比 较繁重(例如某些复杂的数学运算)时

What are the downsides of using caching? 缓存会占用应用程序的内存。随着时间的推移,缓存可能会不断增大,因此 应当引入某种清理机制以避免出现内存溢出异常。这类机制通常基于数据的 过期时间。此外,缓存中的数据可能会过时,即在数据源中已发生变化,但缓存 中仍保留旧版本并在应用程序中使用。正因为如此,缓存对于那些不常变化 的数据最为有用

相关推荐
§ꦿCFོ༉7 小时前
嵌入式八股文—C语言入门学习(四)
c语言·开发语言·学习
投图匠7 小时前
十种不同风格的 CTP接口 框架
开发语言·python
爱笑的k1110 小时前
nano-vllm 源码剖析:千行 Python 手写离线推理引擎的调度、显存与并行时序
开发语言·python·vllm
用户37215742613510 小时前
C# 提取 PDF 附件:包括文档附件和页面注释附件
c#
寂寞的船11 小时前
【Unity Bug挑战】第12期 Awaitable 二次 await 死锁之谜 —— 为什么同一个异步操作等两次就卡死?
unity·c#·游戏引擎·bug
X1A0RAN11 小时前
PPT 图片批量处理教程:导出全部幻灯片 · 提取全部素材
开发语言·javascript·powerpoint
熊猫钓鱼>_>13 小时前
普通用户视角的端侧智能体验手记【鸿蒙心迹】
开发语言·人工智能·华为·智能手机·性能优化·ai编程·harmonyos
瑞雪兆丰年兮13 小时前
JavaWeb-day13-SpringBootWeb事务管理&AOP
java·开发语言·springboot·javaweb·事务·web·aop
布莱克60514 小时前
Swift 常量详解:从 let 到编译期优化
服务器·开发语言·ssh·swift·常量·let
布莱克60515 小时前
Swift 可选类型(Optionals)详解:从原理到实战
开发语言·安全·ssh·swift·optional·可选类型