Friday, October 2, 2015

SQL Caching and availability

Data Copy
Log shipping
Data Mirroring
Always on group sql 2012

Seamless failover is only possible in  Always on group sql 2012.

Load Balancing:
no out of box solution for SQL DB load balancing which is transparent to application.

two strategies:
try to share sql request across servers
try to code functionalities to use different servers - which uses different set of tables.

https://www.youtube.com/watch?v=A8lSl8nO1r4


Saturday, March 22, 2014

General - 2013

  • 3Tier vs 3 Layer:
    • Tier is physical separation of components and Layer is logical separation.
    • Application UI - First Tier, web services/ business logic - Sec Tier / Database - third tier.Three tiers are linear UI-BUS-DAL while MVC is triangular UI - controller and UI-Model and Controller- Model. Generally MVC is part of UI for larger systems.
  • Repository Pattern:Prepare business entities in DAL (Repository) so business layer is independent of any data related information and has to deal only with strong type entities.
  • Code Smell:In computer programming, code smell is any symptom in the source code of a program that possibly indicates a deeper problem. Code smells are usually not bugs—they are not technically incorrect and don't currently prevent the program from functioning. Instead, they indicate weaknesses in design that may be slowing down development or increasing the risk of bugs or failures in the future
  • Anti Pattern:Very common practice which is being used to solve a  common problem but instead of solving it's causing more problems.  Such as: God Objects - Multi purpose object.
  • Anonymous Functions:
    • An anonymous function is an "inline" statement or expression that can be used wherever a delegate type is expected. You can use it to initialize a named delegate or pass it instead of a named delegate type as a method parameter 
  • A lambda expression is an anonymous function that you can use to create delegates or expression tree types. using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls.very helpful in writing LINQ queries.
    • (int x, string s) => s.Length > x () => SomeMethod()
    • if you are creating expression trees that will be consumed in another domain, such as SQL Server, you should not use method calls in lambda expressions. The methods will have no meaning outside the context of the .NET common language runtime.
                delegate void TestDelegate(string s); //1.0 syntax. - Named Method
               TestDelegate   testDelA = new TestDelegate(M);
               TestDelegate    testDelB = delegate(string s) { Console.WriteLine(s); };                              //Anonymous Method
               TestDelegate    testDelC = (x) => { Console.WriteLine(x); }; //Lambda                           expression

  • Expression Trees:
    • Expression trees represent code in a tree-like data structure, where each node is an expression, for example, a method call or a binary operation such as x < y.
    • Used for dynamic modification of executable code, the execution of LINQ queries in various databases, and the creation of dynamic queries
    • Expression trees are also used in the dynamic language runtime (DLR) to provide interoperability between dynamic languages and the .NET Framework and to enable compiler writers to emit expression trees instead of Microsoft intermediate language (MSIL).

Can be created by anonymous lambda expression, or manually by using the System.Linq.Expressions namespace.




SOA

SOA


  • Service is a program you interact via message exchange. Message is any kind of data that is sent to a Service. Microsoft laid out following four doctrines (MS says them as tenets):
  • Boundaries are Explicit
    • A service's boundary is published by means of WSDL and may include assertions dictating the expectations of a given service. So every thing should be declared explicitly in WSDL instead of relying on some implicit behaviors.
    • Services have explicit boundaries and are assumed to be expensive to traverse in order to make it more understandable and expressive.
    • Location, Security and Execution factors define the service boundary. Changing location may change the network configuration and suddenly consumers can experience performance degradation without they changing anything.
    • Similarly changing security setting may breach any existing contract as systems are complex. Marshaling and casting of data could change by changing boundaries.
  • Services are Autonomous:
    • Application or any other consumer should not influence the way service is implemented. Complete de-coupling.
    • Service may gradually enhance its implementation, but it doesn't affect consumers by any means.
    • Services are not to be confused with application workflow or business process. Those might incorporate multiple services, but a service operates independently from other services.
    • Each service should be constructed to be able to stand alone with no external dependencies on other services.
  • Services share schema and contract, not class:
    • Information is passed by value. Not like pass objects and let them work in service boundary and control it from application (RPC Style).
    • To know what service you need to consume, you just need to know it's schema not the way it does.
  • Service compatibility is determined based on policy
