πŸ’» Programming Language/C#

4번째 μŠ€ν„°λ”” 이후 정리

S.Honey 2022. 4. 9. 23:53

catch μˆœμ„œ λ’€μ£½λ°•μ£½ν•΄μ„œ 확인

class Program
{
    class A
    {
        public int field;
        public static int getField(A obj)
        {
            return obj.field;
        }
    }

    static void Main(string[] args)
    {
        try
        {
            // DivideByZeroException
            int a = 10;
            int b = 0;
            Console.WriteLine(a / b);

            // NullReferenceException
            A obj = null;
            Console.WriteLine(A.getField(obj));

            // IndexOutOfRangeException            
            int[] arr = { 1, 2, 3 };
            for (int i = 0; i < 4; i++)
            {
                Console.WriteLine(arr[i]);
            }
        }

        catch (DivideByZeroException e)
        {
            Console.WriteLine("μ—λŸ¬ : {0}", e.Message);
        }
        catch (Exception e)
        {
            Console.WriteLine("μ—λŸ¬ : {0}", e.Message);
        }
        catch (IndexOutOfRangeException e)
        {
            Console.WriteLine("μ—λŸ¬ : {0}", e.Message);
        }
        catch (NullReferenceException e)
        {
            Console.WriteLine("μ—λŸ¬ : {0}", e.Message);
        }
        finally
        {
            Console.WriteLine("ν”„λ‘œκ·Έλž¨ μ’…λ£Œ");
        }
    }
}

Output

Output of Upper Code


배열에 λŒ€ν•œ μ‹œκ°„λ³΅μž‘λ„ => ν•΄μ‹±κ³Ό 비ꡐ


λ°°μ—΄

  • λ°°μ—΄(array)은 μ—°κ΄€λœ 데이터λ₯Ό λͺ¨μ•„μ„œ ν•œ λ²ˆμ— κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” 데이터 νƒ€μž…

  • 배열은 논리적인 μ €μž₯μˆœμ„œμ™€ 물리적인 μ €μž₯μˆœμ„œκ°€ 일치

  • λ”°λΌμ„œ 인덱슀(index)λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•΄λ‹Ή μ›μ†Œμ— μ ‘κ·Όν•  μˆ˜κ°€ μžˆλ‹€.

  • 인덱슀λ₯Ό μ•Œκ³  μžˆλ‹€λ©΄ 각각의 μ›μ†Œλ₯Ό λ°”λ‘œ μ°Ύμ•„κ°ˆ 수 있게 λ˜λ―€λ‘œ μ›μ†Œλ₯Ό μ°ΎλŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„λ³΅μž‘λ„λŠ” O(1) 이라고 λ³Ό 수 있고, 이λ₯Ό μž„μ˜ μ ‘κ·Ό(random access)이 κ°€λŠ₯ν•˜λ‹€κ³  λ§ν•œλ‹€.

  • λ°˜λ©΄μ— μƒˆλ‘œμš΄ 데이터λ₯Ό μ‚­μ œν•˜κ±°λ‚˜ μ‚½μž…μ„ ν•˜κ²Œ 되면 쑰금 λ³΅μž‘ν•΄μ§„λ‹€.

  • μ‚­μ œμ˜ 경우 λ¨Όμ € ν•΄λ‹Ή μ›μ†Œμ— 접근을 ν•΄μ„œ μž‘μ—…μ„ μ™„λ£Œν•˜λŠ”λ° (O(1)), 이 μƒνƒœλŠ” λ°°μ—΄μ˜ 연속적인 νŠΉμ„±μ΄ κΉ¨μ§€κ²Œ λœλ‹€.

  • λ”°λΌμ„œ μ΄λŸ¬ν•œ 빈 곡간을 λ©”κΏ”μ£ΌκΈ° μœ„ν•΄μ„œ μ‚­μ œν•œ μ›μ†Œλ³΄λ‹€ 더 큰 인덱슀λ₯Ό κ°–λŠ” μ›μ†Œλ“€μ„ shift ν•΄μ£Όμ–΄μ•Ό ν•˜λ©°, 이 λ•Œ λΉ„μš©μ΄ λ°œμƒν•˜κ³  결과적으둜 μ‹œκ°„λ³΅μž‘λ„λŠ” O(n)이 λœλ‹€. μ‚½μž…μ˜ κ²½μš°λ„ λΉ„μŠ·ν•˜κ²Œ 생각해 λ³Ό 수 μžˆλ‹€.

  • λ˜ν•œ λ©”λͺ¨λ¦¬ μ£Όμ†Œκ°€ μ—°μ†λ˜μ•Ό ν•˜κΈ° λ•Œλ¬Έμ—, λ°°μ—΄μ˜ 크기λ₯Ό λŠ˜λ¦¬λŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€.

  • λ§Œμ•½ λ°°μ—΄μ˜ 크기λ₯Ό λŠ˜λ €μ•Ό ν•  ν•„μš”κ°€ μžˆλ‹€λ©΄, 크기가 큰 배열을 λ§Œλ“€μ–΄μ„œ κΈ°μ‘΄ λ‚΄μš©μ„ λ³΅μ‚¬ν•˜κ±°λ‚˜, μ—°κ²° 리슀트(LinkedList)λ₯Ό μ‚¬μš©ν•˜λŠ” 방법을 생각해 보아야 ν•œλ‹€.


