23
Software Development Questions & Answers C# Microsoft .NET Plus General Design, Development & OOP Topics Answers & Code Samples by James B. Higgins February 19 th , 2015

James Higgins - C# Developer Q&A with Code Samples

Embed Size (px)

Citation preview

Page 1: James Higgins - C# Developer Q&A with Code Samples

Software Development

Questions & Answers

C#

Microsoft .NET

Plus General Design,

Development & OOP Topics

Answers & Code Samples by

James B. Higgins

February 19th, 2015

Page 2: James Higgins - C# Developer Q&A with Code Samples

.Net Developer – Source Code Questions

A. Implement a basic Person data structure in SQL and also its code-first representation in Entity Framework. Assume there isn’t a primary key named with ID in the name.

B. Create a Counter class with a method Increment with a private property _counter that is meant to be called by multiple parallel threads.

C. Create a class that implements an interface ITicket with method Punch and inherits from a base Ticket class. D. Create a Singleton Log class that implements an ILog interface and can be used by multiple projects. E. Create a Unit Test for this method int CalcTotal(int A, int B) return A+B; F. Create a WebAPI POST method that returns a Result json result object with a result and error properties. The

result property should contain an array of integers. G. Create a Class that allows a person to quickly add new strings to its collection if they are unique and has a

method to return a list containing the strings in the order they were added. Explain why your class is the most efficient method from a speed, memory, or maintainability standpoint. Provide a unit test to prove it performs quickly on 1 million plus strings with a level of duplication.

H. Refactor this class to make Roll better testable and write the unit test. public Class Chair Wheels _wheels = new Wheels(); Public Chair()1 public void Roll() _wheels.Roll();

Pre‐Screen Questions:

1. What is SOLID? 2. Why is the Single Responsibility Principle important? 3. What is Inversion of Control? How does that relate to dependency injection? 4. How does a 3 tier application differ from a 2 tier one? 5. What is the Repository pattern? The Factory Pattern? Why are patterns important? 6. How do the MVP, MVC, and MVVM patterns relate? When are they appropriate? 7. Explain the concept of Separation of Concerns and its pros and cons. 8. Name three primary attributes of object-oriented design. Describe what they mean and why they're

important. 9. Describe a pattern that is NOT the Factory Pattern? How is it used and when? 10. Explain the concept of convention over configuration, and talk about an example of convention over

configuration you have seen in the wild. 11. What's the difference between Locking and Lockless (Optimistic and Pessimistic) concurrency models? 12. What kinds of problems can you hit with locking model? And a lockless model? 13. What tradeoffs do you have for resource contention? 14. How might a task-based model differ from a threaded model? 15. What's the difference between asynchrony and concurrency? 16. How does the addition of Service Orientation change systems? When is it appropriate to use? 17. What's so great about Windows Workflow Framework? 18. If your database was under a lot of strain, what are the first few things you might consider to speed it up? 19. What is SQL injection? 20. What's the difference between unit test and integration test?

Page 3: James Higgins - C# Developer Q&A with Code Samples

James Higgins - .Net Source Code Answers

A. Implement a basic Person data structure in SQL and also its code-first representation in Entity Framework. Assume there isn’t a primary key named with ID in the name.

I haven’t really used code-first with Entity Framework. I have a rather strong belief that while code is important, data is much more so. There are a lot of database details you can’t specify in a code-first model and I don’t entirely trust the automatic creation, dropping and modification of database tables. Plus code-first relies much to heavily on the notion that the code completely owns the database definition when those tables may also be used for reporting, import/export or other systems.

Code First:

Which is roughly equivalent to:

Page 4: James Higgins - C# Developer Q&A with Code Samples

Just for the heck of it here is an alternative table that demonstrates how a GUID key could be used (if desired/necessary) without destroying insert performance:

B. Create a Counter class with a method Increment with a private property _counter that is meant to be called by multiple parallel threads.

Piece of cake.

Page 5: James Higgins - C# Developer Q&A with Code Samples

C. Create a class that implements an interface ITicket with method Punch and inherits from a base Ticket class.

Here is the code for ITicket, TicketBase and Ticket:

Page 6: James Higgins - C# Developer Q&A with Code Samples

As a demonstration of inheritance & polymorphism:

Page 7: James Higgins - C# Developer Q&A with Code Samples

D. Create a Singleton Log class that implements an ILog interface and can be used by multiple projects.

Extremely simple ILog and a singleton pattern for accessing an instance of it:

Page 8: James Higgins - C# Developer Q&A with Code Samples

