Coding Questions

Please answer one or both of the following questions. Please do not use existing class libraries in your answer(s):

Write me a function that receives three integer inputs for the lengths of the sides of a triangle and returns one of four values to determine the triangle type (1=scalene, 2=isosceles, 3=equilateral, 4=error). Generate test cases for the function assuming another developer coded the function

   1: using System;

   2:  

   3: namespace CubicType

   4: {

   5:     class Program

   6:     {

   7:         public enum CubicType

   8:         {

   9:             Scalene = 1, // no sides same length

  10:             Isosceles = 2, // 2 sides same length

  11:             Equilateral = 3, // 3 sides same length

  12:             Error = 4,

  13:         }

  14:  

  15:         private static CubicType GetCubicType(int a, int b, int c) {

  16:             if (a <= 0 || b <= 0 || c <= 0) {

  17:                 return CubicType.Error;

  18:             }

  19:  

  20:             if ((a == b) && (b == c)) {

  21:                 return CubicType.Equilateral;

  22:             }

  23:  

  24:  

  25:             if ((a == b) || (a == c) || (b == c)) {

  26:                 return CubicType.Isosceles;

  27:             }

  28:  

  29:  

  30:             if (((a + b) < c) || ((a + c) < b) || ((b + c) < a)) {

  31:                 return CubicType.Error;

  32:             }

  33:             else {

  34:                 return CubicType.Scalene;

  35:             }

  36:  

  37:         }

  38:  

  39:         static void Main(string[] args) {

  40:  

  41:             CubicType result;

  42:  

  43:             /*

  44:              * Test cases

  45:              * 1. valid scalene triangle?

  46:              * 2. valid equilateral triangle?

  47:              * 3. valid isosceles triangle?

  48:              * 4. 3 permutations of previous?

  49:              * 5. side = 0?

  50:              * 6. negative side?

  51:              * 7. one side is sum of others (1, 2, 3)?

  52:              * 8. 3 permutations of previous?

  53:              * 9. one side larger than sum of others (1, 2, 4)?

  54:              * 10. 3 permutations of previous?

  55:              * 11. all sides = 0?

  56:              * 12. non-integer input?

  57:              * 13. wrong number of values?

  58:              * 14. for each test case: is expected output specified?

  59:              * 15. check behaviour after output was produced?

  60:              * 

  61:             */

  62:             result = GetCubicType(1, 1, 1);

  63:             Console.WriteLine("(1, 1, 1) = {0}", result.ToString()); // Equilateral triangle

  64:  

  65:             result = GetCubicType(2, 1, 1);

  66:             Console.WriteLine("(2, 1, 1) = {0}", result.ToString()); // Isosceles triangle

  67:  

  68:             result = GetCubicType(1, 2, 1);

  69:             Console.WriteLine("(1, 2, 1) = {0}", result.ToString()); // Isosceles triangle

  70:  

  71:             result = GetCubicType(1, 1, 2);

  72:             Console.WriteLine("(1, 1, 2) = {0}", result.ToString()); // Isosceles triangle

  73:                        

  74:             

  75:             result = GetCubicType(1, 2, 25);

  76:             Console.WriteLine("(1, 2, 25) = {0}", result.ToString()); // Error

  77:  

  78:             result = GetCubicType(1, 0, -1);

  79:             Console.WriteLine("(1, 0, -1) = {0}", result.ToString());

  80:  

  81:             result = GetCubicType(4, 5, 6);

  82:             Console.WriteLine("(4, 5, 6) = {0}", result.ToString());

  83:             

  84:             result = GetCubicType(2147483647, 2147483647, 2147483647);

  85:             Console.WriteLine("(2147483647, 2147483647, 2147483647) = {0}", result.ToString());

  86:  

  87:         }

  88:     }

  89: }

 

