Dotnet Core 备忘录
Meeting
1.C#.NET中的CTS、CLS和CLR
CTS通用类型系统(Common Type System)
cts定义了一套通用的对于编译时的数据类型系统,比如vb 和C# 同时定义一个int类型 在经过cts编译后统一会变成int32CLS通用语言规范 (common language specification)
主要就是将vb,c#语言编译成IL语言或者exe dllCLR(common language runtime)
用于驱动程序运行 将IL语言编译成机器指令 还包括GC垃圾回收机制
了解更多
2.针对语法的题目
2.1 面向对象
面向对象(Object-Oriented,简称 OO)是一种编程范式,它通过将数据和与数据相关的操作封装在对象中,从而模拟真实世界的实体和其相互之间的关系。面向对象编程的主要思想是将问题划分为一系列相互关联的对象,每个对象负责特定的功能或行为。
面向对象编程的主要特征包括:
三大特性
- 1.封装(Encapsulation):将数据和操作数据的方法封装在一个单元(即对象)中,对象对外部隐藏其内部的实现细节,只提供必要的接口。
- 2.继承(Inheritance):通过继承,一个对象(子类)可以继承另一个对象(父类)的属性和方法。这有助于代码重用和构建层次结构。
- 3.多态(Polymorphism):允许对象在不同的上下文中表现出不同的行为。多态性有两种主要形式:编译时多态性(静态多态性)和运行时多态性(动态多态性)。
六大原则
- 单一职责 一个方法的功能尽量单一 降低耦合。
- 开放封闭原则 就是设计上对于拓展要开放 对于修改要封闭。
- 里氏代换原则 子类必须能够替换基类,否则就不应该设计成为其子类 就是说子类可以去扩展基类的功能,但不能改变基类原有的功能。子类可以实现基类的抽象方法,但不能覆盖基类的非抽象方法,子类中可以增加自己特有的方法。
- 依赖倒转原则 核心就是面向接口编程 设计要依赖于抽象而不是具体 思考的时候要抽象思考而不是划分得很具体。
- 接口隔离原则 使用多个隔离的接口比使用单个接口要好。 接口应该保持最小单元 定义的时候要遵循单一职责原则。
- 迪米特原则 一个类对其他类知道的越少越好 就是说一个对象应当对其他对象有尽可能少的了解。
2.2 引用类型和值类型的区别
| 引用类型 | 值类型 | |
|---|---|---|
| 内存分配 | 引用类型的对象是存储来堆的,但是会在栈中存储一个指针指向实例的堆地址 | 值类型的对象的实例直接存储在栈内存 |
| 传递方式 | 传递的是引用的地址 | 传递的是变量本身 |
| 默认值 | null | 每个不同的数据类型默认值都不同 好比int是0 |
| 生命周期 | 引用类型的生命周期不是在声明的时候决定的,他是通过GC回收的,当没有任何引用指向的时候就会被回收 | 值类型的生命周期是按照它的作用域决定的,当变量超出作用域就会被销毁 |
| 继承 | 引用类型可以支持多继承和多态 | 不支持 |
| 常见类型 | 类,接口,数组,委托等 | int,long,float,struck,在想值类型可以为null是可以加? int? a = null |
2.3 什么是命名空间?它的作用是什么?
命名空间是用于组织和管理代码的一种机制,防止命名冲突。它将类,接口,结构和其他类型组织在一起。
2.4 C#中的构造函数和析构函数分别是什么?
构造函数用于初始化对象的实例,它的名称与类名相同。
析构函数(Finalizer)用于清理资源,由垃圾回收器调用。
1 | class MyClass |
ps 一般程序员不需要手动去写,大多数情况下,使用 IDisposable 接口和 Dispose 方法来进行资源的显式释放更为常见和推荐。
2.5 泛型的几种约束
| 约束 | 说明 |
|---|---|
| T:struct | 类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。 |
| T:class | 类型参数必须是引用类型,包括任何类、接口、委托或数组类型。 |
| T:new () | 类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。 |
| T:<基类名> | 类型参数必须是指定的基类或派生自指定的基类。 |
| T:<接口名称> | 类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。 |
| T:U | 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束. |
2.6 C#中的事件是什么?如何订阅和触发事件?
事件是一种用于通知其他类发生某些操作的机制。
使用+=操作符订阅事件,使用Invoke或eventname?.Invoke()触发事件。
2.7 值类型在引用类型里面声明 是存在哪里
你可以在引用类型中声明值类型。这样的情况下,值类型的实例仍然存储在堆上,因为引用类型本身总是存储在堆上。当你声明一个类,并在类中包含值类型的字段或属性时,这些值类型的实例将与包含它们的引用类型实例一起存储在堆上。
2.8 C#委托
C# 中的委托(Delegate)是一种类型,它可以用于表示对方法的引用。委托可以看作是函数指针,它允许你传递方法作为参数,存储对方法的引用,以及调用方法。委托提供了一种灵活的方式来实现回调、事件处理和异步编程等场景。
例如
1 | delegate void MyDelegate(string message); |
C# 提供了一些内置的委托类型,如 Action 和 Func,它们可以用于引用不同的方法签名
1 | Action<string> actionDelegate = MethodToBeCalled; |
2.9 AOP DI是什么
AOP(面向切片)是一种编程思想,其核心思想是通过将横切关注点,例如在 AOP 中,你可以创建一个日志切面,用于记录每个方法的执行时间,而不需要在每个方法中都添加相同的日志代码。在.NET中可以参考过滤器。
DI(依赖注入)
- 概念: DI 是一种设计模式,旨在减少类之间的耦合,通过将依赖关系从类内移出,而是在类的外部进行管理。这有助于提高代码的可测试性和可维护性。
- 实现方式: DI 可以通过构造函数注入、属性注入或方法注入等方式来实现。依赖通常由外部容器(如容器框架或手动管理)提供。
- 示例: 在 DI 中,你可以将数据库访问对象注入到服务中,而不是在服务内部创建数据库访问对象。
AOP 与 DI 结合:
- 利用 DI 实现 AOP: DI 容器可以用来注入横切切面,以实现 AOP 的概念。通过 DI,你可以将横切关注点的实现注入到需要它的类中,而不是在这些类内部直接编写横切切面的代码。
- AOP 改进 DI: AOP 可以通过在 DI 容器中注册切面,以增强 DI 的能力。例如,在 DI 容器中注册一个日志切面,以便自动在每个注入的服务中添加日志记录功能。
2.9.1 Dotnet Core的依赖注入
1.主要使用IServiceCollection来进行依赖注入,通常是使用反射的机制来进行依赖注入,再编写注入代码,在程序运行的时候通过给定的接口名类名,反射找到类文件,注入到一个统一的集合当中
2.注入也分不同的方式
- 构造函数注入
1
2
3
4
5
6
7
8
9
10
11
12public class MyService
{
private readonly IAnotherService _anotherService;
public MyService(IAnotherService anotherService)
{
_anotherService = anotherService;
}
// ...
} - 方法注入
1
2
3
4
5
6
7
8public class MyService
{
public void DoSomething(IAnotherService anotherService)
{
// ...
}
} - 属性注入
1
2
3
4
5
6
7public class MyService
{
public IAnotherService AnotherService { get; set; }
// ...
} - 服务定位
使用IServiceProvider1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class MyService
{
private readonly IServiceProvider _serviceProvider;
public MyService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void DoSomething()
{
var anotherService = _serviceProvider.GetRequiredService<IAnotherService>();
// ...
}
} - 手动解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14using Microsoft.Extensions.DependencyInjection;
public class MyService
{
private readonly IAnotherService _anotherService;
public MyService(IServiceProvider serviceProvider)
{
_anotherService = serviceProvider.GetRequiredService<IAnotherService>();
}
// ...
}
2.9.2 依赖注入的生命周期
| 瞬态(Transient)作用域 | 作用域(Scoped)作用域 | 单例(Singleton)作用域 | |
|---|---|---|---|
| 生命周期 | 对于每次服务的请求,都会创建一个新的实例 | 在每个作用域(每个请求)内,只创建一个实例。在同一个请求内,多次调用IServiceProvider.GetService会得到相同的对象。 | 在整个应用程序的生命周期内,只创建一个实例。每次调用IServiceProvider.GetService都返回同一个对象。 |
| 示例 | services.AddTransient<IMyService, MyService>(); | services.AddScoped<IMyService, MyService>(); | services.AddSingleton<IMyService, MyService>(); |
不要在生命周期长的实例里使用生命周期短的实例
2.10 配置文件读取
- 1.IOptions:
不会读取到新的值; - 2.IOptionsMonitor:
实时获取新的值; - 3.IOptionsSnapshot:建议使用
会获取新的值,但是会在一个范围里保持一致;
2.11 Startup 类包含两个主要的方法:ConfigureServices 和 Configure
1.ConfigureServices
- 用途: ConfigureServices 方法用于配置应用程序的服务集合(Service Collection)。
- 运行时 : 在应用程序启动时被调用,通常是在 Main 方法中通过调用 WebHost.CreateDefaultBuilder(args).UseStartup
() 来启动应用程序时。 - 任务
- 注册应用程序所需的服务,包括数据库上下文、身份认证、授权、依赖注入服务等。
- 配置各种服务选项。
- 配置第三方服务集成,如Swagger、CORS等。
- 通过依赖注入向服务容器添加组件。
2.Configure
- 用途:Configure 方法用于配置应用程序的HTTP请求处理管道。
- 运行时:在 ConfigureServices 方法执行完毕后被调用。
- 任务:
- 配置中间件,构建请求处理管道。
- 配置路由、静态文件、错误处理等。
- 注册使用的中间件,例如身份认证、授权等。
说说脚本在请求Web CoreApi的时候,为什么会发生跨域问题?
跨域问题:本质是浏览器的行为,浏览器有一个同源策略,同源策略:协议、IP地址相同就认为是同源;否则就非同源;同源策略限定脚本请求只能请求同源的服务器返回的内容才给正常的使用;否则就会报跨域问题;其实我们在请求Core WebApi的时候,浏览器直接访问Api没有问题,如果是脚本请求,就会出现跨域问题;
3.redis常见面试题
3.1 什么是Redis?
Redis是一个开源的内存数据库系统,用作缓存、数据库和消息代理。它支持键值存储,数据结构存储,以及发布/订阅等功能。
3.2 Redis与Memcached有什么区别?
- Redis支持更复杂的数据结构(如列表、集合、哈希表),而Memcached只支持简单的键值存储。
- Redis提供持久性选项,可以将数据保存到磁盘,而Memcached则通常将数据存储在内存中。
- Redis支持数据的复制和高可用性。
- Redis支持事务,而Memcached不支持。
3.3 Redis的数据类型有哪些?说出几个应用场景。
1.字符串(String):
- 应用场景: 用于存储简单的键值对,例如缓存数据、配置信息等。
- 示例: 缓存系统中的数据、存储用户会话信息等。
2.列表(List):
- 应用场景: 用于实现消息队列、日志记录等有序集合场景。
- 示例: 实现异步任务队列、记录应用程序的操作日志等。
3.集合(Set):
- 应用场景: 用于存储唯一值,检查元素是否存在于集合中。
- 示例: 用户标签系统、存储唯一用户ID等。
4.有序集合(Sorted Set):
- 应用场景: 用于按分数范围获取元素,排行榜等场景。
- 示例: 实现排行榜、按照评分获取高分用户等。
5.散列(Hash):
- 应用场景: 用于存储对象、记录等,以字段的形式组织数据。
- 示例: 存储用户信息、存储对象属性等。
6.位图(Bitmap):
- 应用场景: 用于记录用户在线状态、统计用户行为等。
- 示例: 统计用户每天的登录情况、用户签到等。
7.HyperLogLog:
- 应用场景: 用于进行基数估算,估算数据集中的不同元素数量。
- 示例: 统计网站的独立访客数、社交网络中不同用户之间的关系数等。
8.地理空间(Geospatial):
- 应用场景: 用于存储地理位置信息,进行位置相关的查询。
- 示例: 实现位置附近的人、存储商家的地理位置信息等。
3.4 什么是缓存雪崩和缓存穿透?如何防止它们?
3.4.1 缓存雪崩
解释:Redis中缓存的数据大面积同时失效,或者Redis宕机,从而会导致大量请求直接到数据库,压垮数据库。对于一个业务系统,如果Redis宕机或大面积的key同时过期,会导致大量请求同时打到数据库,这是灾难性的问题。
解决办法
- 设置有效期均匀分布
避免缓存设置相近的有效期,我们可以在设置有效期时增加随机值;
或者统一规划有效期,使得过期时间均匀分布。 - 数据预热
对于即将来临的大量请求,我们可以提前走一遍系统,将数据提前缓存在Redis中,并设置不同的过期时间。 - 保证Redis服务高可用
Redis的哨兵模式和集群模式,为防止Redis集群单节点故障,可以通过这两种模式实现高可用。
3.4.2 缓存穿透
解释:缓存和数据库中都没有的数据,可用户还是源源不断的发起请求,导致每次请求都会到数据库,从而压垮数据库。
举例:比如客户查询一个根本不存在的东西,首先从Redis中查不到,然后会去数据库中查询,数据库中也查询不到,那么就不会将数据放入到缓存中,后面如果还有类似源源不断的请求,最后都会压到数据库来处理,从而给数据库造成巨大的压力。
解决方式
- 业务层校验
用户发过来的请求,根据请求参数进行校验,对于明显的错误参数直接拦截返回 - 不存在数据设置短过期时间
对于某个查询为空的数据,可以将这个空结果进行Redis缓存,但是设置很短的过期时间,比如30s,可以根据实际业务设定。注意一定不要影响正常业务。 - 布隆过滤器
布隆过滤器是一种数据结构,利用极小的内存,可以判断大量的数据“一定不存在或者可能存在”。
对于缓存击穿,我们可以将查询的数据条件都哈希到一个足够大的布隆过滤器中,用户发送的请求会先被布隆过滤器拦截,一定不存在的数据就直接拦截返回了,从而避免下一步对数据库的压力。
3.4.3 缓存击穿
解释:Redis中一个热点key在失效的同时,大量的请求过来,从而会全部到达数据库,压垮数据库。
这里要注意的是这是某一个热点key过期失效,和后面介绍缓存雪崩是有区别的。比如淘宝双十一,对于某个特价热门的商品信息,缓存在Redis中,刚好0点,这个商品信息在Redis中过期查不到了,这时候大量的用户又同时正好访问这个商品,就会造成大量的请求同时到达数据库。
解决方式
- 设置热点数据永不过期
对于某个需要频繁获取的信息,缓存在Redis中,并设置其永不过期。当然这种方式比较粗暴,对于某些业务场景是不适合的。 - 定时更新
比如这个热点数据的过期时间是1h,那么每到59minutes时,通过定时任务去更新这个热点key,并重新设置其过期时间。 - 互斥锁
这是解决缓存穿透比较常用的方法。
互斥锁简单来说就是在Redis中根据key获得的value值为空时,先锁上,然后从数据库加载,加载完毕,释放锁。若其他线程也在请求该key时,发现获取锁失败,则睡眠一段时间(比如100ms)后重试。
3.5 Redis的持久性机制是什么?
Redis提供了两种持久性机制:
- 快照(RDB):周期性地将内存数据快照到磁盘,生成一个二进制文件。
- 追加式文件(AOF):记录每个写操作,将写操作追加到文件中。在重启时,可以通过重新执行AOF文件中的写操作来还原数据。
3.6 Redis的主从复制是什么?
Redis的主从复制是一种数据复制机制,其中一个Redis服务器(主服务器)可以将其数据复制到其他Redis服务器(从服务器)。主服务器负责写操作,而从服务器负责复制主服务器上的数据。这提高了系统的可读性、扩展性和高可用性。
3.7 Redis的哨兵是用来做什么的?
Redis哨兵是用于监视和管理Redis主从复制环境的工具。它可以用于检测主服务器的故障,选择新的主服务器,以及在主服务器故障时自动切换到备用服务器。
3.8 为什么Redis是单线程的?
Redis是单线程的主要是为了避免多线程的复杂性和锁的开销。在IO密集型的场景下,单线程模型足够高效,而且通过异步IO操作,Redis可以在某些情况下达到很高的并发性能。
3.9 什么是Lua脚本在Redis中的应用?
Redis允许使用Lua脚本执行一系列命令,将多个命令组合成一个原子操作。这在保证原子性的同时减少了网络开销,并且在执行过程中不会被其他操作中断。Lua脚本可以用于复杂的数据处理和原子性操作的需求。
3.10 如何在 DotNET Core中使用Redis?
在.NET Core中,可以使用StackExchange.Redis等库来与Redis进行交互。首先,通过NuGet安装适当的库,然后通过配置文件或代码配置连接信息,使用库提供的API进行操作。
4. efcore 常见面试题
4.1 IEnumerable和IQueryable
IQueryable的参数是Expression是一个表达式,会存储拼接表达式树,直到在运行期最终执行,将查询操作翻译成sql在服务器中执行。
IQueryable是基于dataReader的。
使用FormattableString类型的变量来拼接sql字符串是不会有注入攻击的危险。
IEnumerable的参数是一个委托,委托一旦调用,就立即执行了,将执行结果保存在内存中,将数据全部加载到客户端内存中然后进行操作。
4.2 Lambda和Linq是什么关系
● Lambda是实例化委托的快捷方式,是方法(匿名方法的调用);
● Linq是基于委托的封装,逻辑解耦代码的重用,是帮助类库;
● 使用IEnumerable的拓展方法是方法语法,使用select from是查询语法;
4.3 说说EFCore查询的性能调优小技巧。
(1).使用DbContext池
(2).优先使用异步方法
(3).批处理语句
(4).关闭状态追踪,AsNoTracking()
(5).关闭状态同步,context.ChangeTracker.AutoDetectChangesEnabled = false
4.4 说说对SaveChanges的理解。
SaveChanges是以Context为维度的一次提交,对于数据库操作的一切动作,只要是在同一个Context实
例,所有的操作,在调用SaveChanges方法后,统一体现到数据库中去,在实操发现sql也是逐行运行的。
4.5 正确使用Find/FirstOrDefault
正确使用Find(id=10)来代替FirstOrDefault(t=>t.id=10)
Find会优先查询缓存,当前面已经查询过这条数据的时候使用,而FirstOrDefault每次都会查询数据库;当id=10的数据被修改之后,find查出的数据是新数据。
4.6 导航属性要延迟加载必须具备两个条件
a.导航属性是virtual的;
b.延迟查询必须是开启的。
5. sql 面试部分
5.1 mysql数据库优化
5.1.1 选取最适用的字段属性
MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。另外一个提高效率的方法是在可能的情况下,应该尽量把字段设置为NOTNULL,这样在将来执行查询的时候,数据库不用去比较NULL值。
5.1.2 使用连接(JOIN)来代替子查询(Sub-Queries)
Join之所以更有效率一些,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。
5.1.3 使用联合(UNION)来代替手动创建的临时表
5.1.4 使用事务
5.1.5 锁定表
因为开启事务会锁定表,会导致其他用户只能等事务结束才能进行操作数据库,人数少的时候影响不大,但是一些电商平台人数过多就会导致这个问题放大出来,这个时候可以自己手动锁定表来进行操作
5.5.6 使用外键
锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。如果要在MySQL中使用外键,一定要记住在创建表的时候将表的类型定义为事务安全表InnoDB类型。该类型不是MySQL表的默认类型。定义的方法是在CREATETABLE语句中加上TYPE=INNODB。如例中所示。
5.5.7 使用索引
创建索引的语句
1 | CREATE INDEX indexName ON table_name (column_name) |
索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(),MIN()和ORDERBY这些命令的时候,性能提高更为明显。一般说来,索引应建立在那些将用于JOIN,WHERE判断和ORDERBY排序的字段上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。
索引分类
- 1.普通索引:
最基本的索引。 - 2.唯一索引:
类似普通索引但是要求所有的值是唯一的,但是允许有空值。 - 3.主键索引:
不允许有空值。 - 4.全文索引:
可以对text varchar image型字段进行检索 - 5.组合索引:
查询有多个条件时适用 有最左原则 - 6.前缀索引:
当字符串本身可能比较长,而且前几个字符就开始不相同,适合使用前缀索引;相反情况下不适合使用前缀索引
不能在 order by 或者 group by 中触发前缀索引,也不能把它们用于覆盖索引
索引分为聚簇索引和非聚簇索引
- 聚簇索引:
将数据存储和索引放在一起、并且是按照一定的顺序组织的,找到索引也就找到了数据,数据的物理存放顺序与索引顺序是一致的,
即:只要索引是相邻的,那么对应的数据一定也是相邻的存放在磁盘上的 - 非聚簇索引:
叶子节点不存储数据,存储的是数据行地址,也就是说根据索引查找到数据行的位置再去磁盘查找数据,这就有点类似一本书的目录,
比如要找到第三章第一节,那就现在目录里面查找,找到对应的页码后再去对应的页码看文章。
索引方面优化
- 创建索引
对于创建索引要针对性不能所有字段都设置索引,因为索引会再每一行占一定的空间,如果很多重复的值或者null的话 有时候会降低内存 - 复合索引
比如有一条语句是这样的:select * from users where area=’beijing’ and age=22;
如果我们是在area和age上分别创建单个索引的话,由于mysql查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效率,但是如果在area、age两列上创建复合索引的话将带来更高的效率。如果我们创建了(area, age, salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀特性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。 - 索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。 - 使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的 列,如果在前10 个或20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。 - 排序的索引问题
mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。 - like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。 - 不要在列上进行运算
select * from users where YEAR(adddate)<2007;
将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成
select * from users where adddate<‘2007-01-01’; - 不使用NOT IN和<>(<>就是不等于逻辑符号)操作
NOT IN和<>操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id<>3则可使用id>3 or id<3来代替。
索引失效场景
- 查询条件中带有or,除非所有的查询条件都建有索引,否则索引失效
- like查询是以%开头
- 如果列类型是字符串,那在查询条件中需要将数据用引号引用起来,否则不走索引
- 索引列上参与计算会导致索引失效
- 违背最左匹配原则
- 查询的数量是大表的大部分,应该是30%以上。
了解更多
5.5.8 硬件优化(不属于程序员范畴)
cpu 内存 磁盘I/O优化 调整磁盘调度算法
5.5.9 修改mysql的配置文件my.cnf(不属于程序员范畴)
如mysql查询缓冲区的大小 mysql允许的最大连接进程
##ps 自我介绍
大家好,我是徐毅飞,很高兴有机会参加这次面试。
我拥有本科学位,并在过去的3年里专注于C#开发。在上一份工作中,我负责公司的.net core研发,负责公司各种不同礼堂需求的开发,这也让我学习积累到很多的.net core 开发经验。在工作之余还自修了java,vue的技能了解一些云技术,看到公司的技术栈很符合我的职业规划,希望有幸加入贵公司。
- Title: Dotnet Core 备忘录
- Author: faith team
- Created at: 2023-12-15 11:21:05
- Updated at: 2025-11-29 09:01:08
- Link: https://redefine.ohevan.com/2023/12/15/20231215CsharpMeeting/
- License: This work is licensed under CC BY-NC-SA 4.0.