2023-12-12面试C#/.Net遇到的题目总结

1. Task.ConfigureAwait(false)

        该函数含义:是否返回原来捕捉到的上下文

2. 聚集索引和非聚集索引区别

        没有索引查询会遍历所有记录,聚集索引的顺序与物理表的顺序是一致的,一个表只能有一种排序所以只能有一种聚集索引;

        聚集索引会影响表记录的排序,非聚集索引不会影响表记录排序。所以一个表可以有多个非聚集索引。

        聚集索引比非聚集索引快;非聚集索引需要额外存储数据行地址,所以占用更多的存储空间。

3. MVC Filter的执行顺序

        Authorization filters, Action filters, Response filters, Exception filters

4.gRPC服务和HTTP API区别

        比较 gRPC 服务和 HTTP API | Microsoft Learn

功能gRPC具有 JSON 的 HTTP API
协定必需 (.proto)可选 (OpenAPI)
协议HTTP/2HTTP
PayloadProtobuf(小型,二进制)JSON(大型,人工可读取)
规定性严格规范宽松。 任何 HTTP 均有效。
流式处理客户端、服务器,双向客户端、服务器
浏览器支持无(需要 grpc-web)
安全性传输 (TLS)传输 (TLS)
客户端代码生成OpenAPI + 第三方工具

        gRPC缺点: 非人工可读取;浏览器支持受限;

5.链表从第N项开始倒叙排序

        FYI:reverse - Reversing single linked list in C# - Stack Overflow

using System;

namespace TestOrderLink
{
    class Program
    {
        static void Main(string[] args)
        {            
            var root = new Node { Order = 1 };
            root.Next = new Node { Order = 2 };
            root.Next.Next = new Node { Order = 3 };
            root.Next.Next.Next = new Node { Order = 4 };
            root.Next.Next.Next.Next = new Node { Order = 5 };
            root.Next.Next.Next.Next.Next = new Node { Order = 6 };
            root.Next.Next.Next.Next.Next.Next = new Node { Order = 7 };
            root.Next.Next.Next.Next.Next.Next.Next = new Node { Order = 8 };
            root.Next.Next.Next.Next.Next.Next.Next.Next = new Node { Order = 9 };
            root.Next.Next.Next.Next.Next.Next.Next.Next.Next = new Node { Order = 10 };
            root.Next.Next.Next.Next.Next.Next.Next.Next.Next.Next = new Node { Order = 11 };
            root.Next.Next.Next.Next.Next.Next.Next.Next.Next.Next.Next = new Node { Order = 12 };

            ReverseFromTheN(ref root, 0);
            ConsoleOutNodeOrder(root);

            ReverseFromTheN(ref root, 12);
            ConsoleOutNodeOrder(root);

            ReverseFromTheN(ref root, 3);
            ConsoleOutNodeOrder(root);

            Console.ReadLine();
        }

        public static void ConsoleOutNodeOrder(Node root)
        {
            Console.WriteLine(root.Order);
            if (root.Next != null)
                ConsoleOutNodeOrder(root.Next);
        }

        public static void ReverseFromTheN(ref Node root, int n)
        {
            Node node = root;
            if (n <= 0)
            {               
                ReverseNoTemp(ref root, null);
                return;
            }
            for (int i = 0; i < n - 1; i++)
            {
                if (root.Next == null)
                    return;
                node = node.Next;
            }
            var first = node.Next;            
            ReverseNoTemp(ref first, node);
        }

        public static void ReverseNoTemp(ref Node root, Node frontNode)
        {
            var p = root;
            Node n = null;
            while (p != null)
            {
                var tmp = p.Next;
                p.Next = n;
                n = p;
                p = tmp;
            }
            if (frontNode != null)
                frontNode.Next = n;
            else
                root = n;
        }
    }

    public class Node
    {
        public int Order { get; set; }
        public Node Next { get; set; }

    }
}

6. 泛型的作用 FYI:c#泛型的作用有哪些 - 问答 - 亿速云

  • 提高代码可重用性:泛型允许开发人员编写通用的代码,可以在多种数据类型上进行操作,从而避免了重复编写相似的代码。
  • 提高代码的性能:使用泛型可以避免装箱和拆箱操作,提高了代码的执行效率。
  • 提高代码的类型安全性:使用泛型可以在编译时捕获类型错误,减少了运行时的错误。
  • 提高灵活性和扩展性:泛型可以通过参数化类型来实现不同类型的算法和数据结构,提供了更多的灵活性和扩展性。
  • 提供更好的代码可读性和可维护性:使用泛型可以使代码更加简洁、清晰。

7. C#Static关键字的作用 FYI:【2023】 50道C#基础笔试题 附详解答案! - 知乎

        静态字段在内存中只有一个拷贝,非静态字段则是在每个实例对象中有一个拷贝。方法无论是否静态在内存中只有一份拷贝,区别是通过类型来访问还是通过实例来访问。

8. C#Dispose和Finalize(在C#是析构函数)区别 FYI: C# Interview Questions (2023)

        Dispose用来释放unmanaged资源,这些资源不被.Net运行时管控,比如数据库和Handles。Dispose被客户端代码明确的调用当资源不被使用时。该方法可以被隐含的调用,当该对象超出使用范围时。

        Finalize是被自动调用的,在垃圾收集器(管理.Net对象的内存)回收资源之前。

        如果资源没有被Dispose方法明确调用过,垃圾收集器才会执行调用Finalize方法释放资源。

9. What’s the difference between the Array.CopyTo() and Array.Clone()?

The Array.Clone() method creates a shallow copy of an array. A shallow copy of Array copies only the elements of the Array, whether reference types or value types, but it does not copy the objects that the references refer to. The references in the new Array point to the same objects as those in the original Array.

The CopyTo() static method of the Array class copies a section of an array to another array. The CopyTo method copies all the elements of an array to another one-dimension array. For example, the code listed in Listing nine copies the contents of an integer array to various object types. 

10. FYI:C# HashTable和Dictionary的区别 - 简书

11. throw和throw ex区别:FYI “throw” 和“throw ex”之间有区别吗?_知更鸟的码-Byzer 白泽

        throw ex会将到现在为止的所有异常信息清空,即重置了堆栈跟踪,很难找到原始发生异常的行,通俗点说异常只能定位到该行。

        throw 可以追溯到原始异常点。

        推荐使用 throw new Exception("", ex),重新包装异常,这样会保留原始异常点。

12. 使用接口的意义:FYI https://www.cnblogs.com/mkmkbj/p/16880488.html

        使用接口的意义在于它强大的可扩展性,很灵活。非常符合面向对象的概念多态。

        什么时候用,传参的时候用。

        以下是使用接口的几种常见情况:

        实现多态性:接口允许类实现多个接口,从而实现多态性。通过实现接口,一个类可以具备多个不同的行为,而不仅仅局限于单一的继承。

        将行为从实现中分离:接口可以将类的行为与具体的实现分离。通过定义接口,可以将类 的行为抽象出来,并在不同的类中进行实现。这样可以提高代码的可维护性和可扩展性。

        定义可插拔组件:接口可以用于定义可插拔的组件。通过定义接口,可以将组件的功能与具体实现分离,从而使组件可以在不同的环境中使用。

        总而言之,使用接口可以提供更高级别的抽象和灵活性,使代码更易于维护和扩展。特别是在需要多态性、定义合同或分离行为和实现的情况下,使用接口是一个很好的选择。

        

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值