ν•΄μ‹œν…Œμ΄λΈ”

  • ν•΄μ‹œν…Œμ΄λΈ”(HashTable)은 ν•΄μ‹œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ ν‚€λ₯Ό ν•΄μ‹œκ°’μœΌλ‘œ λ§€ν•‘ν•˜κ³ , 이 ν•΄μ‹œκ°’μ„ 인덱슀 ν˜Ήμ€ μ£Όμ†Œλ‘œ μ‚Όμ•„μ„œ λ°μ΄ν„°μ˜ 값을 킀와 ν•¨κ»˜ μ €μž₯ν•˜λŠ” μžλ£Œκ΅¬μ‘°μ΄λ‹€.

  • ν•΄μ‹œ ν•¨μˆ˜λž€ λ°μ΄ν„°μ˜ 효율적 관리λ₯Ό λͺ©μ μœΌλ‘œ μž„μ˜μ˜ 길이 데이터λ₯Ό κ³ μ •λœ 길이 λ°μ΄ν„°λ‘œ λ§€ν•‘ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.

  • 이 λ•Œ λ§€ν•‘ μ „ μ›λž˜ 데이터 값을 ν‚€(key), λ§€ν•‘ ν›„ 데이터 값을 ν•΄μ‹œκ°’(hash value), λ§€ν•‘ν•˜λŠ” κ³Όμ • 자체λ₯Ό ν•΄μ‹±(hashing)이라고 ν•œλ‹€.

  • 이와 같이 해싱을 ν•˜κ²Œ 되면, 적은 λ¦¬μ†ŒμŠ€λ₯Ό κ°€μ§€κ³  λ§Žμ€ 데이터λ₯Ό 효율적으둜 관리할 수 있게 λœλ‹€.

    • 예λ₯Ό λ“€λ©΄ ν•΄μ‹œ ν•¨μˆ˜λ₯Ό 톡해 ν•˜λ“œλ””μŠ€ν¬λ‚˜ ν΄λΌμš°λ“œμ— μ‘΄μž¬ν•˜λŠ” λ¬΄ν•œμ— κ°€κΉŒμš΄ 데이터(ν‚€)듀을 μœ ν•œν•œ 개수의 ν•΄μ‹œκ°’μœΌλ‘œ λ§€ν•‘ν•¨μœΌλ‘œμ¨ μž‘μ€ 크기의 캐쉬 λ©”λͺ¨λ¦¬λ‘œ ν”„λ‘œμ„ΈμŠ€λ₯Ό 관리할 수 μžˆλ‹€.
  • ν•΄μ‹œ ν•¨μˆ˜λŠ” μ–Έμ œλ‚˜ λ™μΌν•œ ν•΄μ‹œκ°’μ„ λ¦¬ν„΄ν•˜κ³ , 인덱슀만 μ•Œλ©΄ ν•΄μ‹œ ν…Œμ΄λΈ”μ΄ 아무리 컀도 데이터에 λΉ λ₯΄κ²Œ μ ‘κ·Όν•  수 μžˆλ‹€.(λ°°μ—΄κ³Ό μœ μ‚¬)

  • λ”°λΌμ„œ 데이터에 μ ‘κ·Όν•˜λŠ” 경우 μ‹œκ°„λ³΅μž‘λ„λŠ” O(1)을 μ§€ν–₯ν•˜λŠ” μƒμˆ˜μ— κ°€κΉŒμš΄ 값이 λ‚˜μ˜€κ²Œ λœλ‹€.

  • λ°°μ—΄μ˜ 경우 νƒμƒ‰μ‹œ μ‹œκ°„λ³΅μž‘λ„λŠ” O(1)μ΄μ§€λ§Œ, λ©”λͺ¨λ¦¬λ₯Ό 미리 많이 ν• λ‹Ήν•΄ 두어야 ν•˜κΈ° λ•Œλ¬Έμ— κ³΅κ°„νš¨μœ¨μ μ΄λΌκ³  보기가 μ–΄λ ΅λ‹€.

  • 이런 ν•΄μ‹œ ν…Œμ΄λΈ”μ—λ„ 단점이 μžˆλŠ”λ°, λ°”λ‘œ ν•΄μ‹œ ν•¨μˆ˜κ°€ μ„œλ‘œ λ‹€λ₯Έ 두 개의 킀에 λŒ€ν•΄ λ™μΌν•œ ν•΄μ‹œκ°’μ„ λ‚˜νƒ€λ‚΄λŠ” 좩돌(collision)ν˜„μƒμ΄ μΌμ–΄λ‚œλ‹€λŠ” 것이닀.

  • 보톡 ν•΄μ‹œ ν…Œμ΄λΈ”μ„ μ‚¬μš©ν•˜λ©΄, *** ν•΄μ‹œ ν…Œμ΄λΈ”μ˜ 크기(m)κ°€ μ‹€μ œ μ‚¬μš©ν•˜λŠ” ν‚€ 개수(n)보닀 적어야 ν•˜λŠ”λ°(λ©”λͺ¨λ¦¬ λ¦¬μ†ŒμŠ€ 문제 λ“±), 이 λ•Œ n/m을 load factor(Ξ±)라고 λΆ€λ₯Έλ‹€. load factorκ°€ 클 수둝 ν•΄μ‹œ 좩돌 λ¬Έμ œκ°€ λ°œμƒν•  κ°€λŠ₯성이 λ†’μ•„μ§„λ‹€.


  • 좩돌 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ λ‚˜μ˜¨ 방법듀이 μ—¬λŸ¬κ°€μ§€κ°€ μžˆλŠ”λ°, λŒ€ν‘œμ μΈ 두 κ°€μ§€ μ•„μ΄λ””μ–΄λŠ” 뢄리 연결법(seperate chaining)κ³Ό 개방 μ£Όμ†Œλ²•(open addressing)이닀.