General (Not specific to Microsoft def) Web Services Principles:  

  • Object Oriented , Service Oriented, Component base development - All based on the principle of "separation of concern" , This theory is based on the notion that it is beneficial to break down a large problem into a series of smaller, individual problems or concerns. This allows the logic required to solve the larger problem is now decomposed into a collection of smaller, related pieces. Each piece of logic addresses a specific concern. It's just that Service Oriented architecture implement this in a different way.
  • The most recent results establish the following eight principles:
    • services share a formal contract [CORE] - Boundaries are explicit.
    • services are loosely coupled [CORE] - Share contract not class.
    • services abstract underlying logic [CORE] - Policy
    • services are autonomous [CORE] - Autonomous.
    • services are reusable
    • services are discoverable
    • services are composable
    • services are stateless
    • Core principles directly enable the realization of the remaining principles.
  • 1.Service Contracts:  Service description document. 
    • In web services there are two technical description document which solves this purpose: WSDL definition and  XSD  Schema.Third type of document is also required that is Policy document.
    • Service description documents can be collectively viewed as establishing a service contract – a set of terms and conditions that must be met and accepted by a potential service requestor in order to enable successful communication and interaction. (Note that a service contract can also refer to additional non-technical documents or legal agreements, such as SLAs.) Within SOA, service contracts provide a formal definition of:
      • the service endpoint
      • each service operation
      • every input and output message supported by each operation
      • the data representation model of each message's contents
      • rules and characteristics of the service and its operations
    • Because this contract is shared amongst services, its design is extremely important. Service requestors that agree to this contract can become dependent on its definition. Therefore, contracts need to be carefully maintained and versioned after their initial release
    • This enables other principle such as abstraction, composability, discoverability and loose coupling.

  • 2.Loose coupling:
    • Being able to ultimately respond to unforeseen changes in Business or workflows in an efficient manner is a key goal of applying service-orientation. Realizing this form of agility is directly supported by establishing a loosely coupled relationship between services and between service and requestor.
    • Distributed architecture models are based on the fact that Small logics/concern can be composed together to automate a business task. One of the characteristics that distinguishes SOA from its predecessors is how these units of logic are required to relate to each other. Ideally they should not relate to each other and it called  decoupled or loosely coupled and it is accomplished by limiting the dependencies between a service and its requestors by the information expressed in the service contract – and –designing the service contract in such a way that it is not necessarily specific to any one service requestor.
    • When creating multiple services in pursuit of establishing a service-oriented enterprise, these services can be categorized into specific service models. This allows them to become specialized in the type of logic they encapsulate. One increasingly important service model is the business service, which limits the logic a service represents to the accurate expression of a specific business context. Or there are Infrastructure services.
  • 3.Abstraction:
    • it is this principle that encourages us to establish services as black boxes, intentionally hiding their underlying details from potential consumers.There is no limit to the amount of logic a service can represent. Services abstract not only lot of business logic but also specific vendor interfaces or lot of connectivity.
    • This puts a great deal of emphasis on the design of the service contract. The more that is expressed in the service contract, the less details we end up abstracting. The more generic we make the service contract, the less process or consumer-specific the service becomes. This then determines the reuse potential of what we choose to expose (to not abstract) through the service contract.
  • 4.Service Autonomous:
    • Since service are reusable components, over a period of time, the same service will need to facilitate the automation of different business processes or tasks and may become part of numerous service compositions. This eventuality translates into high usage volumes, unpredictable usage scenarios and a runtime condition such as concurrency. Service Autonomy and Stateless are design consideration which allow us to handle these scenarios.
    • Autonomy is each service should be a building block in the enterprise service inventory. So that each service can be part of one or many business automation process. i.e. any service can be moved to different business process stack without requiring to move many dependent services.
    • By increasing the amount of control a service has over its own execution environment, we reduce dependencies it may otherwise require on shared resources within the enterprise. Even though we cannot always provide a service with exclusive ownership of the logic it encapsulates, our primary concern is that it attains a reasonable level of control over whatever logic it represents at the time of its execution.
    • Service-level autonomy – Service boundaries are distinct from each other, but the service may still share underlying resources. For example, a wrapper service that encapsulates a legacy environment that also is used independently from the service has service-level autonomy. It governs the legacy system, but also shares resources with other legacy clients.
    • Pure autonomy – The underlying logic is under complete control and ownership of the service. This is typically the case when the logic is built from the ground up in support of the service. (COSTLY).
  • 5.Reusability:
    • Service-orientation encourages reuse in all services, regardless of whether immediate requirements for reuse exist. This fundamental principle forces us to pay extra attention to each delivered unit of automation logic we want to call a "service."
    • It reduces response time and cost of organization to any specific changes.
    • The emphasis on far reaching reuse also highlights the suitability of Web services as an implementation option for services. By making each service available via an industry standard communications framework (as available as wcf or dll or windows services), reuse potential can broaden dramatically because the logic encapsulated by a service now becomes accessible to service requestors built with different underlying technologies.
    • It is the content of this contract that determines what is and is not abstracted. It is through the design of this content that we can determine how generic and reusable the non-abstracted parts actually are. This raises the need to truly view the design of a service as an investment. Building service-oriented solution logic is almost always more expensive and more time consuming because considerations need to be taken into account that go beyond immediate tactical requirements.
  • 6.Service discoverability
    • Even the most reusable service is not useful if it cannot be found by those responsible for creating potential consumers. Furthermore, even the most loosely coupled services will have limited reuse potential if they cannot be assembled into effective compositions. This is where the principles of service discoverability and service composition come into play.
    • The characteristic of discoverability essentially helps avoid the accidental creation of redundant services or services that implement redundant logic.
    • There are two aspect of this, one is the technology which provide discover-ability such as Service Registry or Directory Other is service itself should be as discoverable as possible, regardless of weather a discoverability product exists in surrounding or not.
  • 7.Service Composition
    • Composability is simply another form of reuse and therefore operations need to be designed in a standardized manner (and with an appropriate level of granularity) to maximize composition opportunities.
  • 8.Service statelessness:
    • This principle states that services should minimize the amount of state information they manage, as well as the duration for which they remain stateful. In a service-oriented solution, state information usually represents data specific to a current service activity. While a service is processing a message, for example, it is temporarily stateful (Figure 2). If a service is responsible for retaining state for longer periods of time, its ability to remain available to other concurrent consumers will be impeded.
    • As with autonomy, statelessness is a preferred condition for services and one that promotes reusability and scalability.
  • Two main type of application in any enterprise:
    • Business Applications: Core business applications - generally developed inside.
    • Infrastructure Applications - These are generally 3rd party applications like outlook, word doc, timesheets..
    • Because SOA opens up the possibility of utilizing a packaged unit of functionality (service) in a location-independent way, the potential and push for having an “extended enterprise” are obvious.
    • Topographically, services can be either deployed on-premise or accessed from a remote source. Various models exist to categorize remotely accessible services, including 
      • Software as a Service (SaaS),
      • Cloud Computing, Cloudware, 
      • Platform as a Service (PaaS), and
      • Web-oriented architecture (WOA). 
    • Each of these can serve a somewhat different concern, but the common thread remains that none of them is deployed and managed by the service-consumer organization. Infrastructure availability, resource provisioning, and quality of the service become the service provider’s concerns
    • DSB addresses cross-enterprise service-collaboration scenarios. Organizations that attempt to implement such scenarios with a traditional Web services composition/enterprise service bus (ESB) approach are facing tremendous challenges when it comes to spanning business-process workflows across the enterprise boundaries. Firewalls, network-deployment DMZ zones, and software-product boundaries are some of the many obstacles that enterprise architects must overcome.
General:
  • Products: Indigo - Microsoft  / ?? - IBM
  • Alchemy is a Service-Oriented Architecture (SOA) for Web service management, developed for line-of-business use by Microsoft IT. Alchemy Web services were released in 2003, followed by the Alchemy Common Platform (ACP) in 2004. ACP is a protocol-agnostic framework for service development and management across the enterprise.

Tuesday, February 25, 2014

Summary - Jeff

