2010年前的我的户外活动记录

  • 2010-06-19 西胡林-火村 西枫队
  • 2009-08-29 黄安坨 - 百花山 坐隐队
  • 2006-06-23晚-06-25午 龙聚山庄-后河-泉水营地-古城河-三叉-泉水营地-龙聚山庄 领队
  • 2006-06-09晚-06-11晚 龙聚山庄-苏家河-五里坡-三叉河-苏家河-龙聚山庄 领队
  • 2005-08-12-08-14 后河-古城河-五里坡-三叉河-后河
  • 2005-07-24 刘家峪-黄草梁-柏峪 一日
  • 2005-07-17 箭扣一日
  • 2005-05-27-29 后河二日(拣垃圾) 领队
  • 20050521-22 黄安陀-百花山-百花草甸-百花林场两日 领队
  • 20050109 龙聚山庄-后河-三岔-龙庆峡 一日 领队
  • 20041106 水闸-绝石梁-圈门一日(九龙山)
  • 20040925 威海 戚家夼-石门-仙姑顶-望岛村 一日穿越 领队 1.0级
  • 20040922 威海 戚家夼-石门-通讯站-潍坊路 半日探路 领队1.0级
  • 20040912 威海 菊花顶-古陌岭-远遥村 半日穿越 领队 1.0级
  • 20040908 威海 菊花顶-古陌岭-远遥村 独行半日探路 1.0级
  • 20040815 马栏-老龙窝-煤窝一日探路 2.0组 领队
  • 20040731-0801 后龙庆峡一日一夜 领队 1.5级 领队
  • 20040725 香山邮局->快活林->香山水库->挂甲塔->打鹰洼->四棵树->植物园->香山停车场一日穿越 1.0级 领队
  • 20040718 西大庄科-小海坨-大海坨-大海陀村一日 2.0级 领队
  • 20040711 九龙山-绝石梁-峰口庵-王平村 1.5级 领队
  • 20040702-0704 蒸汽机游游队 北京-延庆-龙聚山庄-后河-玉渡山-次仲泉-大海陀(未登顶)-小海陀-松山-延庆-北京 2.5+级
  • 20040618-0620 摩西队 北京-龙聚山庄-后河-古城河-五里坡-古城河-三岔河-龙庆峡-三岔河-后河-龙聚山庄 负重后龙庆峡探路穿越 2.0级
  • 20040612-13 变色龙yuci队 黄安陀-百花山-百花山停车场两日 2.0级
  • 20040605晚-20040606 私下带队 北京-龙聚山庄-后河-古城河-三岔河-后河-龙聚山庄 负重后龙庆峡一日穿越 2.0级
  • 20040530 私下带队 北京-龙聚山庄-后河-古城河-三岔河-后河-龙聚山庄 后龙庆峡一日穿越 2.0级
  • 20040523 西枫队 圈门-峰口庵-龙潭 一日 1.0
  • 20040522 漂流队 柏峪-黄草梁-北灵山-灵山停车场一日 2.0级
  • 20040515-0516 咕咚队雨中密云小水峪-牛盆峪穿越(雨大林密,未完成,中途折返) 1.7级
  • 20040502-0503 泰安药乡国家森林公园
  • 20040501 自驾车北京-济南->泰安
  • 20040417 变色龙队玉皇庙-无名山1-无名山2..-无名山N-连理石-妙境林场-北港沟一日疯狂抱石穿棘探路 2.0级
  • 20040411 yuci队 玉皇庙-清水尖一日F·B探路(探路未完成) 1.0级
  • 20040404 小榄队 涧沟村-庙洼-阳台山-大风口-凤凰岭-飞来石-减肥路-天梯-神泉-龙泉寺 一日穿越 2.0级
  • 20040328 小榄队 柏峪-黄草梁-留言壁-实心楼-落叶谷-椴木沟-灵山停车场一日穿越 1.5级
  • 20040321 yuci变色龙队 柏峪-十里坪-腊子口-象鼻山 一日FB 1.2级
  • 20031002 航天桥-月陀岛自驾车一日游(非绿野)
  • 20020915 高崖口-妙峰山 一日穿越(非绿野)

网友语录 - 第13期 - 人类之所以进步,是因为下一代不听上一代的话

安子 尽量多发现身边那些笑点很低,很容易满足,无论何时看起来都是喜洋洋的人,并且尽量多的跟他们在一起,你会感觉到被滋养,被激发,被启迪。它们像炭火一样煲养你的生命,给你力量,带来喜悦,他们是真正的人间天使。(更重要的,只要你贴他们足够近,他们还有能力把你转化成他们的同类)