Separate_Chaining

[Serparate_Chaining](좜처 : ratsgo κΉƒν—™ λΈ”λ‘œκ·Έ)

  • λ¨Όμ € 뢄리 연결법을 μ‚΄νŽ΄λ³΄λ©΄ ν•˜λ‚˜μ˜ 버킷당 λ“€μ–΄κ°ˆ 수 μžˆλŠ” μ—”νŠΈλ¦¬μ˜ μˆ˜μ— μ œν•œμ„ 두지 μ•ŠμŒμœΌλ‘œμ„œ, λͺ¨λ“  자료λ₯Ό ν•΄μ‹œν…Œμ΄λΈ”μ— λ‹΄λŠ” 것이닀. ν•΄λ‹Ή 버킷에 이미 데이터가 μžˆλ‹€λ©΄ μ—°κ²° 리슀트 방식을 μ‚¬μš©ν•˜μ—¬ λ…Έλ“œμ™€ λ…Έλ“œλ₯Ό 체인처럼 μ—°κ²°ν•œλ‹€λŠ” μ˜λ―Έμ—μ„œ chainingμ΄λΌλŠ” μš©μ–΄κ°€ 뢙은 κ²ƒμœΌλ‘œ 보인닀. 이 λ°©λ²•μ˜ μž₯점은 μœ μ—°ν•˜λ©°, μ‚­μ œ 및 μ‚½μž…μ˜ μ‹œκ°„λ³΅μž‘λ„κ°€ O(1)으둜 λΉ λ₯΄λ‹€λŠ” 점이 μžˆλ‹€. 반면, 단점은 μ—°κ²° 리슀트 자체의 μ œν•œμ΄ μ—†λ‹€λ³΄λ‹ˆ μ˜€λ²„ν—€λ“œκ°€ 뢀담이 되고 λ©”λͺ¨λ¦¬ 문제λ₯Ό μ•ΌκΈ°ν•  수 μžˆλ‹€λŠ” 점이닀.
    • μ˜€λ²„ν—€λ“œ(overhead)λŠ” μ–΄λ–€ 처리λ₯Ό ν•˜κΈ° μœ„ν•΄ λ“€μ–΄κ°€λŠ” 간접적인 처리 μ‹œκ°„ Β· λ©”λͺ¨λ¦¬ 등을 λ§ν•œλ‹€.

