Moonglade

Modern Markdown blogging with AI-powered localization and search.

All Posts


.NET Backend Interview: 26 Questions — In-Depth Analysis of Concurrency, Caching, Databases, and Industrial Communication

This article provides an in-depth analysis of several core technical aspects within the C# and .NET ecosystem. First, it clarifies the fundamental differences between events and delegates, emphasizing the strict restrictions on external assignment and triggering for events. Second, it elaborates on the .NET garbage collection generational model, Large Object Heap (LOH) characteristics, and optimization strategies, recommending the use of object pools and `Span` to reduce GC pressure. In terms of architectural choices, it compares the differences between time-series databases and relational databases in storage, writing, and querying, noting that they are typically used together; it also analyzes the advantages and limitations of gRPC based on HTTP/2 and Protobuf, as well as the solution for implementing connection count limits in clustered environments using SignalR with Redis. Regarding the challenge of exporting million-row datasets to Excel, it proposes solutions such as asynchronous tasks, streaming reads, and streaming write libraries like MiniExcel to avoid out-of-memory errors. Additionally, the article distinguishes the practical differences between baud rate and bit rate in serial communication, outlines C# thread synchronization mechanisms, and points out that `SemaphoreSlim` should be used instead of `lock` in asynchronous scenarios. Finally, by comparing the underlying structures and time complexities of `List` and `Dictionary`, it emphasizes the importance of leveraging dictionaries to optimize lookup performance in large-scale data scenarios, and provides interview tips, suggesting the use of real project data to demonstrate technical depth.

Views 299
C# Development Database Design IoT Systems Message Queues Performance Tuning System Architecture

A Brief Overview of the Time-Series Database InfluxDB and How to Interact with It Using .NET

This article addresses the sensor data management requirements of water utility companies' pump rooms and introduces the application of the time-series database InfluxDB. It first explains the optimization advantages of time-series databases for scenarios involving high write throughput, time-based queries, and immutable data. It then compares the differences between time-series databases and relational databases in core concepts such as Bucket, Measurement, Tag, Field, and Timestamp, with particular emphasis on the distinction that Tags are used for low-cardinality dimension indexing while Fields store non-indexed metric values. Subsequently, based on the .NET environment, it provides a detailed demonstration of the complete workflow: installing the client via NuGet, configuring connection information, writing data using PointData method chaining, and performing efficient queries using the Flux language. Finally, it points out that mastering the correct usage of Tags and Fields is key to operating InfluxDB efficiently, and that this solution can effectively improve sensor data write performance and query efficiency.

Views 324
.NET Flux InfluxDB IoT TagDB TimeSeries

Creating an MQTT client with automatic reconnection using `ManagedMqttClient` from MQTTnet

This article introduces how to simplify MQTT communication development in C# projects by leveraging the ManagedMqttClient extension package from MQTTnet. Compared to the native MqttClient, this extension package has built-in features for automatic reconnection, offline message queuing, and automatic subscription state recovery, significantly reducing the maintenance cost of reconnection logic. The article focuses on analyzing three core concepts in the MQTT protocol: QoS (Quality of Service) levels, where QoS 1 (at least once) is suitable for most scenarios, QoS 2 (exactly once) is reliable but has high performance overhead, and QoS 0 is used for low-priority data where packet loss is acceptable; the CleanSession flag, where setting it to false allows the Broker to cache QoS 1/2 messages while the client is offline and resend them after reconnection, which is ideal for devices requiring data integrity; and the Retain message mechanism, which allows the Broker to store the latest state of a Topic so that new subscribers can immediately obtain the most recent data, commonly used for device state synchronization. Finally, through examples of a temperature sensor and an alarm system, the article demonstrates how to combine these parameters based on business requirements to balance message reliability, real-time performance, and system resource consumption, providing clear guidelines for MQTT configuration in real-world projects.

Views 334
.NET C# IoT MQTT MQTTnet ManagedMqttClient

Implementing API Rate Limiting with Redis in Admin.Core

This article introduces the configuration and principles of implementing IP rate limiting in the ZhonTai Admin.Core framework based on AspNetCoreRateLimit and Redis. First, rate limiting must be enabled in `appconfig.json` and `cacheconfig.json`, with Redis specified as the storage backend to support multi-instance distributed environments. Rate limiting rules are defined in `appsettings.json`, supporting differentiated strategies for global endpoints and specific interfaces (such as login). Key configurations include enabling endpoint rate limiting, avoiding request stacking, and correctly setting the real IP header. The working principle involves the middleware generating Redis keys based on IP and path for counting; if the limit is exceeded, a 429 status code is returned, and the frontend prompts the user. The article specifically points out that the middleware registration order must place `UseIpRateLimiting` after `UseStaticFiles` to prevent static file requests from triggering rate limiting. Additionally, the article provides steps for manually integrating this component in environments other than Admin.Core, and mentions the built-in rate limiting mechanism in .NET 7 as an alternative solution, recommending that developers already using this framework directly leverage the built-in features to simplify development.

Views 312
.NET Admin.Core AspNetCore RateLimiting Redis WebApi

Several Ways to Write and the Differences Between `server_name`, `location`, and `proxy_pass` in Nginx

