kitlau
kitlau

kitlau's blog

All Posts in 2023.7


如何 3 分钟搭建图片转文本工具

本文介绍了如何利用LAF(一个基于Node.js的开发平台)快速构建一个图像识别系统。前端部分通过HTML、CSS和JavaScript实现了图片上传界面和结果显示功能,用户可以选择本地图片并预览;后端则使用Node.js处理图片文件,并通过调用AI图像识别API获取结果并返回给前端。文章还提到可以通过替换不同的AI模型(如支持中文的模型)来提升识别效果或实现多语言支持,同时强调了前后端分离设计的优势和开发流程的基本框架。--DeepSeek

AI LafStack Image Processing Computer Vision Frontend Development API Integration

如何使用 Optional 模式解决 C# 中的烦人的空引用问题

文章讨论了在C#中处理null值的两种方法:Optional模式和Nullable特性。作者通过示例代码展示了这两种方法的特点,并强调了Optional模式的优势,包括避免显式的null检查、减少NullReferenceException的风险以及在编译时就能发现潜在问题。与Nullable特性相比,Optional模式虽然可能让代码稍显复杂,但它通过函数式编程的概念提供了一种更安全和简洁的方式来处理可能为空的值。作者总结指出,在选择使用哪种方法时,可以根据项目的规模和团队成员的技术水平来决定,但两种方法都是有效的null引用解决方案。--DeepSeek

C# Null Handling Null Safety Optional Pattern Functional Programming Type System

Linq 和 lambda 的区别是什么?

这篇文章探讨了Linq和Lambda表达式之间的区别与联系,并反思了开发者对基础知识的忽视现象。作者通过代码示例说明,Linq(Language-Integrated Query)是一种查询库,提供多种语法形式,而Lambda是创建匿名委托的简洁方式,常用于Linq的方法语法中。两者虽紧密相关,但本质不同:Linq是一个功能库,而Lambda是一种表达式形式。文章指出,开发者往往因教材和文档中的同时出现而将它们混淆,并强调掌握基础知识的重要性。最后,作者建议读者探索表达式树的高级应用,并提出问题:你是否真正理解了这些基础概念,还是仅停留在表面应用上?这引发对学习方式和深度思考的反思。--DeepSeek

C# linq lambda expressions expression trees entity relationship mapping Method Syntax

一幅漫画解释 .NET 垃圾收集(GC)原理

本文通过一幅漫画科普了 .NET 垃圾收集(GC)的基本原理,并结合实际工作中的观察,指出了国内普通开发者对基础知识掌握不足的问题。作者认为,虽然当前工作环境可能将开发者视为流水线代码工,但从性能优化的角度切入学习仍是一个值得探索的方向,而减少 GC 压力则是 .NET 性能优化的重要切入点。 漫画来自 Redgate 的经典科普内容,尽管该内容主要针对 .NET Framework 时代,但其核心原理在现代 .NET 中依然适用。作者分享了这幅漫画的翻译,并提到了大对象堆(LOH)压缩问题的一个解决方案:将 GCSettings.LargeObjectHeapCompactionMode 设置为 CompactOnce。然而这一方案仅能在一个 GC 周期内生效,本质上回到了手动内存管理的方式,这也引发了对如何有效管理和优化 LOH 的进一步思考。 这篇文章不仅帮助开发者理解 .NET GC 的基本机制,还通过实际案例展示了性能优化的复杂性。对于想要深入了解 .NET 内存管理、GC 机制以及性能优化的同学来说,本文是一个不错的起点。你是否也曾在工作中遇到过因 GC 压力导致的性能问题?如何在现代 .NET 环境中更好地管理和优化 LOH 呢?这些问题值得每一位开发者深入思考和探索。--DeepSeek

.NET dotnet garbage collection performance optimization large object heap comic translation

C# required:跟 string 的空引用异常说再见

文章讨论了一个软件开发中的常见问题:属性类型设置错误导致线上bug,并结合C#11引入的`required`关键字探讨了如何避免此类问题。作者指出,在快速开发和压缩工时的环境下,开发者可能忽视基础质量保障,最终导致软件质量下降,影响用户体验。文中通过技术手段(如`required`关键字)与管理反思(批评急功近利的绩效考核模式),强调了在开发过程中重视代码质量和可维护性的重要性。同时,作者吐槽了团队中普遍存在的“外包模式”思维,认为这种做法会损害产品质量和用户信任,并呼吁在软件开发中避免牺牲质量以追求速度。--DeepSeek

C# Code Quality required keyword Nullables Engineering Practices Software Product Management

.NET 是如何编译的?如何阅读中间语言?

C#代码的编译过程分为几个关键步骤:首先,编写C#源代码;其次,通过Roslyn编译器将其转换为中间语言(IL);然后,在运行时由JIT编译器将IL转换为机器码。文章详细解释了每个阶段的工作原理,包括编译器如何解析代码、生成IL的结构以及JIT如何优化性能以实现跨平台兼容性。此外,文章还介绍了如何阅读和理解IL代码,这对分析代码性能和执行过程有所帮助。--DeepSeek