Open_Addressing

[Open_Addressing](좜처 : ratsgo κΉƒν—™ λΈ”λ‘œκ·Έ)

  • 개방 μ£Όμ†Œλ²•μ€ ν•œ 버킷당 λ“€μ–΄κ°ˆ 수 μžˆλŠ” μ—”νŠΈλ¦¬κ°€ ν•˜λ‚˜λΏμΈ ν•΄μ‹œ ν…Œμ΄λΈ”μ΄λ‹€.
  • ν•΄μ‹œν•¨μˆ˜λ‘œ 얻은 μ£Όμ†Œκ°€ μ•„λ‹Œ, λ‹€λ₯Έ μ£Όμ†Œμ— 데이터λ₯Ό μ €μž₯ν•  수 μžˆλ„λ‘ ν—ˆμš©ν•œλ‹€λŠ” μ·¨μ§€μ—μ„œ open addressingμ΄λΌλŠ” 이름이 뢙은 κ²ƒμœΌλ‘œ 보인닀.
  • 이 λ°©λ²•μ˜ 경우, ν•΄μ‹œ 좩돌이 λ°œμƒν•˜λ©΄ (μ‚½μž…ν•˜λ €λŠ” ν•΄μ‹œ 버킷이 이미 μ‚¬μš©μ€‘μΈ 경우) λ‹€λ₯Έ ν•΄μ‹œ 버킷에 ν•΄λ‹Ή 자료λ₯Ό μ‚½μž…ν•œλ‹€.
  • 이 λ•Œ λ‹€λ₯Έ ν•΄μ‹œ 버킷을 μ°ΎλŠ” 탐사 과정을 probing이라고 ν•œλ‹€.
  • 뢄리 μ—°κ²°λ²•μ˜ μž₯점은 μΊμ‹œ 효율이 λ†’κ³  λ©”λͺ¨λ¦¬ λ¬Έμ œκ°€ λ°œμƒν•  κ°€λŠ₯성은 μ μ§€λ§Œ, ν•΄μ‹œ 좩돌이 λ°œμƒν•  κ°€λŠ₯성이 뢄리 연결법에 λΉ„ν•΄μ„œ λ†’μœΌλ©° νŠΉμ • ν•΄μ‹œκ°’μ΄ ν‚€κ°€ λͺ°λ¦¬κ²Œ 되면 νš¨μœ¨μ„±μ΄ κΈ‰κ²©ν•˜κ²Œ λ–¨μ–΄μ§„λ‹€λŠ” 단점이 μžˆλ‹€.

μ°Έκ³  => https://devowen.com/209


κΈ°μ‘΄ μΈλ±μ„œ μ½”λ“œμ—μ„œ Resizeλ₯Ό ν• λ•Œ ref ν‚€μ›Œλ“œμ‚¬μš©

  • ref ν‚€μ›Œλ“œλ₯Ό 톡해 μ€‘κ°„μ—μ„œ 배열을 λ³΅μ‚¬ν•˜λŠ” λ©”λͺ¨λ¦¬ λ‚­λΉ„λ₯Ό μ€„μ΄κ³ μž μ‚¬μš©μ„ ν–ˆμ§€λ§Œ μœ μ§€λ³΄μˆ˜ μΈ‘λ©΄μ—μ„œ 어떀것이 인자둜 듀어와 어떀것이 λ‚˜κ°€λŠ”μ§€ 확인이 μ–΄λ ΅κΈ° λ•Œλ¬Έμ— μœ μ§€λ³΄μˆ˜μƒ μ’‹μ§€ μ•Šλ‹€. λ”°λΌμ„œ μ •μ μ‹œν—˜μ—μ„œλŠ” refν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šλ„λ‘ 할것! => λ§€λ‰΄μ–Όμ—μ„œλ„ κ·Έλ ‡κ²Œ λ‚˜μ™€ μžˆλ‹€κ³  ν•˜μ‹¬.

for{...} λ‚΄λΆ€ λ³€μˆ˜ μ„ μ–Έ - μŠ€μ½”ν”„ κ΄€λ ¨


μ½”λ“œ 쀑간에 같은 μ΄λ¦„μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό ν™œμš©ν•  μ‹œ {} λ₯Ό 잘 ν™œμš©ν•˜λ©΄ νŽΈν•  수 μžˆλ‹€.


λ°•μ‹± & μ–Έλ°•μ‹±


Conqurent Queue


