【加入默语老师的私域】C#面试题
什么是依赖注入,如何实现?
依赖注入是一种设计模式。我们不是直接在另一个类(依赖类)中创建一个类的对象,而是将对象作为参数传递给依赖类的构造函数。它有助于编写松散耦合的代码,并有助于使代码更加模块化和易于测试。实现依赖注入的三种方式:
构造函数注入:这是最常用的注入类型。在构造函数注入中,我们可以将依赖项传递给构造函数。我们必须确保这里没有默认构造函数,唯一的应该是参数化构造函数。
属性注入:在某些情况下,我们需要一个类的默认构造函数,那么在这种情况下,我们可以使用属性注入。
方法注入:在方法注入中,我们只需要在方法中传递依赖即可。当整个类不需要那个依赖时,就不需要实现构造函数注入。当我们对多个对象有依赖关系时,我们不会在构造函数中传递该依赖关系,而是在需要它的函数本身中传递该依赖关系。
为什么要使用线程池?直接new个线程不是很舒服?
如果我们在方法中直接new一个线程来处理,当这个方法被调用频繁时就会创建很多线程,不仅会消耗系统资源,还会降低系统的稳定性,一不小心把系统搞崩了,就可以直接去财务那结帐了。
如果我们合理的使用线程池,则可以避免把系统搞崩的窘境。总得来说,使用线程池可以带来以下几个好处:
降低资源消耗。通过重复利用已创建的线程,降低线程创建和销毁造成的消耗。
提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
增加线程的可管理型。线程是稀缺资源,使用线程池可以进行统一分配,调优和监控。
线程池的核心属性有哪些?
threadFactory(线程工厂):用于创建工作线程的工厂。
corePoolSize(核心线程数):当线程池运行的线程少于 corePoolSize 时,将创建一个新线程来处理请求,即使其他工作线程处于空闲状态。
workQueue(队列):用于保留任务并移交给工作线程的阻塞队列。
maximumPoolSize(最大线程数):线程池允许开启的最大线程数。
handler(拒绝策略):往线程池添加任务时,将在下面两种情况触发拒绝策略:
1)线程池运行状态不是 RUNNING;
2)线程池已经达到最大线程数,并且阻塞队列已满时。
keepAliveTime(保持存活时间):如果线程池当前线程数超过 corePoolSize,则多余的线程空闲时间超过 keepAliveTime 时会被终止。
锁有哪几种?
的分类
1.公平锁/非公平锁
2.可重入锁
3.独享锁/共享锁
4.互斥锁/读写锁
5.乐观锁/悲观锁
6.分段锁
7.偏向锁/轻量级锁/重量级锁8.自旋锁
乐观锁
所谓的乐观,实际上是相对于悲观锁来说,我们先看一下百度百科中的解释。
乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库 性能的大量开销, 特别是对长事务而言,这样的开销往往无法承受。相对悲观锁而言,乐观锁更倾向于开发运用。
悲观锁
惯例,先来看看百度百科中的解释
悲观锁,正如其名,具有强烈的独占和排他特性。
它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度, 因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性, 否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
因为悲观锁总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。
-
lock关键字:这是C#中最简单和最常用的锁机制,用于在代码块中获取对象的互斥锁,确保同一时间只有一个线程能够执行该代码块。lock关键字实际上是一个语法糖,它将Monitor对象进行封装,给对象加上一个互斥锁。lock锁定的对象应该是静态的引用类型(字符串除外)。
-
Monitor类:Monitor类提供了一种更灵活的同步机制,通过Monitor.Enter和Monitor.Exit方法来获取和释放对象的锁。Monitor类还提供了等待和通知的功能,可以实现更复杂的线程同步方案。
-
Mutex类:Mutex是一种操作系统级别的内核对象,用于进程间的同步。在C#中,Mutex类封装了操作系统提供的互斥体,可以用于实现跨进程的线程同步。使用Mutex时,需要成对使用WaitOne和ReleaseMutex方法,以避免死锁。
-
Semaphore类:Semaphore也是一种操作系统级别的同步原语,用于控制同时访问共享资源的线程数量。Semaphore类允许指定一个计数器,表示可访问共享资源的线程数量,适用于一些限流的场景。
-
AutoResetEvent和ManualResetEvent类:这两种类是基于事件的同步原语,用于线程间的信号通知和同步。它们允许一个或多个线程等待另一个线程发送信号,然后继续执行。
-
SpinLock:这是一种内核模式锁,自旋锁是“原地等待”的方式解决资源冲突的,即线程会不停地检查锁是否可用(忙等待),直到获取到锁为止。自旋锁适用于锁定时间极短的场景,可以避免线程的上下文切换,但长时间持有会导致CPU资源的浪费。
选择合适的锁类型的重要性:
选择合适的锁类型对于避免性能下降和死锁非常重要。例如,自旋锁适用于锁定时间极短的场景,而互斥锁和监视锁则适用于需要长时间保护的代码段。此外,Mutex和Semaphore适用于进程间或资源数量控制的场景
在C#中,使用多线程可以通过System.Threading命名空间下的Thread类来实现。以下是一个简单的多线程示例,它创建了两个线程,每个线程打印出自己的名字和当前线程ID:
using System;
using System.Threading;
class Program
{
static void Main()
{
Thread thread1 = new Thread(ThreadProc);
thread1.Name = "Thread1";
Thread thread2 = new Thread(ThreadProc);
thread2.Name = "Thread2";
thread1.Start();
thread2.Start();
Console.WriteLine("Main thread ends.");
}
static void ThreadProc()
{
Console.WriteLine($"{Thread.CurrentThread.Name} is running, thread ID: {Thread.CurrentThread.ManagedThreadId}");
}
}
在这个例子中,ThreadProc是一个线程执行的方法,每次调用都会打印出线程的名字和当前线程ID。thread1和thread2是两个通过调用ThreadProc方法创建的线程。每个线程都有自己的名字和ID,这些信息通过Thread.CurrentThread.Name和Thread.CurrentThread.ManagedThreadId属性获取。
请注意,在实际应用中,应该避免在多个线程间共享资源,除非有适当的同步机制,否则可能会导致竞态条件和不一致的状态。
在C#中,设置线程的优先级可以使用Thread类的Priority属性。ThreadPriority枚举定义了五个级别:
-
Lowest
-
BelowNormal
-
Normal
-
AboveNormal
-
Highest
以下是设置线程优先级的示例代码:
using System;
using System.Threading;
class Program
{
static void Main()
{
Thread thread = new Thread(Run);
// 设置线程优先级为最低
thread.Priority = ThreadPriority.Lowest;
// 启动线程
thread.Start();
}
static void Run()
{
// 线程体
// 此处为了演示,简单地打印线程优先级
Console.WriteLine("线程运行,优先级: " + Thread.CurrentThread.Priority);
}
}
请注意,设置线程的优先级并不保证操作系统会按照指定的优先级来调度线程。操作系统根据线程的优先级来决定何时以及如何分配CPU时间,但最终的调度策略还受到很多其他因素的影响,例如当前系统负载、其他运行线程的优先级等。此外,线程的优先级也可能被提升以保证系统服务和应用程序的稳定性。
在C#中,可以使用System.Threading命名空间下的Thread类来创建和控制线程,使用System.Diagnostics命名空间下的Process类来创建和控制进程。
创建并启动一个新线程的示例代码:
using System.Threading;
public class ThreadExample
{
public static void Main()
{
ThreadStart ts = new ThreadStart(ThreadMethod);
Thread t = new Thread(ts);
t.Start();
}
private static void ThreadMethod()
{
// 线程执行的代码
Console.WriteLine("线程运行中...");
}
}
创建并启动一个新进程的示例代码:
using System.Diagnostics;
public class ProcessExample
{
public static void Main()
{
Process.Start("notepad.exe");
}
}
上述代码分别展示了如何在C#中创建并启动一个线程和进程。线程是操作系统能够进行运算调度的最小单位,而进程是运行中的程序,它可以包含一个或多个线程。在C#中,通过使用Thread类,可以创建和控制用户模式的执行线程;通过使用Process类,可以创建和控制一个或多个进程。
相关文章:
【加入默语老师的私域】C#面试题
什么是依赖注入,如何实现? 依赖注入是一种设计模式。我们不是直接在另一个类(依赖类)中创建一个类的对象,而是将对象作为参数传递给依赖类的构造函数。它有助于编写松散耦合的代码,并有助于使代码更加模块…...
称重传感器指示器行业全面且深入的分析
称重传感器指示器是一种用于显示和解释称重传感器输出信号的设备,用于测量力、重量或压力。称重传感器是将物理力(如重量)转换为电信号的传感器,称重传感器指示器将该电信号转换为可读格式,通常以磅、公斤或牛顿等单位…...
NAT网络地址转换——Easy IP
NAT网络地址转换 Tip: EasylP没有地址池的概念,使用接口地址作为NAT转换的公有地址。EasylP适用于不具备固定公网IP地址的场景:如通过DHCP, PPPOE拨号获取地址的私有网络出口,可以直接使用获取到的动态地址进行转换。 本次实验模拟nat协议配置 AR1配置如下&…...
【Visual Studio系列教程】如何在 VS 上编程?
上一篇博客中,我们介绍了《什么是 Visual Studio?》。本文,我们来看第2篇《如何在 VS 上编程?》。阅读本文大约10 分钟。我们会向文件中添加代码,了解 Visual Studio 编写、导航和了解代码的简便方法。 本文假定&…...
Mybatis-Plus 多租户插件属性自动赋值
文章目录 1、Mybatis-Plus 多租户插件1.1、属性介绍1.2、使用多租户插件mavenymlThreadLocalUtil实现 定义,注入租户处理器插件测试domianservice & ServiceImplmapper 测试mapper.xml 方式 1.3、不使用多租户插件 2、实体对象的属性自动赋值使用1. 定义实体类2. 实现 Meta…...
AWTK-WIDGET-WEB-VIEW 实现笔记 (4) - Ubuntu
Ubuntu 上实现 AWTK-WIDGET-WEB-VIEW 开始以为很简单,后来发现是最麻烦的。因为 Ubuntu 上的 webview 库是 基于 GTK 的,而 AWTK 是基于 X11 的,两者的窗口系统不同,所以期间踩了几个大坑。 1. 编译 AWTK 在使用 Linux 的输入法时…...
Python入门(7)--高级函数特性详解
Python高级函数特性详解 🚀 目录 匿名函数(Lambda)装饰器的使用生成器与迭代器递归函数应用实战案例:文件批处理工具 1. 匿名函数(Lambda)深入解析 🎯 1.1 Lambda函数基础与进阶 1.1.1 基本…...
【数据库原理】理解数据库,基础知识
第一代:网状数据库;第二代:关系数据库;第三代:新一代数据库系统BigData 一、理解数据库 什么是数据:信息,对事物的存在方方式、运动状态及特征的描述。数据,记录信息的识别方式有数…...
VConsole——(H5调试工具)前端开发使用于手机端查看控制台和请求发送
因为开发钉钉H5微应用在手机上一直查看不到日志等,出现安卓和苹果上传图片一边是成功的,一边是失败的,所以找了这个,之前在开发微信小程序进行调试的时候能看到,之前没想到过,这次被人提点发现可以单独使用…...
论文分享 | FuzzLLM:一种用于发现大语言模型中越狱漏洞的通用模糊测试框架
大语言模型是当前人工智能领域的前沿研究方向,在安全性方面大语言模型存在一些挑战和问题。分享一篇发表于2024年ICASSP会议的论文FuzzLLM,它设计了一种模糊测试框架,利用模型的能力去测试模型对越狱攻击的防护水平。 论文摘要 大语言模型中…...
vmWare虚拟环境centos7安装Hadoop 伪分布式实践
背景:近期在研发大数据中台,需要研究Hadoop hive 的各种特性,需要搭建一个Hadoop的虚拟环境,本来想着使用dock ,但突然发现docker 公共仓库的镜像 被XX 了,无奈重新使用vm 搭建虚拟机。 大概经历了6个小时完…...
【C++入门(一)】半小时入门C++开发(深入理解new+List+范围for+可变参数)
目录 一.深入理解new 使用格式 二.List列表 定义一个列表 迭代器 添加元素 删除元素 排序 反转序列 三.范围for 四.可变参数 std::initializer_list 可变参数模板(variadic template) 一.深入理解new 类似于C语言中的malloc、calloc和reallo…...
Vue 3与TypeScript集成指南:构建类型安全的前端应用
在Vue 3中使用TypeScript,可以让你的组件更加健壮和易于维护。以下是使用TypeScript与Vue 3结合的详细步骤和知识点: 1. 环境搭建 首先,确保你安装了Node.js(推荐使用最新的LTS版本)和npm或Yarn。然后,安…...
MATLAB和Python发射光谱
在MATLAB和Python中,可以使用不同的库来生成发射光谱。以下是两种语言的简单示例: MATLAB: % 定义波长(nm)和强度(a.u.) wavelengths linspace(300, 1000, 1000); intensity sin(wavelengths / 500);…...
IEEE(常用)参考文献引用格式详解 | LaTeX参考文献规范(IEEE Trans、Conf、Arxiv)| 期刊会议名缩写查询
期刊 ** 期刊:已正式出版(有期卷号) ** 期刊:录用后在线访问即Early access(无期卷号)会议Arxiv论文 期刊 期刊:已正式出版(有期卷号) article{gu2024ai, title{{AI}-Enhanced Cloud-Edge-Terminal Collaborative Ne…...
第二十周:机器学习
目录 摘要 ABSTRACT 一、吴恩达机器学习exp2——逻辑回归 1、logistic函数 2、数据预处理 3、损失函数 4、梯度下降 5、设定评价指标 6、决策边界 7、正则化 二、动手深度学习pytorch——数据预处理 1、数据集读取 2、缺失值处理 3、转换为张量格式 总结 摘要…...
Elasticsearch面试内容整理-Elasticsearch 基础概念
Elasticsearch 是一个基于 Apache Lucene 的开源分布式搜索和分析引擎,提供强大的全文本搜索、实时数据分析、分布式存储等功能。以下是 Elasticsearch 的一些基础概念: 什么是 Elasticsearch? ● Elasticsearch 是一个用于全文搜索和实时分析的分布式搜索引擎。 ● 开源和可…...
机器学习算法模型系列——Adam算法
Adam是一种自适应学习率的优化算法,结合了动量和自适应学习率的特性。 主要思想是根据参数的梯度来动态调整每个参数的学习率。 核心原理包括: 动量(Momentum):Adam算法引入了动量项,以平滑梯度更新的方向…...
Qt按钮类-->day09
按钮基类 QAbstractButton 标题与图标 // 参数text的内容显示到按钮上 void QAbstractButton::setText(const QString &text); // 得到按钮上显示的文本内容, 函数的返回就是 QString QAbstractButton::text() const;// 得到按钮设置的图标 QIcon icon() const; // 给按钮…...
基于xr-frame实现微信小程序的手部、手势识别3D模型叠加和石头剪刀布游戏功能
前言 xr-frame是一套小程序官方提供的XR/3D应用解决方案,基于混合方案实现,性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。xr-frame在基础库v2.32.0开始基本稳定,发布为正式版,但仍有一些功能还在开发&#…...
如何用KeyStore Explorer轻松管理Java密钥库?5分钟快速上手指南
如何用KeyStore Explorer轻松管理Java密钥库?5分钟快速上手指南 【免费下载链接】keystore-explorer KeyStore Explorer is a free GUI replacement for the Java command-line utilities keytool and jarsigner. 项目地址: https://gitcode.com/gh_mirrors/ke/ke…...
3步完成M9A小助手配置:重返未来1999终极自动化指南
3步完成M9A小助手配置:重返未来1999终极自动化指南 【免费下载链接】M9A 重返未来:1999 小助手 | Assistant For Reverse: 1999 项目地址: https://gitcode.com/gh_mirrors/m9/M9A M9A是专为《重返未来:1999》玩家设计的智能自动化小助…...
WarcraftHelper:魔兽争霸3引擎现代化改造与帧率优化技术方案
WarcraftHelper:魔兽争霸3引擎现代化改造与帧率优化技术方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 魔兽争霸3作为一款经典的即时…...
为AI Agent注入OpenCLI肌肉记忆:从命令行自动化到智能体工程实践
1. 项目概述:为AI Agent注入OpenCLI的“肌肉记忆”如果你正在使用像Codex、Claude Code或OpenClaw这样的AI编程助手,并且经常需要它们帮你处理一些“接地气”的任务——比如抓取B站热门视频列表、搜索知乎上的技术文章、或者直接操作你本地的Cursor编辑器…...
抖音无水印下载工具:从零到精通的完整实战指南
抖音无水印下载工具:从零到精通的完整实战指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音…...
GetQzonehistory:一站式自动化QQ空间历史数据备份解决方案
GetQzonehistory:一站式自动化QQ空间历史数据备份解决方案 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 在数字记忆日益重要的今天,如何安全高效地备份个人社交…...
光伏运维工具推荐
1.绿虫:聚焦光伏运维数字化领域,核心产品为光伏运维软件及全流程管理系统,可实现远程智能巡检、智能告警、数据分析优化等功能,能提升运维效率、减少故障停机时间,适配多站点集中管理需求,已服务数百家光伏…...
3步掌握GetQzonehistory:新手也能轻松备份QQ空间历史记录的完整指南
3步掌握GetQzonehistory:新手也能轻松备份QQ空间历史记录的完整指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾经想找回多年前在QQ空间发布的某条说说…...
从手动保存到一键下载:抖音无水印视频获取的革命性工具
从手动保存到一键下载:抖音无水印视频获取的革命性工具 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback supp…...
新手入门 Taotoken 从注册到获取第一个 API Key 全指南
新手入门 Taotoken 从注册到获取第一个 API Key 全指南 1. 注册 Taotoken 账号 访问 Taotoken 官方网站完成账号注册流程。在浏览器地址栏输入 https://taotoken.net 进入首页,点击右上角的「注册」按钮。填写邮箱地址、设置密码并完成手机号验证后,系…...