I have a rather extensive collection of my own personal .net (C#) libraries that I’ve written over the years. Among the functionality is a very robust logging system which happens to define an ILog interface:

Page 9: James Higgins - C# Developer Q&A with Code Samples

E. Create a Unit Test for this method int CalcTotal(int A, int B) return A+B;

Unit tests which should thoroughly validate the method, including expected exceptions.

Page 10: James Higgins - C# Developer Q&A with Code Samples

Since I sometimes find that way of writing unit tests very lengthy (particularly for library methods) here is an alternative implementation:

Page 11: James Higgins - C# Developer Q&A with Code Samples

F. Create a WebAPI POST method that returns a Result json result object with a result and error properties. The result property should contain an array of integers.

There are many ways to do this and implementation details can vary depending on the version of MVC being used. Here is one simple implementation that should produce the desired result. Note that the actual data type returned may not be JSON and would be dependent upon the web application configuration (namely which serializes are configured) in addition to the content type specified in the request.

Note that I used the class name “JsonResult” instead of “Result” since it did not have a conflict and Result did.

Model:

Controller action:

Page 12: James Higgins - C# Developer Q&A with Code Samples

G. Create a Class that allows a person to quickly add new strings to its collection if they are unique and has a method to return a list containing the strings in the order they were added. Explain why your class is the most efficient method from a speed, memory, or maintainability standpoint. Provide a unit test to prove it performs quickly on 1 million plus strings with a level of duplication.

I abstracted this out to an IStrings interface and two implementations with different performance characteristics:

Page 13: James Higgins - C# Developer Q&A with Code Samples

Unit tests to verify that both implementations function correctly:

Page 14: James Higgins - C# Developer Q&A with Code Samples

Unit tests to benchmark the performance of both implementations and verify that the Fast implementation is much faster than the Simple one:

Page 15: James Higgins - C# Developer Q&A with Code Samples

H. Refactor this class to make Roll better testable and write the unit test. public Class Chair Wheels _wheels = new Wheels(); Public Chair()1 public void Roll() _wheels.Roll();

This was a bit confusing as written, especially since

Public Char()1

won’t compile and the purpose of it isn’t obvious (at least to me).

Here is the refactored interface and class I came up with:

Page 16: James Higgins - C# Developer Q&A with Code Samples

Here are the corresponding unit tests:

Page 17: James Higgins - C# Developer Q&A with Code Samples

Pre‐Screen Questions:

1. What is SOLID?

S.O.L.I.D is an acronym referring to 5 object oriented development principles:

Single responsibility principle

Open-Closed principle

Liskov substitution principle

Interface segregation principle

Dependency inversion principle

2. Why is the Single Responsibility Principle important?

The idea is any given entity (class, interface, layer, etc) is focused around one particular responsibility (a person object, a log writing interface, a database access layer, etc). This helps organize code into smaller, more flexible, more maintainable and more reusable blocks.

3. What is Inversion of Control? How does that relate to dependency injection?

Inversion of control is a generic concept that states an object should not be aware of the implementation details of other objects or elements it depends upon. Basically meaning that if a class used an interface to write out logging data or to access a data store that dependency should not be created & configured (instantiated) within the dependent object and should instead come from outside.

Dependency Injection is more specific strategy used to effect Inversion of Control. An implementation of Dependency Injection would likely pass the objects/interfaces required by a class into its constructor. Thus supplying the dependencies to an object without requiring that the object know anything about how they were created or configured.

Page 18: James Higgins - C# Developer Q&A with Code Samples

4. How does a 3 tier application differ from a 2 tier one?

The term “tier” sometimes gets applied in two different ways. Tiers most accurately refers to the various elements that make up a distributed system. It is often also used as a pseudonym for the layers within a single piece of software.

In general terms a “2 tier” system would be one where the user interface and data access are separated (such as client/server). A “3 tier” system would generally be one where the presentation, business logic and data persistence are implemented separately.

Below are examples of what a 4 tier / layer system might look like.

Employee Training App

Personnel

Data Server

Training

Data Server

Authentication &

Authorization Server

Corporate Data Warehouse

WinForms GUI Layer

Personnel

Authentication &

Authentication

User

Interface

Business

Logic

Security

Persistence Database Access Layer

Training

Distributed System Tiers Application Layers

5. What is the Repository pattern? The Factory Pattern? Why are patterns important?

The repository pattern describes an optional intermediate layer that would provide querying and loading services for data objects from an underlying data store. The repository layer would internally handle caching and could, for instance, return the same cached in-memory instance of a data object anytime it was needed instead of allowing multiple in-memory objects that referred to the same underlying entity in the data store. Every ORM system I’ve implemented has included this functionality and I’ve frequently added this layer when using 3rd party ORMs that did not inherently implement it.

The factory pattern is simply a method call that instantiates and returns an object of an expected base class or implementing an expected interface. It is used to transfer the responsibility of creating and configuring an object to a factory specifically intended for the purpose. An example could be the need to obtain an interface for a data access

Page 19: James Higgins - C# Developer Q&A with Code Samples

layer without the calling code needing to know if the underlying data store was coming from a database, an XML file on disk or a remote WebAPI.

All systems with any degree of complexity have naturally occurring patterns in their data and structure. Recognizing and leveraging these patterns in the system design and implementation lead to cleaner, more flexible and more reusable systems. The commonly known / named patterns reflect those that frequently occur and have been documented as such. Identifying and utilizing the patterns that occur in systems and data, weather known and documented or more specific to the system at hand, is an extremely useful tool in good architectural design.

6. How do the MVP, MVC, and MVVM patterns relate? When are they appropriate?

These are all patterns that describe separating data and presentation. All three consist of a Model (the data) which is the first M in their acronym. After that they consist of the presentation (UI) and the glue code between the two. In visual studio WinForms is MVP, WPF is MVVM and ASP.NET MVC is (obviously) MVC. Since these patterns are tied to specific GUI technologies when they are appropriate (at least in Microsoft development shops) is much more about when those technologies are appropriate than when the patterns themselves are.

7. Explain the concept of Separation of Concerns and its pros and cons.

The general concept behind SoC is that a system’s design should identify discrete areas of functionality and separate them into separate entities (data entities, classes, interfaces, modules, etc). This is highly correlative with and essentially similar to the Single Responsibility Principal (SRP) and Interface Segregation Principal (ISP). The key behind all of these really being the ability to identify and define good boundaries between entities in a design.

The advantages of SoC and similar principals are many such as reducing the total amount of code, increasing code reuse, adding flexibility, improving testability, making maintenance easier, etc. If properly applied are there cons? I don’t believe so. These are underlying concepts that I personally consider obvious and baked into my personal methodology and coding/design style years ago.

Page 20: James Higgins - C# Developer Q&A with Code Samples

8. Name three primary attributes of object-oriented design. Describe what they mean and why they're important.

The terms Object Oriented Programming (OOP), Object Oriented Design (OOD), Object Oriented Analysis (OOA) and Object Oriented Analysis & Design (OOAD) have a lot of overlap and are used somewhat interchangeably. I’m not sure what “primary attributes” would refer to in OOD specifically. OOD (in my experience at least) is more of a loose definition revolving around design methodologies intended for use with OOP. Once common tenant of OOD is that it does generally involve modeling (diagramming) and I have used UML for this purpose at multiple companies.

Since these terms are used somewhat interchangeably and the attributes of OOP are better defined (and frequently referred used in OOD & OOA) I’ll assume it’s those attributes that are of interest here.

Encapsulation – This refers to the ability of a class to contain all of the data and methods related to the functionality of that particular entity.

Information Hiding – Related to encapsulation but further allowing certain aspects of the implementation (both data and activities) to be hidden within the implementation and not exposed to its consumers.

Inheritance – Allows the creation of class hierarchies where descendants can be implemented to further refine or specialize the implementation of the parent(s).

Abstraction – The ability to define a generic template / concept as an abstract class which itself can’t be instantiated but which can be extended through inheritance into concrete classes that provide specific implementations of the generic concept the parent defines.

Polymorphism – By combining the attributes of OOP such as inheritance and abstraction it becomes possible to reference and act upon objects who’s exact type is not known or relevant at run time. This is because such objects are more specific implementations of the class that the code knows about and expects. The Liskov Substitution Principal (part of SOLID asked about above) helps define good polymorphic practices.

9. Describe a pattern that is NOT the Factory Pattern? How is it used and when?

Probably the most widely implemented and used pattern in .Net is the Iterator which is handled by IEnumerable and IEnumerable<T>. This allows code to iterate though the contents of a container without needing to know any details regarding how the container stores its data or is configured.

Page 21: James Higgins - C# Developer Q&A with Code Samples

10. Explain the concept of convention over configuration, and talk about an example of convention over configuration you have seen in the wild.

Convention over Configuration is a concept by which a framework relies on conventions it defines instead of requiring explicit configuration. The most common example of this in Visual Studio is MVC which uses convention to map controller actions with their related views.

11. What's the difference between Locking and Lockless (Optimistic and Pessimistic) concurrency models?

In pessimistic concurrency the resource being used would be locked so that only one user could access and modify it at a time. Depending on the system it may be possible to refine this into any number of users could concurrently lock an entity for reading, but only one at a time could obtain a write lock and that would also exclude anyone else from holding a read lock concurrently. Multi-threading systems typically use pessimistic locking to control access to shared data. Database servers can employ row, page and table locking in order to provide pessimistic locking. For database servers in particular pessimistic locking can be costly in comparison to optimistic locking, especially if update collisions are expected to be infrequent.

In an optimistic concurrency model the entities being accessed and updated are not locked, allowing any client to read and/or write to them at any time. This can provide a major throughput increase in systems since it eliminates lock contention. However it opens up the possibility that clients could overwrite each other’s updates potentially destroying data integrity. To eliminate this clients using optimistic locking must remember what the entity they are updating looked like before they modified it and must verify it has not changed before applying changes.

12. What kinds of problems can you hit with locking model? And a lockless model?

See #11 above

13. What tradeoffs do you have for resource contention?

I assume this also refers to the locking & lockless questions above. See answer to #11.

Page 22: James Higgins - C# Developer Q&A with Code Samples

14. How might a task-based model differ from a threaded model?

I believe this most likely refers to the new Task-based Asynchronous Pattern (TAP) capability added to the .net framework in more recent versions. I have not worked with this implementation in particular but it appears to be very similar to thread pool functionality I’ve created and utilized in the past.

In general a thread is a separate sequence of code that will execute independently. Activity that requires setup, execution (particularly involving wait states or looping) and cleanup is well suited to be implemented as a thread. Simpler operations that can be implemented as a method call which performs a discrete task and then returns are generally better suited to be implemented using a thread pool or (it would appear) the new TAP functionality.

15. What's the difference between asynchrony and concurrency?

As implemented in the .net framework these refer to two different concepts. I believe the term “concurrency” being used here refers to the use of multi-threading to execute two or more sequences of code independently (likely in parallel given that most computers have multiple cores now). Asynchrony would refer to the practice of kicking off an action that is likely to incur a wait state, allowing execution of code to continue and then being notified when the action completes. Personally I’d consider this an extension of event driven programming and not a new concept.

16. How does the addition of Service Orientation change systems? When is it appropriate to use?

I’m not sure I can answer this in a short, succinct statement. The underlying principles required to support SOA are very similar to generally good software architecture & design principles (single responsibility, segregation of concerns, interface segregation, etc). An SOA likely incurs additional work and overhead due to implementing the boundaries between entities as separate servers operating over a distributed network instead of more cohesively within the same application or single server. There are various reasons (complexity, security, methods of use, etc) why a Service Oriented Architecture may or may not be a good choice for a particular system.

My first major experience with a SOA was at Intel in ~1999 where I designed and built a complete SOA distributed system from the ground up including all of the protocols, security, connectivity, service locators, data servers, data transfer, query language, etc.

17. What's so great about Windows Workflow Framework?

Honestly, I don’t know. I haven’t worked with it nor worked for a client that was using it. I’d be very curious to find out from someone who has worked with it though…

Page 23: James Higgins - C# Developer Q&A with Code Samples

18. If your database was under a lot of strain, what are the first few things you might consider to speed it up?

There is no universal answer to this without more context. What exactly is the strain? Is it slow fetching any data? Are certain queries slow? Are inserts slow? Updates? The combination of those experiencing performance problems is very indicative of the potential problems.

If certain queries are performing very slowly but overall access and inserts/updates are fine then it’s probably a lack of appropriate indices. If inserts are very slow but updates (not involving the primary key) are quick then it’s a problem with the primary key and most likely the clustered index (such as assigning a table to use a GUID key for its clustered index). If inserts and updates are both slow then it may be that there are too many complex indices that need to be updated. Database performance tuning requires a solid understanding of the data being stored, the queries used to access it and the general nature of the data itself (such as how frequently will inserts / updates occur).

19. What is SQL injection?

SQL injection (aka “SQL injection attacks”) is a situation where a malicious client uses carefully constructed data submitted to an application in order to cause the database server to execute arbitrary SQL not envisioned or desired by the programmer. SQL injection can occur anytime text data obtained from an outside source is used to construct SQL statements without somehow ensuring the data is valid and does not contain unwanted characters / SQL code. The easiest way to do this is generally by using the parameter capabilities built into the ADO.NET data access components (though there are other possibilities as well).

20. What's the difference between unit test and integration test?

Unit testing is typically used for white-box testing of a specific class or method. Good unit tests tend to have a very small scope which validates that one very specific piece of code functions as intended. Unit tests would likely confirm that business logic implemented in a class worked as expected, but it would not test to see that business objects were successfully saved and loaded from a SQL database.

Integration testing is the practice of validating the interaction between two or more components / modules / systems / etc. Testing a business object connected to a functional data access layer capable of persisting those objects to a SQL database would be an example of integration testing.