NULLABLE VALUE TYPE:

  • Structure has two fields - value and bool hasValue (indicate if it's null).
  • Good use in LINQ to integrate with queries.
  • Java support null datetime, .Net doesn't so if Java is calling a web service with date time it can be null this can be handled by nullable type.
  • If the nullable type is null, Boxing doesn't happen CLR checks and just return Null.
  • Generally there is no memory allocation for Unboxing but if unboxing a value type into a nullable version CLR might have to allocate memory. it's because while boxing there is only value but for unboxing there is value + hasValue field.
  • GetType on nullable type get the actual value type as Int32 etc.
  • Casting from Nullable to IComparable works fine even though Nullable doesn't implement Icomparalbe but Int32 does, this is b'coz of special handling of CLR to nullable type.
  • Nullable == int32?.

CUSTOM ATTRIBUTES
  • Custom Attributes are instance of a type, derived from System.Attribute class.
  • All nonabstract attributes must contain at least one public constructor. but class can't offer any public method, events or other members.
  • Two important attributes are:
    • Target - where this attribute can be applied such as Enum
    • IsInherited - If the derive class of the class on which attribute is applied inherit the attribute behavior.
    • AllowMultiple - attribute can be applied multiple times, usually good for bit flag attribute for OR operator.
  • Attribute class whose constructor takes an array is not CLS compliant.
  • Important Methods:
    • IsDefined : efficient as doesn't construct object. Defined in System.Attribute and System.Reflection.
    • GetCustomAttributes : Defined in System.Attribute and system.Reflection. it desearilize and construct the array of attributes applied on type. System.Attribute method returns array of attribute while reflection return array of object.
    • GetCustomAttrubute: Define in system.attribute - return an instance of attribute class.
    • These method also checks derived attribute classes also so while defining your attribute class it's better to define it as Sealed.
  • Any time a attribute is returned by reflection a new instance is created so for comparison you might override System.Attribute.Match method as by default it simply calls Equal. So override - Match, Equals and GetHashCode for your attribute class to compare instances correctly. (basically comparing the fields in your attribute instance.)
  • Conditional attribute : When conditional attribute is applied on attribute class compiler will emit attribute information into metadata only when conditional symbol is defined in the code (#define TEST.... [Conditional("TEST")]) - good use in NUNIT as all nuint attributes are defined as conditional attributes so that test info is emitted when code is executed for nunit. this is done to avoid bloating meta data in prod run.
  • System.refleciton.CustomattributeDat. GetCustomAttributes - can be used to get attribute information without creating the instance of attribute class. Generally used to analyze CA when assembly is loaded using Assembly.reflectionOnlyLoad mthod.
GENERICS:
  • Generic Reference type, value type, Delegate type, interface type is allowed. Generic enumerated type is not allowed.
  • Advantages : Type safety, Reduce casting and boxing and this enhance performance.
  • For List and Arraylist of string performance is almost same but for generics code is cleaner.
  • Type with Generic type parameter is open type List and type with actual type is closed List. Instances of open type can't be created. Number are called Arity. list arity =1, dictionary arity = 2.
  • Each close type of same open type is treated as different type so if a type has static filed / constructor each close type will have it's own static field and const will exec separately.
  • Generics Identity : For simplicity use using instead of deriving from generic type as deriving will break the type identity. 
  • Code Explosion : For each method / Type combination diff native code should be generated - code explosion. But CLR does optimization to avoid this - for Each method/type combination native code is generated only once in appdomain. For all reference type code is generated only once (as ref type is just a pointer) but for value type code is generated for each value type. there will be code for List and List but native code is generated only once for List and List.
  • Type Inference : For clean and readability compiler tries to inference the type for calling a method. For ex 
    • Swap(ref T o1, ref T o2)
    • Ideal call - Swap(ref n1, ref n2) ; n1,n2 are int.
    • Inference call Swap(ref n1,ref n2). without
    • Swap(ref str, ref obj) - str ="1" -string and obj ="2" - object. Error - Type can't be inferred. B'coz for inference C# uses the variable's data type not the actual type of the object referred to by the variable.
  • Constraints:
    • Primary constraints : 0 or 1. special type - Class (not sealed) or struct. Nullable, object, array, delegate, enum etc is not allowed.
    • Secondary type : 0 or N.  represents an interface constraints. Other is type parameter constraints / Naked type constraints - define relationship between the types  where T:TBase.
    • Constructor constraints - 0-1. : constraint type is non abstract and offer public parameter less constructor.
  • Method can't be overloaded on type parameter names or constraints overload is allowed only on Arity.
  • When overriding a virtual generic method, overriding method must specify the same number of parameters and inherit the same constraints. can't add any constraints.
  • To set the default value of T use "default(T)". 
  • Using unconstrained T take care of what could be done as it could be value type or ref type etc. as if(o1==o2) gives error as o might be value type and all value type (defined struct) doesn't have == override all ref type though have by the virtue of being inherited from object.


DELEGATES:
  • Type safe call back mechanism.
  • Delegate d = new Delegate( callback method) : Delegate object is a wrapper around a method, allowing method to be called back indirectly via wrapper.
  • Private method of a class can be invoked using public Delegate wrapper. 
    • Public MyDelegate GetWrapper() { return new MyDelegate(private method);}
  • Delegate supports Covariance in return type and Contravariance in input parameter type. covariance and contravariance is supported only for ref type not for value type.
  • Delegate translates into a class which inherits from System.MulticastDelegate which in turn inherits from System.delegate, following methods are created for any defined delegate:
    • Constructor
    • Public virtual void Invoke (same signature as call back method)
    • BeginInvoke
    • EndInvoke
  • Methods of delegate class : Target - Instance of class, Method - call back method pointer and InvocationList - Array of delegates to invoke - Delegate chain.
  • += and -= are overload method for Delegate.Combine and Delegate.Remove which add/remove delegate to invocationlist array.
  • Array of delegates are invoked in loop - issue is the result of only last delegate/callback method can be retrieved and also if there is exception in executing one delegate all are impacted. To handle these scenario Delegate class provide GetInvocationList method which returns the array of delegates to be invoked to user and user can handle each invocation.
  • Delegate can also be created at run time using reflection information. System.delegate offers CreateDelegate method for this as:
    • Public static Delegate CreateDelegate(Type,MethodInfo) - both these parameters can be retrieved using reflection.
    • There are couple of other overloads for CreateDelegate mthod.
    • Create delegate return an instance of delegate class (d).
    • Delegate DynamicInvoke instance method allows to dynamically invoke delegates. d.DynamicInvoke(CallbackArgs).
INTERFACES:
  • Interfaces is a CAN DO relationship. Abstract is ISA relationship. Is a set of method.
  • Events / Properties / Indexers can be defined as these all translate to methods. Can't define an instance field as Interface can't be instantiated.
  • Though CLR does allowed static methods/fields/constants/constructor but C# doesn't allow any of these static members.
  • Interface is like a type so just like type it can be nested in another type and any visibility/accessibility can be set on interface.
  • C# compiler requires that all interface method must be marked public.
  • CRL requires that interface method must be marked as virtual.
    • If we don't mark interface method as virtual, compiler with mark the method as virtual and sealed, which means derived class can't override it (it's like non virtual) But derive class can re-inherit the same interface and provides it's own implementation (with new keyword).
    • If we explicitly marked interface method as virtual compiler doesn't mark it as sealed, which means derive class can override interface method.
    • When calling an interface method on an object, the implementation associated with the object's type is called.
    • Class Base : Idisposable { public void dispose ())} //implicit - Virtual sealed.
    • Class derive : Idisposalbe { new public void dispose()}
    • Base b = new derived(); b.dispose() // Base dispose as dispose is like non virtual called on type of variable.
    • Idisposable d = new derive(); - // Derive dispose.
  • Using variable on interface type all method of an interface + all method define by an System.object can be called.
  • Variable from one interface can be cast to another interface as long as the object implements both interfaces.
  • Value type can also implement interfaces. But using value type with interface variable requires boxing because interface variable is a reference that must point to an object on the heap.
  • EIMI - Explicit interface method implementaion : If a class explicitly implements an interface method (Idisposable.Dispose()...) than that method can be called only by interface variable and can't be called by type variable. 
    • C# doesn't allow to mark any accessibility on EIMI method as compiler marks them private to prevent calling it from class instance, can only be called from interface variable.
    • EIMI method can't be marked as virtaul as they are not actually part of type object model.
    • EIMI method should be avoided as much as possible. use of generic interface offer some help in avoiding EIMI.
  • Generic interface can be defined for compile time type safety. can be used for by value types to avoid boxing. 
  • A type can implement Generic interface multiple time each with different type .
  • Generics and interface constraints can be used to make sure that input type is implementing all constrains interface.
    • Public static void M(T t) where t : Icomparable, Iconvertible => that method M will accept only types that implements both Icomparable and Iconvertible.

ARRAYS:
but for DateTime[] darray type will implement only . This means darray could not be passed to M3 ( void M3(IEnumerable oenum) whiel farray could be.
  • System.Array : System.Object.
  • Jagged arrays - Arrays of arrays.
  • Memory is allocated when you create a new array with new keyword
  • Single-dimensional, zero-based arrays are also referred as SZ arrays or Vectors.
  • For value type array memory is allocated on managed heap which hold unboxed values of value type for ref type arrays memory hold the reference to actual ref type object.
  • Casting is allowed from one ref type array to other ref type array implicitly or explicitly but casting is not allowed for value type. object[] o = new int[10] - Error.
  • value type can be casted using Array.Copy method. Copy just not copy but also does boxing/unboxing and if required widening as required in casting from int to double. Also downcast ref type if direct casting is not compatible for ex object[] to IFormattable[]  if every object implements IFormatable.
  • Array.Copy - does the shallow copy so if the array elements are ref type the new array will refer to the already existing objects.
  • Type safety - All elements in an array are of same type it checks at run time. if an array of object is assigned string and then int then assignment of int will throw type mismatch error at run time. since int derive from object compiler allows assignment at compile time.
  • All arrays implements IEnumerable, IColleciton and IList (all non generic versions). Internally compiler implements Generic version of these interface. For ref type generic version of the type + all its base type is implemented for value type only generic version of value type is implemented. For FileStream[] farray - the type will implement all three interfaces for , and
  • Each array in Memory has array elements plus some overhead information like number of dimensions, lower bound of each dimension length of each dimension and element type.
  • Creating Non-Zero-Lower Bound arrays : System.Array.CreateInstance : Can create instance at run time it take array overhead parameters as input and allocates a memory on heap and return it's reference. This can be used to create non-zero bound arrays.
  • CLR does support non-zero bound array but their use is discouraged due to performance issue and language portability issues.
  • CLR does some optimization for zero bound arrays such as Length is checked and cached and index is checked before the loop to avoid these to be performed for each element access. These performance can also be acheived using unsafe array access but that's allowed only for some primitive type....?? Unsafe access avoid index bound checking.
  • Accessing Jagged array is more efficient than accessing Rectangular arrays (multi dimensional).
  • For performance critical app use stackalloc to allocate array on thread stack and use unsafe array access to access elements. stackalloc can be used only for vectors of value type and value type should not contain any reference type field.**

ENUMS
  • Use to define name value pair. Compiler treat it as primitive type.
  • System.Enum : System.ValueType : System.Object
  • Compiler convert enum type to a structure with each element as constant and one instance filed (but instance field can't be accessed). The constants fields are emitted to assembley's meta data and can be accessed via Reflection.
  • Since it's convert to constants it's turn out to be a compile time feature where ever it's used directly but if it's used in method like parsing etc then enum assembly is required at run time.
  • The underlying type for an enum could be byte,int,short,ushort,sbyte.
  • Enum doesn't offer any support for localization, so toString() can be used to format values.
  • If [Flags] is applied on Enum then each enumerated type represent a set of bits, some of which are on and some of which are off. Used to convert a numeric values into string of flags and vise versa. IsDefined will not work on Bit Flags enums because input comma separated values treated as single string which wouldn't match and input numeric value will also not matched with bits.

STRINGS:
  • System.Char - Value type a structure.
  • Letter casing is culture dependent while Comparison is not culture sensitive.
  • System.String : System.Object - Ref Type - Array of characters.
  • Can't create string object with new keyword unless using unsafe code. string s = new string("gauri") - Error. String have some constructor which takes char*/SByte* as input and return string object (unsafe though).
  • Strings are immutable once created can't be modified.  Which also means that there is no thread synchronization issues when manipulating or accessing a string.
  • string class is tightly integrated with CLR which has lot of optimization for string class that's why this class is sealed to make sure none of the optimization assumption CLR is making goes for a toss in derived classes.
  • String comparison has two param - Culture and Casing. Explicitly mention this for good programming. For programmatic strings (not to be shown on UI) use Ordinal comparison - StringComparison.Ordinal / StringComparison.OrdinalIgnoreCase (culture insensitive) that is fast.
    • Use ToUpper instead of ToLower as toupper is optimized by CLR.
    • CompareTo performs culture sensitive comparison while equals performs ordinal comparison.
    • In culture sensitive comparison different looking same characters will compared as equal. as German "B" and English "B" will be equal. Also string of different length can be considered equal.
    • System.StringComparer - Use If same type of comparison has to be performed repeatedly for many string .
  • String Interning : To avoid copying of same string and use the intern string instead, this will reduce the memory foot falls.
  • String Pooling : Many compilers including C# write the same literal string into module's metadata only once to avoid memory bloating.
  • StringBuilder:
    • Use to manipulate string efficiently.
    • MaxCapacity (int32.MaxValue), Capacity (default is 16) and Char Array are important properties of string builder.
    • If size of character array increases than capacity, string builder create new array with double of capacity - that hurts performance so keep the capacity large enough to hold required characters.
    • Equals method returns true if both StringBuilder objects have same max capacity, capacity and characters in array.
  • All base types built into FCL such as int,byte,double override toString method to return culturally aware string.
  • IFormatProvider : When a type implement this interface, it is saying that an instance of the type is able to provide culture specific formatting information and culture information associated with the calling thread should be ignored.
    • Numeric type also support picture format strings.
    • In FCL just three types implement IFormatProvider - CultureInfo, NumberFormatInfo and DateTimeFormatInfo.
  • Encodings : In .net all characters are represented as 16-bit Unicode values.
    • Transferring 16 bit values over network is not very efficient as half of the bytes written would contain zero.
    • Encoding is typically done when string is send to a file or network by using System.Io.BinaryWriter or System.IO.StreamWriter similarly decode is used while reading using BinaryReader and StreamReader.
    • UTF-16 : All char as 2Bytes, no compression so performance is excellent. Also known as Unicode encoding. Can covert little endian to big endian (little left number is smallest and vise versa).
    • UTF-8 : This default and it uses 1-4 bytes for diff chars. Extremely popular but less efficient than UTL-16.
    • ASCII encode : Encode 16 bit char into ASCII characters But all characters can't be converted to ASCII so those are lost.
  • FCL type also supports secure string which is mandated by some Gov transaction. System.Security.SecureString - using this object allocates unmanaged memory to keep it away from garbage collector, secure string is encrypted

C# Types
  • Default accessibility for a class is internal i.e visible to assembly. It's also possible to access  internal members of a assembly from other assembly, By marking other assembly as Friend assembly. Friend is declared by decorating it with attribute [assebmly : InterVisibileTo(Assembly name, public key token)]
  • For method default visibility is Private. Derive class overriding method must have the same visibility as base class method(C#) but CLR allowed less restrictive accessibility modifier for overriding methods.
  • Static classes are marked as Abstract and sealed by compilers.
  • CLR nothing knows about partial classes so they must be written into same programming language to compile them into single unit. two partial classes can't reside in different assemblies. Two classes in same assembly can't have different languages.
  • Readonly fields are written only within constructor method, other then this Reflection can be used to modify readonly fields.
  • Constants are like Static read only field with only difference is static read only get the value at Run time and it's less efficient than constants.
  • For reference type Readonly field only reference is immutable not the object it's referencing. so If read only field refer to Array, array values can be changed.
CONSTRUCTORS and METHODS:
  • Instance constructor and Static Constructors.
  • Instance Constructor for Ref Type:
    • Compiler generates a default parameter less constructor which calls the base constr.
    • Object can also be created without executing constr, using object.MemberwiseClone method which allocate memory and copies byte by byte.
    • Inline Initialization code for instance variable will be put in all constructors so it's better to define one initialization constr and call it from other constr.
  • Instance constructor for value type:
    • C# doesn't allow parameter less constr for value type. But CLR does.
    • Const need to call explicitly no compiler support for automatic calling.
    • Any defined constr should initialize all instance field else compile time error.
    • Inline initialization is not allowed as parameterless constr is not allowed.
  • Static Constructors / Type Initializers / Class constructor :
    • Can't be applied to Interfaces (C#) . CLR allow this.
    • Type cnstr is marked private by Compiler, can't mark private explicitly.
    • C# doesn't allow parameterized static constructor as it's private no use.
    • Can be define on Ref/Value type. Value type allows static parameterless constructor and inline initialization for static instance fields.
    • CLR make sure that it execute only once in appdomain and any type can't have more than one type constructor.
    • JIT emit the type constructor call in two ways : Precise semantics or before-field-init semantics (preferred). In before init constr is called some time before the code that is accessing the static field. before init is used when Inline initialization is done, precise is done when explicitly type constr is defined for field initialization.
  • Operator overload are feature of compiler and languages, CLR doesn't know anything about operator overload for CLR it's just a method. method should be public and static. 
    • public static Complex Operator+(Complex c1, Complex c2) - this translate into op_Addition(Complex c2, Complex c2)
    • Core FCL type int etc, don't define any operator overload method as overloading will cause runtime performance hit, because for these primitive type compiler put appropriate IL instructions.
    • If a language doesn't support operator overloading it must provide op+* methods directly for interoperability (such as op_Addition)
  • Conversion Operator Method:
    • For converting one type to other the source type can offer constructor, ToXXX methods or conversion operator. For casting a int type from Rational type.
    • public Rational(int32 num){} - Constructor.
    • public int32 ToInt32(){return new int(...)} - Method. 
    • public static Implicit Operator Rational(int32 num) { return new Rational(num) }  - To allow implicit conversion from int to rational. Rational r1 = 5;
    • public static explicit operator Int32(Rational r) { return r.toInt32();} - To allow explicit casting. Int32 i = (Int32) r1;
    • op_Implicit / op_Explicit.
  • By default CLR assumes that all method parameters are passed by value.
  • Passing value type as ref, changed value in caller will be available to callee while if passed as val changed value will not be available to callee.
  • Passing ref type as ref, will pass the pointer as ref type so if pointer is change to point new object callee will get this new object. if ref type is passed by value and pointer is changed to point to new object callee object will not change but any changes in the actual object will be available to callee in both ref/val for ref type.
  • ex : http://msdn.microsoft.com/en-us/library/s6938f28.aspx
  • Properties:
    • Simplified way of calling a method. Fields are objects's state.
    • OOPs - type's field should never be publicly exposed as it breaks data encapsulation principle as caller can modify the field in any way.
    • Define properties for data encapsulation, properties are get and set method which should modify the type fields. These fields should be parked as private. these fields are commonly referred as backing fields. 
    • Properties can't be overloaded.
    • Properties vs Fields : read/write, can throw exception, can't passed as ref or out param to a method, should not be used if thread synchronization is required, should not be used in remote objects (implementing MarshalByRefObjects) as it's very slow in marshaling, can return diff value on each call (dateTime.Now - now is property).
    • Parameter properties are called indexers. 
      • C# doesn't allow static indexers.
      • C# uses this[..] syntax to access indexers. Developer can't name the indexers. default compiler generate is get_item/set_item.
      • Developer can choose to rename this default _item name by decorating it with [Indexername] attribute (say "Bit", name would be get_Bit/set_Bit).
      • Indexers can be overloaded as long as they have diff number of parameters.
    • Property itself be marked with less restrictive accessibility than any one on the accessor methods. property - Public and either get or set can be Protected.
PRIMITIVE, REFERENCE AND VALUE TYPE:
  • Any data type which has direct support of compilers are called Primitive type.
  • string - primitive type which is mapped to System.String FCL type there is no difference in using them.
  • For primitive type does the casting implicitly or explicitly even for different data type (int32 and int64). C# allows implicit casting when conversion is safe and no data loss is possible.
  • Overflow exception : while casting if overflow checked is enabled it throws exception else casting is done with loss of value. by default C# overflow is not checked so no exception. keyword is checked/unchecked. Checked((BYte) 100+200) or code block can also be created - checked {....}.
  • System.Decimal type is considered as primitive type by C# but not by CLR so CLR doesn't have IL instruction to know how to manipulate decimal type, so manipulating decimal type is slower and checked/unchecked operators and compiler switches have no effect. that's why operation on decimal always throw overflowexception if the operation can't be performed safely.
  • When a type offers no member to alter it's fields we say the type is immutable. 
  • Value type : 
    • Value type is either structure or enum.
    • System.Enum(abs) : System.ValueType (abs) : System.Object.
    • All value types are sealed.
    • Use value type if you don't need inheritance, it's immutable, size is small because by default arguments are passed by value, which causes fields in these value type to be copied on caller stack similarly for return type if it's value it's again get copied.
    • Value type can exists in two form - Boxed and Unboxed.
    • Each value type overwrites Equals and GetHashcode method to return true if value is equal and include value in hash code.
    • Assigning a value type variable to another variable, a field by field copy is made.
    • Unboxed value type are allocated on stack and get's cleared as soon as method defining them get inactive => value type instance don't receive notification when it's memory is reclaimed.
    • C# doesn't allow finalize method in value type.
  • Boxing : Reference to an instance of value type. - Memory allocation, values are copied to memory and address of memory is returned.
  • Unboxing : Getting the address of the field of value type object. 
    • Unboxing is less costly as it just get the address and unlike boxing it doesn't involve the copying of any bytes in memory.But unboxing is always followed by field copy as caller reads the boxed values after getting the address.
  • All objects on heap has two overhead fields - type object pointer and sync block index. Since unbox value on stack doesn't have sync block index - synchronization is not required for multi-threaded application.
  • Since value types are sealed, CLR calls value type virtual methods non virtually. Equals, GetHashCode and ToString virtual methods of object are overridden in value types and are called non virtually by passing unboxed ref of value type in "this" argument. But some non virtual methods GetType and MembwiseClone are defined in object and so expect "this" argument as ref to boxed value type. so when these methods are called, boxing happens.
  • Object Equality and Identity:
    • Identity - Two references point to same object. 
    • Equal is a virtual method in object class and it's default implementation is to check identity.
    • Since Equal can be overridden, it should not be used to check identity equality, for identity check use Object.ReferenceEquals static method.
    • Overriding Equals logic : x.Equals(obj)
      • If Obj is null - return false.
      • if this and obj refer to object of different type - return false.
      • Compare each field to check equality and call base.Equals to let base class also checks it fields for equality.
    • System.Valuetype overrides Equals method with same logic but don't call base(object's) equal method. For comparing it uses reflection so for custom value type it's always good to override equal and write logic to compare values and avoid reflection for that (don't call base.equals else it will go to reflection again.
    • Also a type can implemetn System.IEquatable interface equals method.
    • Also overload operators == and != to call type safe overridden equals method.
    • If your type is being used in comparison such as in sorting - implement IComparable CompareTo method and also provide overload for different comparison operators liek <, >, >= etc.
    • If you are overriding Equals, you also need to override GetHashCode virtual method of System.Object. (if not compile will issue warning....). This is mandatory because Hashtable and Dictionary required that two objects that are equal must have the same hash code.
    • System.Object.GetHashCode return an unique identity for an object in the appdomain. after object is garbage collected that identity can be reused. If GetHashCode is overridden,Unique identity for an object is not guaranteed so to get a object's unique identity use System.RunTime.RunTimeHerper.GetHashCode.
    • Value type GetashCode uses reflection so it's slow.
  • Strong Assemblies are first looked into GAC and than in AppBase, weak assembly are first looked into AppBase. For strong assemblies CLR looks into AppBase only if no codeBase element is specified. codeBase element can also be used with weak assemblies. For weak assembly Private path can be used in publisher policy xml to probe the assembly.

Friday, November 29, 2013

.Net Collections



    he .NET Base Class Library (BCL) has a wide array of collection classes at your disposal which make it easy to manage collections of objects. While it's great to have so many classes available, it can be daunting to choose the right collection to use for any given situation. As hard as it may be, choosing the right collection can be absolutely key to the performance and maintainability of your application!

    The Generic Collections: System.Collections.Generic namespace
    The generic collections were introduced in .NET 2.0 in the System.Collections.Generic namespace. This is the main body of collections you should tend to focus on first, as they will tend to suit 99% of your needs right up front.

    It is important to note that the generic collections are unsynchronized. This decision was made for performance reasons because depending on how you are using the collections its completely possible that synchronization may not be required or may be needed on a higher level than simple method-level synchronization. Furthermore, concurrent read access (all writes done at beginning and never again) is always safe, but for concurrent mixed access you should either synchronize the collection or use one of the concurrent collections.

    The Associative Collection Classes
    Associative collections store a value in the collection by providing a key that is used to add/remove/lookup the item. Hence, the container associates the value with the key. These collections are most useful when you need to lookup/manipulate a collection using a key value. For example, if you wanted to look up an order in a collection of orders by an order id, you might have an associative collection where they key is the order id and the value is the order.

    The Dictionary (hash table)  is probably the most used associative container class. The Dictionary is the fastest class for associative lookups/inserts/deletes because it uses a hash table under the covers. Because the keys are hashed, the key type should correctly implement GetHashCode() and Equals() appropriately or you should provide an external IEqualityComparer to the dictionary on construction. The insert/delete/lookup time of items in the dictionary is amortized constant time - O(1) - which means no matter how big the dictionary gets, the time it takes to find something remains relatively constant. This is highly desirable for high-speed lookups. The only downside is that the dictionary, by nature of using a hash table, is unordered, so you cannot easily traverse the items in a Dictionary in order.

    The SortedDictionary (binary tree) is similar to the Dictionary in usage but very different in implementation. The SortedDictionary uses a binary tree under the covers to maintain the items in order by the key. As a consequence of sorting, the type used for the key must correctly implement IComparable so that the keys can be correctly sorted. The sorted dictionary trades a little bit of lookup time for the ability to maintain the items in order, thus insert/delete/lookup times in a sorted dictionary are logarithmic - O(log n). Generally speaking, with logarithmic time, you can double the size of the collection and it only has to perform one extra comparison to find the item. Use the SortedDictionary when you want fast lookups but also want to be able to maintain the collection in order by the key.

    The SortedList (sorted array) is the other sorted associative container class in the generic containers. Once again SortedList, like SortedDictionary, uses a key to sort key-value pairs. Unlike SortedDictionary, however, items in a SortedList are stored as sorted array of items. This means that insertions and deletions are linear - O(n) - because deleting or adding an item may involve shifting all items up or down in the list. Lookup time, however is O(log n) because the SortedList can use a binary search to find any item in the list by its key. So why would you ever want to do this? Well, the answer is that if you are going to load the SortedList up-front, the insertions will be slower, but because array indexing is faster than following object links, lookups are marginally faster than a SortedDictionary. Once again I'd use this in situations where you want fast lookups and want to maintain the collection in order by the key, and where insertions and deletions are rare.

    The Non-Associative Containers
    The other container classes are non-associative. They don't use keys to manipulate the collection but rely on the object itself being stored or some other means (such as index) to manipulate the collection.

    The List (dynamic array) is a basic contiguous storage container. Some people may call this a vector or dynamic array. Essentially it is an array of items that grow once its current capacity is exceeded. Because the items are stored contiguously as an array, you can access items in the List by index very quickly. However inserting and removing in the beginning or middle of the List are very costly because you must shift all the items up or down as you delete or insert respectively. However, adding and removing at the end of a List is an amortized constant operation - O(1). Typically List is the standard go-to collection when you don't have any other constraints, and typically we favor a List even over arrays unless we are sure the size will remain absolutely fixed.

    The LinkedList (doubly-linked list) is a basic implementation of a doubly-linked list. This means that you can add or remove items in the middle of a linked list very quickly (because there's no items to move up or down in contiguous memory), but you also lose the ability to index items by position quickly. Most of the time we tend to favor List over LinkedList unless you are doing a lot of adding and removing from the collection, in which case a LinkedList may make more sense.

    The HashSet is an unordered collection of unique items. This means that the collection cannot have duplicates and no order is maintained. Logically, this is very similar to having a Dictionary where the TKey and TValue both refer to the same object. This collection is very useful for maintaining a collection of items you wish to check membership against. For example, if you receive an order for a given vendor code, you may want to check to make sure the vendor code belongs to the set of vendor codes you handle. In these cases a HashSet is useful for super-quick lookups where order is not important. Once again, like in Dictionary, the type T should have a valid implementation of GetHashCode()and Equals(), or you should provide an appropriate IEqualityComparer to the HashSet on construction.

    The SortedSet (binary tree) is to HashSet what the SortedDictionary is to Dictionary. That is, the SortedSetis a binary tree where the key and value are the same object. This once again means that adding/removing/lookups are logarithmic - O(log n) - but you gain the ability to iterate over the items in order. For this collection to be effective, type T must implement IComparable or you need to supply an external IComparer.

    Finally, the Stack and Queue are two very specific collections that allow you to handle a sequential collection of objects in very specific ways. The Stack is a last-in-first-out (LIFO) container where items are added and removed from the top of the stack. Typically this is useful in situations where you want to stack actions and then be able to undo those actions in reverse order as needed. The Queue on the other hand is a first-in-first-out container which adds items at the end of the queue and removes items from the front. This is useful for situations where you need to process items in the order in which they came, such as a print spooler or waiting lines.

    So that's the basic collections. Let's summarize what we've learned in a quick reference table.

    Collection
    Ordering
    Contiguous Storage?
    Direct Access?
    Lookup Efficiency
    Manipulate
    Efficiency
    Notes
    Dictionary
    Unordered
    Yes
    Via Key
    Key:
    O(1)
    O(1)
    Best for high performance lookups.
    SortedDictionary
    Sorted
    No
    Via Key
    Key: 
    O(log n)
    O(log n)
    Compromise of Dictionary speed and ordering, uses binarysearch tree.
    SortedList
    Sorted
    Yes
    Via Key
    Key:
    O(log n)
    O(n)
    Very similar toSortedDictionary, except tree is implemented in an array, so has faster lookup on preloaded data, but slower loads.
    List
    User has precise control over element ordering
    Yes
    Via Index
    Index: O(1)
    Value: O(n)
    O(n)
    Best for smaller lists where direct access required and no sorting.
    LinkedList
    User has precise control over element ordering
    No
    No
    Value:
    O(n)
    O(1)
    Best for lists where inserting/deleting in middle is common and no direct access required.
    HashSet
    Unordered
    Yes
    Via Key
    Key:
    O(1)
    O(1)
    Unique unordered collection, like a Dictionary except key and value are same object.
    SortedSet
    Sorted
    No
    Via Key
    Key:
    O(log n)
    O(log n)
    Unique sorted collection, like SortedDictionary except key and value are same object.
    Stack
    LIFO
    Yes
    Only Top
    Top: O(1)
    O(1)*
    Essentially same as List except only process as LIFO
    Queue
    FIFO
    Yes
    Only Front
    Front: O(1)
    O(1)
    Essentially same as List except only process as FIFO

    The Original Collections: System.Collections namespace
    The original collection classes are largely considered deprecated by developers and by Microsoft itself. In fact they indicate that for the most part you should always favor the generic or concurrent collections, and only use the original collections when you are dealing with legacy .NET code.
    Because these collections are out of vogue, let's just briefly mention the original collection and their generic equivalents:
    • ArrayList
      • A dynamic, contiguous collection of objects.
      • Favor the generic collection List instead.
    • Hashtable
      • Associative, unordered collection of key-value pairs of objects.
      • Favor the generic collection Dictionary instead.
    • Queue
      • First-in-first-out (FIFO) collection of objects.
      • Favor the generic collection Queue instead.
    • SortedList
      • Associative, ordered collection of key-value pairs of objects.
      • Favor the generic collection SortedList instead.
    • Stack
      • Last-in-first-out (LIFO) collection of objects.
      • Favor the generic collection Stack instead.
    In general, the older collections are non-type-safe and in some cases less performant than their generic counterparts. Once again, the only reason you should fall back on these older collections is for backward compatibility with legacy code and libraries only.

    The Concurrent Collections: System.Collections.Concurrent namespace
    The concurrent collections are new as of .NET 4.0 and are included in the System.Collections.Concurrent namespace. These collections are optimized for use in situations where multi-threaded read and write access of a collection is desired.
    The concurrent queue, stack, and dictionary work much as you'd expect. The bag and blocking collection are more unique. Below is the summary of each with a link to a blog post I did on each of them.
    Summary
    The .NET BCL has lots of collections built in to help you store and manipulate collections of data. Understanding how these collections work and knowing in which situations each container is best is one of the key skills necessary to build more performant code. Choosing the wrong collection for the job can make your code much slower or even harder to maintain if you choose one that doesn’t perform as well or otherwise doesn’t exactly fit the situation.
    Remember to avoid the original collections and stick with the generic collections.  If you need concurrent access, you can use the generic collections if the data is read-only, or consider the concurrent collections for mixed-access if you are running on .NET 4.0 or higher.


    -----
      (code for Class design for most of the adv collection classes)

    1. Analyzing the Performance of Data Structures

    2. The term "running time," despite its name, does not measure the absolute time it takes the program to run, but rather refers to the number of steps the program must perform to complete the given task at hand. When working with arrays, typically the steps considered are how many array accesses one needs to perform. 
      The time it takes to search an array is linearly proportional to the number of elements in the array.
      This sort of analysis described here is called asymptotic analysis, as it examines how the efficiency of a data structure changes as the data structure's size approaches infinity. The notation commonly used in asymptotic analysis is called big-Oh notation. The big-Oh notation to describe the performance of searching an unsorted array would be denoted as O(n). The large script O is where the terminology big-Oh notation comes from, and the n indicates that the number of steps required to search an array grows linearly as the size of the array grows.
      Steps : if any step is in loop and time it takes is n - it's in two loops  it's time taken is n*n.
      To search an array time taken is "n"  - Running time = o(n).
      lower the term  inside the parenthesis for large values of n, the better the data structure's operation's performance.  asymptotic running time should be analyzed in practical scenario, it might be possible that data is less so even if o(n) is small, actual performance is less.

      Array:
      Stores homogenous type or derived type. Memory is contiguous for array elements.
      The running time of an array access (array[7] ) is denoted O(1) , irrespective of the size.
      Search time for simple array: O(n),
      Look up time : O(1).
      search time for two dimension array : o(n*n)
      Homogenous and fixed size.
      Sorted search O(Log n)

      ArrayList :
      Built on top of Array with heterogeneous data type and resizing capabilities (through reallocation). Arraylist is an array of objects and all types derived from object so any data type can be saved. But has cost of casting. Specially with value type as in arraylist value types are stored as Boxed value type i.e array stores a reference and that point to actual value type. While in array the value type is stored as unboxed value type (so no redirection is required). So cost is of boxing/unboxing  as well as of redirection.
      Binary search required values to be in sorted order if arraylist is not sorted binary search will give wrong output.

      List
      List is also built on top of array and it's generic so performance is same and no overhead.
      The Queue and Stack differ from the List class in that there are limitations on how the Queue and Stack data can be accessed.
      Requirement is to buffer (queue) the jobs for further processing - class with list and nextjobindex is inefficient because processed job memory is not reclaimed and can't be done as list is linear structure and nextJobIndex wouldn't work if we store new jobs on free available space.
      Queue is like circular array, with start and end pointers,Enqueue() and Dequque() methods  and growth factor which increase the size of queue for growthfactor=2, size get double when there is new job and no space. Jobs can be assessed in FIFO order and can't be done randomly but it has contains method to find if there is element.
      Opposite is Stack - First in last out LIFO- it has push and pop methods. It can be visualized as vertical collection of items. (used in stack trace debugger)
      The asymptotic running time of the List's operations are the same as those of the standard array's. While the List does indeed have more overhead, the relationship between the number of elements in the List and the cost per operation is the same as the standard array.




      HashTable:
      Stores item against hashkey. To generate Hashkey .Net uses object's GetHashCode function.
      There is posibbility that two objects generates the same hashcode so there are approaches for conflict resolution. Resolution is costly so all care is taken to generate the unique hashcodes.
      Linear Probing - Technique where if generated hashcode already occupied use the next available slot.
      Rehashing or double hashing - .Net hashtable uses this approach, in this couple of hash functions are used which are differ just in some multiplication factor, so first H1 will be used incase it's duplicate H2 will be used.
      The Hashtable class contains a private member variable called loadFactor that specifies the maximum ratio of items in the Hashtable to the total number of slots. A loadFactor of, say, 0.5, indicates that at most the Hashtable can only have half of its slots filled with items and the other half must remain empty. Load factor of 1 translate to 0.72 in .Net (internal to hashtable).
      Finally, realize that expanding the Hashtable is not an inexpensive operation. Therefore, if you have an estimate as to how many items you're Hashtable will end up containing, you should set the Hashtable's initial capacity accordingly in the constructor so as to avoid unnecessary expansions.
      The asymptotic access time for a Hashtable is O(1), which beats the pants off of the O(n) search time for an array.

      The Dictionary class is a type-safe Hashtable implementation, and strongly types both the keys and values. Dictionary used different conflict resolution approach called Chaining. In these any conflicts are stored in chain which is a secondary data type and is lnked to hash key in the dictionary.

      Binary Trees:  [ only one root / only one parent / no cycles ]
      the various BinaryTreeNode instances that makeup a binary tree can be scattered throughout the CLR managed heap. They are not necessarily contiguous, as are the elements of an array.
      There's no direct access to a given node as with an array. Searching a binary tree can take linear time, as potentially all nodes will need to be examined. That is, as the number of nodes in the binary tree increases, the number of steps to find an arbitrary node will increase as well.
      So, if a binary tree's lookup time is linear, and its search time is linear, how is the binary tree any better than an array, whose search time is linear, but whose lookup time is constant? Well, a generic binary tree doesn't offer us any benefit over an array. However, by intelligently organizing the items in a binary tree, we can greatly improve the search time (and therefore the lookup time as well).
      Organized binary tree efficient for search are called - Binary Search Trees (BSTs) : The principle of data storage for BSTs is that - For each node data on the left is less than the node and data on the right is greater than the node.
      The important concept to understand here is that ideally at each step in the algorithm the number of nodes that have to be considered has been cut in half. Searching a binary tree is similar in analysis to searching a sorted array. Such algorithms that exhibit this property have an asymptotic running time of log2 n, commonly abbreviated lg n.
      The time it takes to search a BST is dependent upon its topology. In the best case, the time is on the order of log2 n, but in the worst case it requires linear time.
      Since newly inserted nodes into a BST are inserted as leaves, the order of insertion directly affects the topology of the BST itself. For example, imagine we insert the following nodes into a BST: 1, 2, 3, 4, 5, and 6. When 1 is inserted, it is insert as the root. Next, 2 is inserted as 1's right child. 3 is inserted as 2's right child, 4 as 3's right child, and so on. This result in linear BST with worst search time o(n)
      Deleting nodes from a BST is slightly more difficult than inserting a node because deleting a node that has children requires that some other node be chosen to replace the hole created by the deleted node.
      A balanced tree is a tree that maintains some predefined ratio between its height and breadth. Different data structures define their own ratios for balance, but all have it close to log2 n. A self-balancing BST, then, exhibits log2 n asymptotic running time. There are numerous self-balancing BST data structures in existence, such as AVL trees, red-black trees, 2-3 trees, 2-3-4 trees, splay trees, B-trees, and others. 

      LinkedList
      Recall that with a binary tree, each node in the tree contains some bit of data and a reference to its left and right children. A linked list can be thought of as a unary tree. That is, each element in a linked list has some data associated with it, and a single reference to its neighbor.
      Linked lists have the same linear running time for searches as arrays.
      The asymptotic time required to insert a new element into a linked list depends on whether or not the linked list is a sorted list. The primary benefit of linked lists is that adding or removing items does not involve messy and time-consuming resizing. Granted, the List class hides the code complexity of this, but resizing still carries with it a performance penalty. Generic linklist class implements a doubly-linked list, which is a linked list whose nodes have a reference to both their next neighbor and their previous neighbor. 
      Skip Lists: A Linked List with Self-Balancing BST-Like Properties

      almost always use Dictionary for lookups
      On the other hand, it is faster to loop through all the elements in a List than in a Dictionary.