This article provides an in-depth analysis of common configurations and potential pitfalls associated with the three core directives `server_name`, `location`, and `proxy_pass` in Nginx reverse proxy setups. First, `server_name` supports various matching methods, including exact domain names, wildcards, regular expressions, empty values, IP addresses, and variables. The matching priority is as follows: exact matches take precedence over prefix wildcards, which in turn take precedence over suffix wildcards and regular expressions. It is recommended to prioritize using wildcards for better performance. Second, the presence or absence of a trailing slash in `location` significantly affects matching behavior. For instance, `location /image` will match `/imageabc`, whereas `location /image/` only matches paths starting with `/image/`. Nginx follows the longest prefix matching principle, with `location /` serving as the fallback option. Finally, whether `proxy_pass` includes a trailing slash determines the path forwarding logic: if no path is specified, the original URI is preserved in its entirety; if a path is specified (including just a single slash), the prefix matched by `location` is replaced by the path specified in `proxy_pass`. This easily leads to incorrect forwarding paths. Understanding these subtle differences is crucial for correctly configuring Nginx and avoiding routing confusion.

Views 287
Default Location Match Nginx Proxy Pass Server Name reverse proxy

How My Steam Account Was Hacked

This article details a chained phishing scam targeting Steam accounts. Hackers first steal QQ accounts through internet cafes or untrusted VPN environments, then compromise user email accounts and block official Steam emails. They subsequently maliciously lock Steam accounts, inducing users into a state of panic. When users attempt to recover their accounts, they receive a forged unlock link that directs them to a highly convincing fake Steam website, tricking them into entering sensitive information such as account names, passwords, and recovery codes. Once submitted, hackers alter the linked email and phone number in the backend and remove security tokens, resulting in the complete theft of the account. The article advises users to avoid using QQ mailboxes, which have lower security, and to never enter account credentials on public computers or over public WiFi. It recommends prioritizing QR code login for Steam and using free accelerators to address slow mobile access issues. Additionally, the text lists specific hacker sender email addresses and characteristics of phishing URLs, urging users to stay vigilant, strengthen their cybersecurity awareness, and prevent the leakage of personal information.

Views 298
Cybersecurity Default Email Safety Password Theft Phishing Steam Security

Issue with Non-Deterministic Ordering of Identical Values in PostgreSQL

PostgreSQL and SQL Server exhibit significant differences in the stability of data sorting. SQL Server stores data physically by primary key, ensuring a fixed order when sort values are identical. In contrast, PostgreSQL uses a heap table structure where the physical location of data changes dynamically with updates, resulting in an unpredictable row order when the `ORDER BY` column contains duplicate values. The solution is to always include a unique column (such as the primary key) as a secondary sorting condition in the `ORDER BY` clause. For example, using `ORDER BY create_time DESC, id DESC` ensures a stable query result order. It is recommended to develop the habit of including a unique column as a fallback in all sorting queries to avoid relying on the database engine's implicit behavior.

Views 198
.NET Data Sorting Deterministic Order ORDER BY PostgreSQL SQL Server

Consuming Kafka in a .NET 5 console service with automatic reconnection

This article introduces a practical solution for building a highly available Kafka consumer background service in .NET 5 using Microsoft.Extensions.Hosting and Confluent.Kafka. The core implementation is based on BackgroundService, employing an outer daemon loop to catch exceptions and delay reconnection, ensuring that the service can automatically recover during network fluctuations or Broker failures. The code uses `await Task.Yield()` to avoid blocking host startup and disables automatic commit to manually control Offset, thereby ensuring that data is not lost when message processing fails. Regarding graceful shutdown, it utilizes CancellationToken to respond to Docker SIGTERM signals, ensuring that `consumer.Close()` is executed in the finally block to promptly notify the Broker to trigger Rebalance and exit cleanly. Additionally, the article emphasizes critical considerations for production environments: externalizing configuration, using IServiceScopeFactory to resolve Scoped service dependency issues, and adopting batch commit to optimize performance in high-volume scenarios.

Views 200
.NET .NET 5 BackgroundService Confluent.Kafka Docker Kafka

Building an IoC Container from Scratch with .NET Framework 4.7.2

This article dissects the core mechanisms of dependency injection by manually implementing a minimalist IoC container. The author points out that IoC primarily consists of three elements: registration, resolution, and lifecycle management. The article presents implementation code based on C# reflection and dictionary mapping, with a focus on analyzing how the Resolve method recursively searches for constructor parameters and automatically creates dependency instances, thereby solving the cumbersome problem of manually assembling objects. Through a test case involving a three-level dependency chain, the article verifies that the container can automatically populate constructor parameters and correctly implements the singleton pattern, ensuring that the same service instance is returned during multiple resolutions. The author also notes that although this simplified container lacks enterprise-grade features such as Scoped lifecycle, thread-safe locking, circular dependency detection, and IDisposable resource management, its 50-plus lines of code precisely reveal the essence of an IoC container: achieving inversion of control by recursively resolving the dependency tree and building objects layer by layer from the leaf nodes upward.

Views 239
.NET C# DI Container Dependency Injection Inversion of Control IoC

StackExchange.Redis Disconnection Pitfalls

This article summarizes common pitfalls and solutions for StackExchange.Redis connection interruptions and reconnection failures. The primary issue is that the default configuration has `abortConnect` set to `true`, which prevents automatic recovery after a disconnection. To enable automatic reconnection, you must set `abortConnect=false` in the connection string. Second, reconnection failures may still occur under high load. It is recommended to catch `RedisConnectionException` and manually rebuild the `ConnectionMultiplexer` instance. Regarding the issue in Linux environments where reconnection can take up to 15 minutes after a disconnection, the root cause is that the kernel parameter `tcp_retries2` has a default value that is too large. You can adjust it to `5` using the `sysctl` command to accelerate TCP layer release. Finally, it is emphasized that `ConnectionMultiplexer` must be used as a singleton. Creating a new connection for every request is strictly prohibited, as it can lead to a connection explosion. It is recommended to register it as a singleton service in dependency injection.

Views 180
.NET BestPractices C# Redis StackExchange.Redis Troubleshooting