1) Implement a circular queue of integers of user-specified size using a simple array. Provide routines to initialize(), enqueue() and dequeue() the queue. Make it thread safe.

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Text;

   5: using System.Threading;

   6:  

   7: namespace ThreadSafeCircularQueue

   8: {

   9:     /// <summary>

  10:     ///  CircularQueue

  11:     /// </summary>

  12:     public class CircularQueue

  13:     {

  14:         private int head;

  15:         private int tail;

  16:         private int[] queue;

  17:         private int length;

  18:  

  19:         private static Object QueueLock = new Object(); // Make the Queue thread safe

  20:  

  21:         /// <summary>

  22:         ///  Queue Constructor

  23:         /// </summary>

  24:         /// <param name="lengh"> Length of Queue</param>

  25:         public CircularQueue(int lengh)

  26:         {

  27:             Initialize(length);

  28:         }

  29:  

  30:         public CircularQueue()

  31:         {

  32:  

  33:         }

  34:  

  35:         /// <summary>

  36:         /// Initializes the Queue

  37:         /// </summary>

  38:         /// <param name="length"> length </param>

  39:         private void Initialize(int length)

  40:         {

  41:             head = -1;

  42:             tail = -1;

  43:  

  44:             this.length = length;

  45:             queue = new int[length];

  46:  

  47:             Console.WriteLine("Queue size: {0}", length);

  48:         }

  49:  

  50:         /// <summary>

  51:         /// Adds a new int element to the tail of the Queue

  52:         /// </summary>

  53:         /// <param name="value">The integer value of the element to be queued</param>

  54:         /// <returns>The index of the queued element or failure</returns>

  55:         public int Enqueue(int value)

  56:         {

  57:             lock (QueueLock) {

  58:                 if ((head == 0 && tail == length - 1) || (tail + 1 == head)) {

  59:                     Console.WriteLine("Queue is full.");

  60:                     return -1;

  61:                 }

  62:                 else {

  63:                     if (tail == length - 1)

  64:                         tail = 0;

  65:                     else

  66:                         tail++;

  67:  

  68:                     queue[tail] = value;

  69:  

  70:                     if (head == -1)

  71:                         head = 0;

  72:  

  73:                     return tail;

  74:                 }

  75:  

  76:             }

  77:         }

  78:  

  79:         /// <summary>

  80:         /// Gets the first element's value

  81:         /// </summary>

  82:         /// <returns></returns>

  83:         public int Dequeue()

  84:         {

  85:             lock (QueueLock) {

  86:                 int value;

  87:  

  88:                 if (head == -1) {

  89:                     value = -1;

  90:                 }

  91:                 else {

  92:                     value = queue[head];

  93:                     queue[head] = 0;

  94:  

  95:                     if (head == tail)

  96:                         head = tail = -1;

  97:                     else

  98:                         if (head == length - 1)

  99:                             head = 0;

 100:                         else

 101:                             head++;

 102:                 }

 103:  

 104:                 return value;

 105:             }

 106:         }

 107:  

 108:         /// <summary>

 109:         /// Gets a formatted string of the queue elements

 110:         /// </summary>

 111:         /// <returns>Queue elements</returns>

 112:         public string ShowQueue()

 113:         {

 114:             lock (QueueLock) {

 115:                 int i;

 116:                 string result = " Queue Emelemnts: ";

 117:  

 118:                 if (head == -1) {

 119:                     result = "No elements(empty)";

 120:                 }

 121:                 else {

 122:                     if (tail < head) {

 123:                         for (i = 0; i <= length - 1; i++)

 124:                             result += queue[i] + " ";

 125:                     }

 126:                     else

 127:                         for (i = 0; i <= tail; i++)

 128:                             result += queue[i] + " ";

 129:                 }

 130:                 return result + "\n";

 131:             }

 132:         }

 133:  

 134:         /// <summary>

 135:         /// Test

 136:         /// </summary>

 137:         public void QueueTest()

 138:         {

 139:             Initialize(3);

 140:             Enqueue(1);

 141:             Console.Write(ShowQueue());

 142:             Enqueue(2);

 143:             Console.Write(ShowQueue());

 144:             Enqueue(3);

 145:             Console.Write(ShowQueue());

 146:             Enqueue(4);

 147:             Console.Write(ShowQueue()); 

 148:             Dequeue();

 149:             Console.Write(ShowQueue());

 150:             Dequeue();

 151:             Console.Write(ShowQueue());

 152:             Dequeue();

 153:             Console.Write(ShowQueue());

 154:             Dequeue();

 155:             Console.Write(ShowQueue());

 156:             Enqueue(4);

 157:             Console.Write(ShowQueue());

 158:             Dequeue();

 159:             Console.Write(ShowQueue());

 160:             Dequeue();

 161:             Console.Write(ShowQueue());

 162:         }

 163:  

 164:     }

 165:  

 166:     class Program

 167:     {

 168:         static void Main(string[] args)

 169:         {

 170:             CircularQueue circularQueue = new CircularQueue();

 171:  

 172:             Thread[] threads = new Thread[5];

 173:  

 174:             for (int i = 0; i < threads.Length; i++) {

 175:                 threads[i] = new Thread(new ThreadStart(circularQueue.QueueTest));

 176:             }

 177:  

 178:             for (int i = 0; i < threads.Length; i++) {

 179:                 threads[i].Start();

 180:             }

 181:             Console.ReadLine();

 182:         }

 183:     }

 184: }

