【加入默语老师的私域】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开始基本稳定,发布为正式版,但仍有一些功能还在开发&#…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...