.NET performance optimization C# Compilation Intermediate Language JIT Compiler .NET Framework

【译】.NET SDK 将会内置容器支持,不再需要 Dockerfile

这篇文章介绍了DotNet SDK构建容器镜像的功能,讨论了其优势和应用场景,如简化容器化过程、避免手动编写Dockerfile的复杂性等,并提供了使用示例。文章还详细说明了当前功能的限制,包括不支持Windows镜像、非x64架构、推送远程仓库以及某些镜像元数据定制等,并指出这些功能将在未来的版本中逐步完善。此外,作者鼓励开发者尝试这一新功能,并表示会持续改进,最终将其直接集成到DotNet SDK中,同时提供了GitHub里程碑和包资源以供跟踪最新进展。--DeepSeek

.NET Docker .NET SDK Container Builds Linux x64 GitHub Actions

还在背依赖注入的概念?不如自己写一个依赖注入框架

在控制台应用中使用依赖注入时,Singleton 和 Scoped 生命周期的行为并不完全相同。通过代码示例展示了即使在控制台环境中,Scoped 服务在不同作用域(Scope)下会生成不同的实例,而 Singleton 服务在整个应用程序生命周期内始终保持唯一实例。文章还指出,有些人错误地认为在控制台应用中 Scoped 与 Singleton 的行为一致,但事实并非如此。进一步说明了即使注册为 Singleton 的服务,在某些特定情况下也可能获取到不同的实例。文章批评了应试教育式的编程学习方式,强调这种教学方法扼杀创造力,并呼吁采用更实践和深入的学习方法来理解依赖注入的真正机制。--DeepSeek

.NET DependencyInjection Dependency Injection Service Lifecycles Software Engineering Design Patterns

异步的原理是什么?C# 如何基于状态机实现异步?

C#异步实现的核心在于通过状态机管理async/await操作,MoveNext()方法负责从正确位置开始执行、保存状态并安排续延。快速路径指所有await操作均已完成,MoveNext()仅被调用一次;慢速路径则在遇到阻塞时暂停并安排续延,后续重新调用MoveNext()继续执行。异常处理通过builder传递而非抛出,"尚未启动"和"正在执行"状态合并以简化实现。整体流程包括从SetStateMachine到完成的各个阶段,展示了C#异步机制的高效与优雅。--DeepSeek

C# C# async programming State Machine Execution Paths Exception Handling Async Execution

什么是异步?异步就是多线程吗?异步就是 async、await 吗?

这篇文章详细介绍了C#异步编程的基础知识及其应用场景。首先,文章解释了`async`和`await`关键字的基本使用方法,并展示了如何在控制台应用程序中实现异步方法。接着,文章讨论了不返回值的异步方法以及如何处理这种情况。然后,通过对比同步与异步执行方式,文章强调了异步编程在提升程序性能和用户体验方面的重要性。 文章还详细介绍了如何先调用异步方法后`await`其结果,以实现多个任务的同时运行,并展示了这种方法的优势。此外,作者解释了不使用`async`修饰符的异步方法的实现方式,包括使用`Task.``FromResult()`和`Task.CompletedTask`来返回结果。 最后,文章介绍了如何通过`Task.WhenAll()`同时等待多个任务完成,以避免阻塞和提高效率。整篇文章旨在帮助开发者理解异步编程的基本概念和应用场景,并提供了一些实用的代码示例来说明这些概念。--DeepSeek

C# dotnet Async Await Task Parallelism Multithreading Task

EF Core 何时、为何使用 IsUnicode 方法

本文讨论了在Entity Framework Core中使用IsUnicode(false)时需谨慎考虑的因素,并通过实际案例说明了可能引发的问题。文章指出,varchar类型适合纯ASCII字符,而nvarchar支持Unicode字符;若错误配置可能导致数据存储问题。通过URL字段和用户输入的示例,作者提醒开发者不应低估用户的输入多样性。最后,介绍了EF Core 6引入的Unicode属性,并总结了软件开发中的潜在陷阱及建议。--DeepSeek

C# EF Core Entity Framework Core IsUnicode Method Database Design Model Configuration

彻底理解 ASCII Unicode UTF-8 UTF-32 是什么以及区别与联系

字符编码与Unicode是一个复杂而重要的计算机科学基础概念,理解它们的内在逻辑对于软件开发和数据处理至关重要。文章详细解释了ASCII、Unicode以及UTF-8等编码方案的基本原理及其实际应用。文章指出,Unicode是一个包含所有字素的通用字符集,而UTF-8是其最常见的编码方式,用于将Unicode代码点转换为二进制形式。不同编程语言在字符串长度计算上表现出差异,例如Python和C#默认使用不同的编码策略(如UTF-16),而Go则直接返回UTF-8字节数。文章还强调了开发者需要理解这些底层机制以避免潜在问题,并建议根据具体情况选择合适的处理方法(如"不可感知Unicode的函数"、"可感知Unicode的函数"或"可感知字素的函数")。此外,文章提到应试教育中常将字符代码与编码方案混为一谈,实际上它们是两个不同的概念。为了帮助读者深入理解,文章推荐了一个在线资源链接,并总结了ASCII与Unicode的区别及其在不同编码策略下的表现。 最终结论:理解字符编码和Unicode的内在机制是开发者必备的核心技能之一,掌握这些知识能够有效避免因编码问题导致的各种麻烦。--DeepSeek