Advertisements

Technical Questions 1

1) Which is better – singly linked list or doubly linked list? What are the pros and cons of using each?

Singly-linked list:

Pros: Simple in implementation, requires relatively lesser memory for storage, assuming you need to insert/delete at next node; insertion/deletion is faster.

Cons: Cannot be iterated in reverse, need to maintain a handle to the head node of the list else, the list will be lost in memory. If you’re deleting previous node or inserting at previous node, you will need to traverse list from head to previous node to be able to carry out those operations – O(N) time.

That should be used when you have lesser memory and your main purpose is insertion/deletion and not searching elements.

Doubly-linked list:

Pros: Can be iterated in forward as well as reverse direction. In case of needing to delete previous node, there is no need to traverse from head node, as the node to be deleted can be found from ‘.previous’ pointer.

Cons: Relatively complex to implement, requires more memory for storage (1 ‘.previous’ pointer per node). Insertions and deletions are relatively more time consuming (assigning/reassigning ‘.previous’ pointer for neighbor nodes)

That should be used when you have no minimal limitations on memory, and your main purpose is to search for elements.

2) What’s the difference between Managed code and Native code? Give examples of each you have worked on.
The big difference is memory management. With Native Code, you need to do your own resource (RAM / Memory) allocation and cleanup. If you forget something, you end up with what’s called a “Memory Leak” that can crash the computer. A Memory Leak is a term for when an application starts using up (eating up) Ram/Memory but not letting it go so the computer can use if for other applications; eventually this causes the computer to crash. With Managed Code, all the resource (RAM / Memory) allocation and cleanup are done for you and the risk of creating “Memory Leaks” is reduced to a minimum. This allows more time to code features instead of spending it on resource management.

  • · Managed code runs under CLR whereas native code does not run under CLR.
  • · Managed code takes advantages of memory management, security and threading services CLR provides, whereas these are missing for native code that directly runs on the machine.
  • · The managed code is the one generated by C# and other .NET language compilers (IL) and gets finally converted to native code by JIT. The code in languages prior to .NET like VC++ get converted directly to native code and runs on the machine.eg COM components

Over the past two years, I developed web applications for extending the server by modules which are developed in two ways (We have specific requirements that demand native code development and would like to convert our existing native ISAPI components, take advantage of this API to build server components.):

a) Using managed code, and the ASP.NET server extensibility APIs

b) Using native code, and the IIS native server extensibility APIs

3) What is thread safe code? Give an example of times you’ve used thread safe code.
Thread-safety is a computer programming concept applicable to multi-threaded programs. A piece of code is thread-safe if it is reentrant or protected from multiple simultaneous executions by some form of mutual exclusion.

Thread-safety is a key challenge in multi-threaded programming. In a multi-threaded program, several threads execute simultaneously in a shared address space. Every thread has access to virtually all the memory of every other thread. Thus the flow of control and the sequence of accesses to data often have little relation to what would be reasonably expected by looking at the text of the program. This violates the principle of least astonishment. Thread-safety is a property aimed for so as to minimize surprising behavior by re-establishing some of the correspondences between the actual flow of control and the text of the program.

General-purpose types are rarely thread-safe in their entirety, for the following reasons:

  • · The development burden in full thread safety can be significant, particularly if a type has many fields (each field is a potential for interaction in an arbitrarily multithreaded context).
  • · Thread safety can entail a performance cost (payable, in part, whether or not the type is actually used by multiple threads).
  • · A thread-safe type does not necessarily make the program using it thread-safe, and often the work involved in the latter makes the former redundant.

Example: Methods used in Logger, to write a log file, should be threading safe for an application that runs under multi-threading environment.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

   1: public static class SharedLogger

   2: {

   3:     private static LogToFile _writer = new LogToFile();

   4:     private static object _lock = new object();

   5:     public static void Write(string text)

   6:     {

   7:         lock (_lock)

   8:         {

   9:             _writer.LogToFile(string text);

  10:         }

  11:     }

  12: }