碧螺姑娘 突然间真实感受到了“人生是旷野”的具体意义。虽然风刀霜剑严相催,但就是要热热闹闹地去活着。


奧匈帝國小説家弗朗茨·卡夫卡(Franz Kafka)寫過一則微型小説叫《法律門前》。小説講的是:有個鄉下人走到一處敞開的大門前,但是看門人不讓他進去。鄉下人問,那他以後可不可以進去呢?看門人跟他説,以後有可能,但是現在不行。看門人還暗示他說,如果他實在想進去,可以試一試,不過裏面還有更多看門人守著其他大門,這些看門人一個比一個難纏。後來這個鄉下人就在這個大門前等了一輩子,就等有機會允許他進去。等到自己快要死的時候,鄉下人問:爲什麽一直沒有其他人要求進這個大門?看門人跟他說:因爲這個大門就是專門給你一個人開的,等你死了,大門就會關起來。


人生若梦为欢几何 有句话说的很好,你把生活当游戏,把周围所有的人当npc,就不会内耗了。


CarrieZ 人类之所以进步,是因为下一代不听上一代的话


…more

Implementing QuickFix/n Logging with NLog

Wen working with QuickFix/n ibrary , efficient logging is crucial for troubleshooting. Here's how to implement a custom logging solution that routes QuickFix logs through NLog to your ELK stack.

Key Components

  1. NLogAdapter: A custom adapter that implements QuickFix's ILog interface:
public class NLogAdapter(ILogger logger) : ILog
{
    private const string HeartbeatPattern = @"\x0135=0\x01";
    private static readonly Regex HeartbeatRegex = new(HeartbeatPattern, RegexOptions.Compiled);

    private static bool IsHeartBeat(string message) => HeartbeatRegex.IsMatch(message);

    public void OnIncoming(string message)
    {
        if (!IsHeartBeat(message))
        {
            logger.Info("Incoming: {Message}", message);
        }
    }
    // ... other implementations
}
  1. NLogQuickFixLogFactory: A factory class to create log instances:
public class NLogQuickFixLogFactory(ILog logger) : ILogFactory
{
    public ILog Create(SessionID sessionId) => logger;
    public ILog CreateNonSessionLog() => logger;
}

Implementation Steps

  1. Register Dependencies in your DI container:
builder.Services.AddSingleton<NLog.ILogger>(_ => LogManager.GetCurrentClassLogger());
builder.Services.AddSingleton<ILog, NLogAdapter>();
builder.Services.AddSingleton<ILogFactory, NLogQuickFixLogFactory>();
  1. Configure QuickFix to use the custom logger:
var initiator = new SocketInitiator(
    clientApp,
    storeFactory,
    sessionSettings,
    new NLogQuickFixLogFactory(quickfixLogger)  // Use custom logger injeted by ILog here 
);

Key Features

  • Heartbeat Filtering: Reduces log noise by filtering out FIX heartbeat messages
  • Structured Logging: Uses NLog's structured logging format for better parsing in ELK
  • Separation of Concerns: Cleanly separates QuickFix logging from application logging

Benefits

  1. Centralized logging in ELK stack
  2. Better debugging apabilities
  3. Reduced log volume through heartbeat filtering
  4. Consistent logging format across your application

Common NUnit `Assert` statements

Here’s a consolidated list of common NUnit Assert statements, categorized by their purpose. This should cover most of the common scenarios:


Basic Assertions

  • Equality:

    Assert.That(actual, Is.EqualTo(expected));
    Assert.That(actual, Is.Not.EqualTo(expected));
    
  • Boolean Conditions:

    Assert.That(condition, Is.True);
    Assert.That(condition, Is.False);
    
  • Null Checks:

    Assert.That(obj, Is.Null);
    Assert.That(obj, Is.Not.Null);
    

String Assertions

  • Contains:

    Assert.That(actualString, Does.Contain(substring));
    
  • Starts With / Ends With:

    Assert.That(actualString, Does.StartWith(prefix));
    Assert.That(actualString, Does.EndWith(suffix));
    
  • Empty or Not Empty:

    Assert.That(actualString, Is.Empty);
    Assert.That(actualString, Is.Not.Empty);
    
  • Matches Regex:

    Assert.That(actualString, Does.Match(regexPattern));
    

