C# (C Sharp) programming
По всем вопросам- @notxxx1 Реестр РКН: https://clck.ru/3Fk3kb #VRHSZ
إظهار المزيد📈 نظرة تحليلية على قناة تيليجرام C# (C Sharp) programming
تُعد قناة C# (C Sharp) programming (@csharp_ci) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 18 307 مشتركاً، محتلاً المرتبة 7 338 في فئة التكنولوجيات والتطبيقات والمرتبة 36 903 في منطقة روسيا.
📊 مؤشرات الجمهور والحراك
منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 18 307 مشتركاً.
بحسب آخر البيانات بتاريخ 12 يونيو, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار -16، وفي آخر 24 ساعة بمقدار 5، مع بقاء الوصول العام مرتفعاً.
- حالة التحقق: غير موثّقة
- معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 18.53%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 7.49% من ردود الفعل نسبةً إلى إجمالي المشتركين.
- وصول المنشورات: يحصل كل منشور على متوسط 3 393 مشاهدة. وخلال اليوم الأول يجمع عادةً 1 371 مشاهدة.
- التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 0.
- الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل .net, api, логика, архитектура, string.
📝 الوصف وسياسة المحتوى
يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
“По всем вопросам- @notxxx1
Реестр РКН: https://clck.ru/3Fk3kb
#VRHSZ”
بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 13 يونيو, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.
using System;
using System.Threading;
class Program
{
static Lazy<HeavyObject> _heavy = new Lazy<HeavyObject>(() =>
{
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] Initializing HeavyObject...");
return new HeavyObject();
});
static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(() =>
{
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] Accessing HeavyObject...");
var obj = _heavy.Value;
}).Start();
}
Console.ReadLine();
}
}
class HeavyObject
{
public HeavyObject()
{
Thread.Sleep(1000); // эмуляция долгой инициализации
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] HeavyObject created.");
}
}
❓ Вопрос:
Сколько раз вы увидите сообщение Initializing HeavyObject... и HeavyObject created.? Почему это может удивить даже опытных .NET разработчиков?
🔍 Разбор:
На первый взгляд вы ожидаете, что:
- `Lazy<T>` гарантирует **ленивую инициализацию один раз** даже при многопоточном доступе.
- Сообщение `Initializing HeavyObject...` и конструктор `HeavyObject` сработают только один раз.
Но! Тут есть подвох.
По умолчанию `Lazy<T>` использует **LazyThreadSafetyMode.ExecutionAndPublication**. Это гарантирует, что даже если несколько потоков обращаются к `.Value` одновременно, объект будет инициализирован **только один раз**.
✅ **Ожидаемый вывод:**
- Каждый поток пишет `Accessing HeavyObject...`
- Только один поток пишет `Initializing HeavyObject...` и `HeavyObject created.`
- Остальные потоки дождутся завершения и получат уже готовый объект.
Примерный вывод:
```
[4] Accessing HeavyObject...
[5] Accessing HeavyObject...
[6] Accessing HeavyObject...
[7] Accessing HeavyObject...
[8] Accessing HeavyObject...
[4] Initializing HeavyObject...
[4] HeavyObject created.
```
🌀 **Подвох, если сменить режим:**
Если вы немного измените код вот так:
```csharp
static Lazy<HeavyObject> _heavy = new Lazy<HeavyObject>(
() =>
{
Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] Initializing HeavyObject...");
return new HeavyObject();
},
LazyThreadSafetyMode.None // без потокобезопасности
);
```
То при **одновременном** доступе к `.Value` вы получите **несколько инициализаций** (по сути гонку потоков).
Примерный вывод может быть таким:
```
[4] Accessing HeavyObject...
[5] Accessing HeavyObject...
[6] Accessing HeavyObject...
[4] Initializing HeavyObject...
[5] Initializing HeavyObject...
[6] Initializing HeavyObject...
[4] HeavyObject created.
[5] HeavyObject created.
[6] HeavyObject created.
```
Итого объект будет создан несколько раз, что ломает инварианты "Lazy должен создавать объект один раз".
✅ **Вывод:**
• По умолчанию `Lazy<T>` **потокобезопасен**, но важно понимать, что это можно **изменить**.
• При работе с многопоточностью в .NET всегда обращайте внимание на **режим LazyThreadSafetyMode**.
• Даже опытные разработчики могут не заметить подвоха, если кто-то по ошибке или из оптимизаций использует `LazyThreadSafetyMode.None`.
💡 **Бонус-вопрос:**
Что произойдёт, если ваш factory-метод (лямбда) выбросит исключение при инициализации? Как `Lazy<T>` поведёт себя при следующем доступе к .Value?
@csharp_ci
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("1");
var task = FooAsync();
Console.WriteLine("2");
await task;
Console.WriteLine("5");
}
static async Task FooAsync()
{
Console.WriteLine("3");
await Task.Delay(100);
Console.WriteLine("4");
}
}
❓ Вопрос:
Какой порядок чисел появится в консоли?
👇 Подумай, прежде чем смотреть ответ.
—
✅ Разбор:
1. Console.WriteLine("1"); → печатает 1
2. var task = FooAsync(); → вызывается FooAsync(), который:
печатает 3
доходит до await Task.Delay(100); и возвращает управление в Main (не дожидаясь задержки)
3. Console.WriteLine("2"); → печатает 2
4. await task; → теперь Main ждёт завершения FooAsync
5. после 100ms продолжает выполнение в FooAsync → печатает 4
6. возвращаемся в Main → печатает 5
—
🎉 Окончательный вывод:
1
3
2
4
5
📝 Что проверяет задача:
- Понимание работы async/await
- Как работают точки приостановки (suspension points)
- Когда код возвращается в вызывающий метод
#CSharp #AsyncAwait #InterviewQuestion #CodeChallenge
@csharp_ci
$ErrorActionPreference = "Stop"
$rootFolder = Resolve-Path -Path "."
$oldName = "Sample.Foo"
$newName = "Sample.Bar"
# Rename files and folders
foreach ($item in Get-ChildItem -LiteralPath $rootFolder -Recurse | Sort-Object -Property FullName -Descending) {
$itemNewName = $item.Name.Replace($oldName, $newName)
if ($item.Name -ne $itemNewName) {
Rename-Item -LiteralPath $item.FullName -NewName $itemNewName
}
}
# Replace content in files
foreach ($item in Get-ChildItem -LiteralPath $rootFolder -Recurse -Include "*.cmd", "*.cs", "*.csproj", "*.json", "*.md", "*.proj", "*.props", "*.ps1", "*.sln", "*.slnx", "*.targets", "*.txt", "*.vb", "*.vbproj", "*.xaml", "*.xml", "*.xproj", "*.yml", "*.yaml") {
$content = Get-Content -LiteralPath $item.FullName
if ($content) {
$newContent = $content.Replace($oldName, $newName)
Set-Content -LiteralPath $item.FullName -Value $newContent
}
}
@csharp_ci
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var funcs = new List<Func<int>>();
// Первая группа лямбд
for (int i = 0; i < 4; i++)
{
funcs.Add(() => i * i);
}
Console.Write("Squares: ");
foreach (var f in funcs)
Console.Write(f() + " ");
Console.WriteLine();
// Вторая группа лямбд с копией переменной
funcs.Clear();
for (int i = 0; i < 4; i++)
{
int j = i;
funcs.Add(() => j * j);
}
Console.Write("SquaresWithCopy: ");
foreach (var f in funcs)
Console.Write(f() + " ");
}
}
Ответ:
Squares: 16 16 16 16
SquaresWithCopy: 0 1 4 9
Объяснение
Первая группа лямбд
Лямбды захватывают переменную i по ссылке. К моменту, когда мы их вызываем в foreach, цикл уже завершился, поэтому i == 4. Каждая лямбда вычисляет 4 * 4 → 16.
Вторая группа лямбд
Внутри цикла для каждого значения i создаётся новая локальная переменная j, и лямбда захватывает именно её. При первой итерации j = 0, при второй j = 1 и т. д. Поэтому j * j даёт 0, 1, 4, 9 соответственно.
Такой приём (захват локальной копии переменной) позволяет избежать «одинообразного» результата и сохранить значение каждой итерации.
متاح الآن! بحث تيليغرام 2025 — أهم رؤى العام 