public class ConcurrentQueue<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection
  • μŠ€λ ˆλ“œλ‘œλΆ€ν„° μ•ˆμ „ν•œ FIFO(μ„ μž…μ„ μΆœ) λ°©μ‹μ˜ μ»¬λ ‰μ…˜μ΄λ‹€.

μ‚¬μš© 예제 μ½”λ“œ
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

class CQ_EnqueueDequeuePeek
{
   // Demonstrates:
   // ConcurrentQueue<T>.Enqueue()
   // ConcurrentQueue<T>.TryPeek()
   // ConcurrentQueue<T>.TryDequeue()
   static void Main ()
   {
      // Construct a ConcurrentQueue.
      ConcurrentQueue<int> cq = new ConcurrentQueue<int>();

      // Populate the queue.
      for (int i = 0; i < 10000; i++)
      {
          cq.Enqueue(i);
      }

      // Peek at the first element.
      int result;
      if (!cq.TryPeek(out result))
      {
         Console.WriteLine("CQ: TryPeek failed when it should have succeeded");
      }
      else if (result != 0)
      {
         Console.WriteLine("CQ: Expected TryPeek result of 0, got {0}", result);
      }

      int outerSum = 0;
      // An action to consume the ConcurrentQueue.
      Action action = () =>
      {
         int localSum = 0;
         int localValue;
         while (cq.TryDequeue(out localValue)) localSum += localValue;
         Interlocked.Add(ref outerSum, localSum);
      };

      // Start 4 concurrent consuming actions.
      Parallel.Invoke(action, action, action, action);

      Console.WriteLine("outerSum = {0}, should be 49995000", outerSum);
   }
}

λ‚˜μ€‘μ— μŠ€λ ˆλ“œ & νƒœμŠ€ν¬μ—μ„œ 책에 였λ₯˜κ°€ μžˆλ‹€. 예제λ₯Ό 톡해 ν•™μŠ΅ν•œ λ’€ μ—λŸ¬λ₯Ό μž‘μ•„λ³΄μž


yield ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν–ˆμ„λ•Œ Interfaceλ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ”μ΄μœ μ— λŒ€ν•΄μ„œ..

  • Program Counter(PC) κ°œλ…μ΄ λ“€μ–΄κ°€λŠ” 것 같은데 ν•œλ²ˆ μ°Ύμ•„λ³΄μž

  • λ°˜ν™˜ ν˜•μ‹μ΄ IEnumerable , IEnumerable<T> , IEnumerator λ˜λŠ” IEnumerator<T> λ©”μ„œλ“œμ— yield ν‚€μ›Œλ“œλ₯Ό λ„£μœΌλ©΄ λ°˜ν™˜ ν˜•μ‹ ( IEnumerable λ˜λŠ” IEnumerator )의 κ΅¬ν˜„μ„ μƒμ„±ν•˜λ„λ‘ μ»΄νŒŒμΌλŸ¬μ— μ§€μ‹œν•œλ‹€.

  • yield ν‚€μ›Œλ“œλŠ” 이둠적으둜 λ¬΄μ œν•œ μ‹œν€€μŠ€μ˜ "λ‹€μŒ"μš”μ†Œλ₯Ό λ°˜ν™˜ν•˜λ €λŠ” κ²½μš°μ— μœ μš©ν•˜λ―€λ‘œ 사전에 전체 μ‹œν€€μŠ€λ₯Ό 계산할 수 μ—†κ±°λ‚˜ λ°˜ν™˜ν•˜κΈ° 전에 전체 κ°’ μ‹œν€€μŠ€λ₯Ό 계산할 경우 μ‚¬μš©μžμ—κ²Œ λ°”λžŒμ§ν•˜μ§€ μ•Šμ€ μΌμ‹œ 쀑지가 λ°œμƒν•  수 μžˆλ‹€.

  • yield break λŠ” λ˜ν•œ μ–Έμ œλ“ μ§€ μ„œμ—΄μ„ μ’…κ²°ν•˜λŠ”λ° μ‚¬μš©λ  수 μžˆλ‹€.

  • yield ν‚€μ›Œλ“œλŠ” IEnumerable<T> 와 같은 λ°˜ν™˜ μœ ν˜•μœΌλ‘œ 반볡기 μΈν„°νŽ˜μ΄μŠ€ μœ ν˜•μ„ μš”κ΅¬ν•˜κΈ° λ•Œλ¬Έμ— Task<IEnumerable<T>> 객체λ₯Ό λ°˜ν™˜ν•˜λ―€λ‘œ 비동기 λ©”μ„œλ“œμ—μ„œλŠ” 이λ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€.