dotnet ASCII Unicode UTF 8 Go Programming Language Character Encoding

EF Core 动态构建表达式树简化 DDD 值对象的比较

这篇文章主要介绍了如何通过构建动态表达式树来生成复杂的SQL查询语句。作者详细讲解了使用`ValueObjectEqualHelper`方法的实现细节,包括如何处理原始类型和非原始类型的相等比较,以及如何将多个属性条件组合成一个逻辑与(AndAlso)的表达式树。最终生成的SQL语句正确,并且能够准确返回预期的结果。文章还提供了相关的代码示例和注释,帮助读者更好地理解动态表达式树的构建过程,并建议进一步阅读作者之前关于C#表达式树的文章以加深理解。--DeepSeek

.NET C# EF Core expression trees Entity Framework Core Dynamic Condition Generation

EF Core 动态构建表达式树为所有实体设置软删除的查询过滤器

作者通过使用Entity Framework Core的查询过滤功能和动态生成的表达式树,成功地为每个实体类自动生成了SoftDelete标记的过滤条件,从而避免了手动重复编写代码。这种方法不仅减少了代码冗余,还提高了项目的可维护性和扩展性,并且可以通过调用IgnoreQueryFilters方法来禁用自动过滤以获取所有数据。--DeepSeek

.NET EF Core lambda expressions Entity Framework Core Dynamic Expression Trees Soft Delete

手把手构建 C# 表达式树

这篇文章详细介绍了如何手动构建一个表达式树以筛选年龄大于18岁的人,包括创建参数、成员访问、比较运算符以及最终的Lambda表达式。作者展示了如何使用这个表达式在代码中过滤列表,并通过控制台输出结果。文章还讨论了手动编译表达式的必要性,提到如果使用`IQueryable`则不需要此步骤,并预告了两篇关于将表达式树应用于EF Core的文章,分别涉及动态构建表达式树来简化值对象比较和为实体类属性设置过滤器,而无需在每个配置中手动设置。--DeepSeek

.NET C# EF Core expression trees Dynamic Expression Linq Expressions

如何使用 CSharp 表达式树?

这篇文章介绍了如何手动构建C#表达式树以解决硬编码问题,并通过一个示例详细讲解了如何创建参数节点、成员访问节点以及组合成Lambda表达式的过程。文章还提到了表达式树在领域驱动设计中的潜在应用,但指出动态构建表达式树的代码可能较难理解,因此建议仅在必要时使用。最后,作者提供了相关的官方文档链接以供进一步学习。--DeepSeek

C# Functional Programming lambda expressions expression trees Dynamic Code Generation Property Access

【译】数据是如何存储在 SQL 数据库中

本文探讨了 SQL 数据库中数据的存储机制,重点解释了数据页、B-树和聚集索引结构等关键概念。文章指出,尽管数据库的逻辑结构看似简单,但其物理存储方式决定了性能优化的可能性。通过详细分析 B-树的层级结构和指针系统,本文揭示了 SQL Server 如何高效定位数据行,以及这些底层机制对查询性能的影响。深入理解这些内容,不仅可以帮助我们更好地设计数据库,还能让我们在遇到性能问题时找到解决方案。那么,你是否已经开始思考如何根据这些知识优化自己的数据库设计了呢?--DeepSeek

DB Data Storage B Tree Clustered Index Data Page Root Node

【译】SQL 索引是如何工作的

这篇文章详细介绍了数据库中的聚集索引和非聚集索引的原理及其工作方式,通过实际操作和执行计划对比了有无索引时的成本差异。文章指出,聚集索引存储表中的所有行数据,并且作为主键自动创建;而非聚集索引则只存储指向聚集索引的指针和相关列值,用于快速定位数据。查询优化器会根据索引类型选择最优执行计划以减少IO操作。通过非聚集索引的Index Seek和Key Lookup过程,可以高效地实现基于非聚集索引的查询,并最终通过嵌套循环将结果集组合起来。文章还对比了有无非聚集索引时的Estimated Subtree Cost差异,强调了索引对性能优化的重要性。--DeepSeek

DB Clustered Index Database Index Non Clustered Index Execution Plan Query Optimization

如何在 CSharp 和 EF Core 中使用 UTC 时间

本文介绍了一位开发者为解决外贸网站时区问题而采用UTC时间处理的方法。通过定义Product实体类并将时间字段存储为UTC,在EF Core中配置模型确保数据库存储UTC时间,并使用Mapster将UTC时间转换为美国当地时间展示给用户,避免了因时区差异导致的时间显示错误。文章详细讲解了UTC时间的概念、C#中的操作方法、EF Core的配置扩展以及Mapster工具的应用,最终实现了前台网站正确显示当地时的功能,确保产品信息准确无误。--DeepSeek

.NET C# EF Core utc time mapster time zones