Collection Assertions

  • Contains Item:

    Assert.That(collection, Does.Contain(item));
    
  • Has Specific Count:

    Assert.That(collection, Has.Count.EqualTo(expectedCount));
    
  • Empty or Not Empty:

    Assert.That(collection, Is.Empty);
    Assert.That(collection, Is.Not.Empty);
    
  • Unique Items:

    Assert.That(collection, Is.Unique);
    

Numeric Assertions

  • Greater Than / Less Than:

    Assert.That(actual, Is.GreaterThan(expected));
    Assert.That(actual, Is.LessThan(expected));
    
  • Greater Than or Equal / Less Than or Equal:

    Assert.That(actual, Is.GreaterThanOrEqualTo(expected));
    Assert.That(actual, Is.LessThanOrEqualTo(expected));
    
  • In Range:

    Assert.That(actual, Is.InRange(lower, upper));
    

Type Assertions

  • Instance of Type:

    Assert.That(obj, Is.TypeOf<ExpectedType>());
    Assert.That(obj, Is.InstanceOf<ExpectedType>());
    
  • Assignable From:

    Assert.That(obj, Is.AssignableTo<ExpectedType>());
    

Exception Assertions

  • Throws Exception:

    Assert.Throws<ExpectedExceptionType>(() => { methodCall(); });
    
  • Throws Specific Exception with Condition:

    var ex = Assert.Throws<ExpectedExceptionType>(() => { methodCall(); });
    Assert.That(ex.Message, Does.Contain("expected message"));
    

Miscellaneous

  • Same Instance:

    Assert.That(actual, Is.SameAs(expected));
    Assert.That(actual, Is.Not.SameAs(expected));
    
  • Applies a Condition:

    Assert.That(collection, Has.Some.Matches<ExpectedType>(item => item.Condition));
    
  • Delayed Constraints (Asynchronous):

    Assert.That(() => condition, Is.True.After(500).PollEvery(50));
    
  • Group related assertions together to improve readability and reporting:

    Assert.Multiple(() =>
    {
        Assert.That(okResult, Is.Not.Null, "okResult should not be null");
        Assert.That(okResult.Value, Is.TypeOf<string>(), "Value should be of type string");
    });
    

= null! vs. = string.Empty: Best Practices for Model Class Initialization

The choice between = null! and = string.Empty depends on the context and the intent of the code. Here's a breakdown to help you decide:


= null!

When to Use:

  1. You Intend to Initialize the Field Later:

    • Use = null! when the property or field is expected to be set by a constructor, a method, or dependency injection after the object is created.

    • Example:

      public string Name { get; set; } = null!;
      
    • Why: null! tells the compiler to trust you that the value will be assigned before being accessed.

  2. Avoid Premature Default Values:

    • If a default value like string.Empty doesn't make sense for the context, null! keeps the intent clearer.
  3. For Models or Data Contracts:

    • In cases where fields are expected to match a schema or be deserialized from external sources, it might be better to indicate "unknown until set."

    • Example:

      public string Username { get; set; } = null!; // Will be deserialized later
      

= string.Empty

When to Use:

  1. Default Values Are Meaningful:

    • Use = string.Empty when an empty string is a valid and reasonable default.

    • Example:

      public string Name { get; set; } = string.Empty;
      
    • Why: This avoids null-checking or potential runtime errors when accessing the property.

  2. Simpler to Work With:

    • If the field/property is commonly accessed and null is not a meaningful value in your application, an empty string simplifies the logic (avoids extra null-checks).
  3. UI or Display-Friendly Fields:

    • For fields used in UI contexts, empty strings often make more sense than null:

      public string Description { get; set; } = string.Empty;
      

Key Differences

Aspect = null! = string.Empty
Purpose Indicates value will be set later. Provides an immediate, valid default.
Compiler Warnings Suppresses nullability warnings (unsafe). Avoids nullability warnings entirely.
Clarity Explicitly states "not initialized yet". Implies "initialized to empty value now".
Best Fit Models, external contracts, DI patterns. Readily usable properties or fields.

When to Avoid = null!

  • When it's unclear who or what will initialize the property.
  • When using null might lead to accidental runtime errors.
  • When the property will be frequently accessed before initialization.

Recommendation

  • Use = string.Empty when empty strings make sense as defaults and simplify code.
  • Use = null! when initialization will occur later, and null isn't a valid or meaningful runtime value.

You know who is the real author of this article, don't you? :P