We are all aware that null values can be dangerous, if not handled properly. Dereferencing a null-valued variable (i.e. calling a method on it or accessing one of its properties) will result in a NullReferenceException, as demonstrated with the following sample code:
就安全的角度,好像我們要不停的檢查 reference type 是不是 null , 雖然這件事常常發生,好像也很難說成是非預期的行為了… (譯注:又有種中槍的感覺)
To be on the safer side, we should always make sure that reference type values are not null before dereferencing them. Failing to do so could result in an unhandled exception in a specific edge case. Although such a mistake occasionally happens to everyone, we could hardly call it unexpected behavior.
Is it possible to distinguish between a nullable and a non-nullable value type using reflection?
The answer is No.
The same type will be returned for both variables in the above code: System.Int32. This does not mean that reflection has no representation for Nullable, though.
1 2 3
Type intType = typeof(int); Type nullableIntType = typeof(Nullable<int>); bool areTypesEqual = intType == nullableIntType;
上面兩段程式在 runtime 拿到的 type 很不一樣喔, 一個是System.Int32一個是 System.Nullable'1\[System.Int32\]
當 null 遇上多載方法 (Handling Null values in Overloaded methods)
bits 跑到底並不會重頭開始喔,一直移位到爆掉就變 0 了. (這裡會用 32 是因為 int 是 32bit 的數值,你可以試試放超過 32 的數值到 for loop 裡會發生什麼事)
The bits don’t wrap around when they reach the end. That’s why the result of the second expression is 0. The same would happen if we shifted the bit far enough to the left (32 bits because integer is a 32-bit number):
1 2 3 4 5
var shifted = 0b1; for (int i = 0; i < 32; i++) { shifted = shifted << 1; }
However, the bit shifting operators have a second operand. Instead of shifting to the left by 1 bit 32 times, we can shift left by 32 bits and get the same result.
1
var shifted = 0b1 << 32;
Right? Wrong.
The result of this expression will be 1. Why?
Because that’s how the operator is defined. Before applying the operation, the second operand will be normalized to the bit length of the first operand with the modulo operation, i.e. by calculating the remainder of dividing the second operand by the bit length of the first operand.
The first operand in the example we just saw was a 32-bit number, hence: 32 % 32 = 0. Our number will be shifted left by 0 bits. That’s not the same as shifting it left by 1 bit 32 times.
No. The result will be 2 again. By default, the midpoint value will be rounded to the nearest even value. You could provide the second argument to the method to request such behavior explicitly:
1
var rounded = Math.Round(2.5, MidpointRounding.ToEven);
這個行為可以透過MidpointRounding參數改變
1
var rounded = Math.Round(2.5, MidpointRounding.AwayFromZero);
try { var failedInstance = new FailingClass(); } catch (TypeInitializationException) { } Config.ThrowException = false; var instance = new FailingClass();
The static constructor for a class is only called once. If it throws an exception, then this exception will be rethrown whenever you want to create an instance or access the class in any other way.
The class becomes effectively unusable until the process (or the application domain) is restarted. Yes, having even a minuscule chance that the static constructor will throw an exception, is a very bad idea.
var instance = new DerivedClass(); var result = instance.Method(); // -> Method in DerivedClass result = ((BaseClass)instance).Method(); // -> Method in BaseClass // The correct answer is: by using the new modifier.
publicclassBaseClass { publicvirtualstringMethod() { return"Method in BaseClass "; } }
It’s typically used to hide the interface methods from the consumers of the class implementing it, unless they cast the instance to that interface. But it works just as well if we want to have two different implementations of a method inside a single class. It’s difficult to think of a good reason for doing it, though.
var instance = new DerivedClass(); var result = instance.Method(); // -> Method in DerivedClass result = ((IInterface)instance).Method(); // -> Method belonging to IInterface It’s explicitinterfaceimplementation.
publicinterfaceIInterface { stringMethod(); }
publicclassDerivedClass : IInterface { publicstringMethod() { return"Method in DerivedClass"; }
string IInterface.Method() { return"Method belonging to IInterface"; } }
var log = new StringBuilder(); foreach (var number inGetEnumerable(log)) { log.AppendLine($"{number}"); }
不是的, 實際上印出的是
Context created Context disposed 1 2 3 4 5
這點很重要, 因為實務上你很有可能 using dbconnetion 之類的物件, 那麼你在取得真正的資料之前, 你的連線就已經中斷了
This means that in our real world database example, the code would fail – the connection would be closed before the values could be read from the database.
var log = new StringBuilder(); var enumerable = GetCustomEnumerable(log); for (int i = 1; i <= 2; i++) { log.AppendLine($"enumeration #{i}"); foreach (var number in enumerable) { log.AppendLine($"{number}"); } }
enumeration #1 before 1 1 before 2 2 before 3 3 before 4 4 before 5 5 before end enumeration #2 before 1 1 before 2 2 before 3 3 before 4 4 before 5 5 before end
var log = new StringBuilder(); var enumerable = GetCustomEnumerable(log).ToList(); for (int i = 1; i <= 2; i++) { log.AppendLine($"enumeration #{i}"); foreach (var number in enumerable) { log.AppendLine($"{number}"); } }
輸出結果
before 1 before 2 before 3 before 4 before 5 before end enumeration #1 1 2 3 4 5 enumeration #2 1 2 3 4 5
2. 建立 IAM User 與指定 Group 權限 AWS IAM 的權限觀念是透過 User 與 Group 來組合的, 權限是授與 Group , 而 User 隸屬於 Group 便擁有其權限, 同時 AWS 提供多組(347 組)預設的 Policies, 讓人選擇 當然也可以建立自已的 Policy. *不確定有沒有反向的 Policy , 如果有當不同的 Group Policy 有衝突時該如何處理。
建立使用者時, 使用 AutoGenerated Password 時 要記得取得 password 在最後一步會按下 Show 就會顯示 3. 設定 AWS Account ID 與 Alias
Q & A
如何禁用 Root user 登入 ? 可以停用而不刪除一個 user account 嗎?
1 2 3 4 5 6 7
root account 無法停用 IAM User 可以透過 disable passwd 方式停用 root account 基本的 practice 1. 啟用 MFA 2. 移除 Access Credential 概念就跟 Windows Administrator or Linux root 一樣 需要時再用
滾動部署策略是指通過逐個替換應用的所有例項, 來緩慢釋出應用的一個新版本。 通常過程如下: 在負載排程後有個版本 A 的應用例項池, 一個版本 B 的例項部署成功,可以響應請求時, 該例項被加入到池中。 然後版本 A 的一個例項從池中刪除並下線。 考慮到滾動部署依賴於系統, 可以調整如下引數來增加部署時間:
並行數,最大批量執行數:同時釋出例項的數目
最大峰值:考慮到當前例項數,例項可以加入的數目
最大不可用數:在滾動更新過程中不可用的例項數
優點:
便於設定
版本在例項間緩慢釋出
對於能夠處理資料重平衡的有狀態應用非常方便
缺點:
釋出/回滾耗時
支援多個 API 很困難
無法控制流量
藍綠部署
藍綠部署策略與滾動部署不同, 版本 B(綠)同等數量的被並排部署在版本 A(藍)旁邊。 當新版本滿足上線條件的測試後, 流量在負載均衡層從版本 A 切換到版本 B。
[Route("Member/Get/{Id}")] public JsonResult GetMemberList(long Id, string cc = "f") { var cleanCache = false; //// logics here if (this.IsFromCompany() && cc == "t") { //// do something ... }
try { var memberList = this.memberService.GetMemberList(Id, cleanCache); //// logics here if (memberList.Any()) { //// do something ... } else { //// do something ... }
returnthis.Json(result, JsonRequestBehavior.AllowGet); } catch (Exception ex) { //// logics here //// do something ... } }
public ActionResult Index() { returnthis.Service.GetIndex(); }
Q3 當 Service 只有取資料的邏輯
No Logics in Service
1 2 3 4
public Member Get(long id) { returnthis.DataAccessor.GetMember(id); }
Q3.自問自答
我認為不要, 要測試商業邏輯,不要在意覆蓋率
Q4. 當 Service 只有取 Catch 資料的邏輯
No Logics in Service , just call another service
1 2 3 4 5 6 7 8 9 10 11
public Member Get(long id) { var enableCache = true; var result = this.CacheService.GetCacheData( cacheKey, () => { returnthis.DataAccessor.GetMember(id); }, enableCache ); }
public Member Get(long id) { var enableCache = true; var result = this.CacheService.GetCacheData( cacheKey, () => { //// logics here if(id > 9487) { returnthis.MemberAccessor.GetMember(id); }else { returnthis.MemberV2Accessor.GetMember(id); }
上略... using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions)) { using (Entities context = Entities.CreateNew(isReadOnly: true)) { //// logics here var query = from a in context.Activies.Valids() where a.Activies_StartDateTime <= startTime && a.Activies_EndDateTime >= now && a.Activies_ShopId == shopId && a.ActiviesCondition.Any(i => i.Activies_ValidFlag && TypeList.Contains(i.Activies_TypeDef)) select a; } }