728x90

Brute force(브루트 포스)란 컴퓨터 과학과 암호학에서 사용되는 용어로, 가능한 모든 경우의 수를 하나씩 대입해가며 해답을 찾는 방법을 의미

이 방법은 주로 암호 해독이나 비밀번호 크래킹 등의 분야에서 사용되며, 무차별 대입 공격이라고도 함

 

브루트 포스 공격은 특정 알고리즘이나 시스템의 취약점을 이용하지 않고 단순히 모든 가능한 조합을 시도함으로써 목표를 달성하는 방식임

쉽게 예를 들면 비밀번호를 찾기 위해 모든 가능한 문자 조합을 하나씩 시도하여 맞추는 경우가 있음

 

브루트 포스의 장점은 시스템이나 알고리즘의 구조에 대한 깊은 이해가 필요 없고, 모든 경우의 수를 시도하기 때문에 성공 확률이 높다는 것임

반면, 단점으로는 매우 많은 시간과 자원이 소모된다는 점이 있음

 

현대의 많은 시스템에서는 이러한 브루트 포스 공격을 방어하기 위해 비밀번호의 길이를 길게 하거나, 복잡한 암호화 알고리즘을 사용함

728x90

'Computer Science' 카테고리의 다른 글

지역 심벌과 전역 심벌  (0) 2024.07.24
링커란?  (0) 2024.07.17
컴파일 언어와 인터프리터 언어 비교  (0) 2024.07.10
스택(stack)과 힙(Heap)  (0) 2024.03.27
명령형 프로그래밍 vs 선언형 프로그래밍  (0) 2024.03.02
728x90

스택(Stack)과 힙(Heap)은 프로그래밍에서 중요한 메모리 구조임

이들은 데이터를 저장하고 관리하는 데 사용되며, 주로 컴퓨터 프로그램의 실행 중에 데이터를 저장하는 데 쓰임

여기에서는 이 두 가지 구조의 기본적인 개념과 차이점에 대해 설명할 예정

스택(Stack)

스택은 후입선출(LIFO, Last In, First Out)의 구조를 가진 메모리 영역

이는 마치 접시를 쌓는 것처럼, 마지막에 들어온 데이터가 먼저 처리되는 구조

  • 특징
    • 구조: 스택은 선형 자료구조로, 데이터가 일렬로 쌓여있는 형태로, 맨 위에 있는 요소에만 접근 가능
    • 연산: 스택에는 데이터를 스택에 추가하는 "push"와, 스택에서 데이터를 꺼내는 "pop"이라는 두 가지 연산이 존재
    • 메모리 할당방식: 정적 메모리 할당을 사용하여 크기가 컴파일 시에 결정됨
    • 용도: 함수 호출 시에 지역 변수, 매개변수, 반환 주소 등을 저장하는 데 사용되며, 재귀 알고리즘의 실행 흐름을 관리하는 데에도 사용
  • 장점
    • 빠른 접근 속도: 메모리에 연속적으로 저장되어 있으므로, 데이터에 빠르게 접근 가능
    • 간편한 관리: 후입선출구조로인해 데이터의 추가와 삭제가 간단하며 메모리 관리에 용이
    • 스택프레임: 함수 호출 시에 지역변수와 매개변수를 저장하는 스택 프레임을 통해 함수의 호출과 반환을 효율적으로 관리 가능
  • 단점
    • 크기 제한: 스택의 크기는 컴파일 시에 결정되므로 런타임 시에 동적으로 조정이 불가 → 정적으로 할당된 메모리의 한계로 인해 스택오버플로우가 발생 가능
    • 임시저장만 가능: 스택은 임시데이터를 저장하는 데 사용되므로, 장기적인 데이터 보관에는 적합하지 않음
# 파이썬 리스트를 이용한 스택 구현 예시
class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        if self.is_empty():
            return None
        return self.stack.pop()

    def peek(self):
        if self.is_empty():
            return None
        return self.stack[-1]

    def is_empty(self):
        return len(self.stack) == 0

# 스택 테스트
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)

# 스택은 무조건 가장 나중에 삽입한 값부터 반환함
print("스택의 맨 위 항목:", stack.peek())  # 출력: 3
print("스택에서 팝된 항목:", stack.pop())  # 출력: 3
print("스택의 맨 위 항목:", stack.peek())  # 출력: 2

 

힙 (Heap)

힙은 메모리의 동적 할당 영역으로 데이터의 저장 및 관리를 위해 사용됨

힙은 데이터를 임의의 순서로 저장하며 메모리가 동적으로 할당되고 해제됨

맨 위의 요소에만 접근 가능한 스택과는 달리, 힙은 임의의 요소에 접근이 가능함

  • 특징
    • 구조: 힙은 트리 형태의 자료구조로, 노드들이 부모-자식 관계로 연결되며, 각 노드는 일반적으로 특정한 데이터를 저장
    • 연산: 힙은 데이터를 삽입하는 "insert" 연산과, 삭제하는 "delete" 연산이 존재
    • 메모리 할당방식: 동적 메모리 할당을 사용하여 런타임 중에 크기가 결정됨
    • 용도: 동적으로 크기가 변하는 데이터 구조를 관리하는 데 사용되며, 주로 동적으로 할당된 객체나 배열, 그래프 등을 저장하기 위해 활용
  • 장점
    • 동적 할당: 힙은 런타임 중에 메모리를 동적으로 할당하므로, 유연한 데이터 구조를 생성 가능하며 크기제한이 없음
    • 오랜 기간 데이터 보존 가능: 힙은 데이터의 수명이 프로그램의 실행 시간 동안 지속되므로, 장기적인 데이터 보존이 가능함
  • 단점
    • 메모리 누수: 메모리 해제를 제대로 처리하지 않으면 메모리 누수가 발생할 수 있음
    • 접근 시간: 힙은 트리 구조로 데이터에 접근하는 데에 추가적인 시간이 소요될 수 있음
    • 효율성: 동적할당 및 해제 작업은 상대적으로 오버헤드가 크므로, 스택에 비해 느릴 수 있음
# 파이썬 heapq 모듈을 이용한 힙 구현 예시
import heapq

heap = []
heapq.heappush(heap, 5)
heapq.heappush(heap, 2)
heapq.heappush(heap, 7)

# 마지막 삽입한 값이 아닌 값 반환 가능 (heapq.heappop 함수는 힙에서 가장 작은 값을 삭제하고 반환)
print("힙에서 팝된 최소 항목:", heapq.heappop(heap))  # 출력: 2
print("힙에서 팝된 최소 항목:", heapq.heappop(heap))  # 출력: 5

 

728x90
728x90

명령형 프로그래밍

프로그램이 어떻게 작업을 수행할지를 명시적으로 정의하는 방식

상태와 상태를 변경하는 명령어들의 연속으로 구성됨

프로그램이 어떤 작업을 수행해야 하느지 단계별로 기술하며, 컴퓨터에게 명령을 내리는 개념

# 리스트에서 짝수를 찾아 제곱한 후 새로운 리스트에 저장하는 명령형 코드
numbers = [1, 2, 3, 4, 5]
squared_evens = []

for num in numbers:
    if num % 2 == 0:
        squared_evens.append(num ** 2)

print(squared_evens)
  • 장점
    • 직관성, 가독성 : 일반적으로 작업이 어떻게 수행되는지 명확히 보여줌
    • 효율적인 메모리 사용 : 상태를 직접 조작하므로 메모리 효율적 사용에 유리
    • 직접적인 제어 : 작업의 세부사항에 대한 직접적인 제어를 제공하므로 세밀한 최적화가 가능
  • 단점
    • 복잡성 : 코드가 상태를 직접 조작하면서 복잡성이 증가할 수 있음
    • 변수 상태 관리 : 변수상태를 올바르게 관리하지 않으면 버그가 발생할 수 있음
    • 유지보수 어려움 : 코드가 어떻게 동작할지 이해하기 어려울 수 있어 유지보수가 불리

선언형 프로그래밍

프로그램이 무엇을 수행할지를 명시적으로 정의하는 방식

어떤 작업을 어떻게 수행할지를 명시하지 않고, 목표를 기술하는 방식

더 추상화되고 선언적인 방식으로 문제를 해결하며, 내부적으로 시스템이 어떻게 동작하는지를 숨김

함수형 프로그래밍은 선언형 프로그래밍의 대표적인 예시

# 리스트에서 짝수를 찾아 제곱한 후 새로운 리스트에 저장하는 선언형 코드 (리스트 컴프리헨션 사용)
numbers = [1, 2, 3, 4, 5]
squared_evens = [num ** 2 for num in numbers if num % 2 == 0]

print(squared_evens)
  • 장점
    • 간결성 : 코드가 더 짧고 간결하며, 목적에 집중할 수 있음
    • 추상화와 모듈화 : 작업을 높은 수준에서 추상화하고 모듈화하므로 코드를 이해하고 재사용하기 쉬움
    • 병렬처리 용이 : 함수형 프로그래밍의 특징인 불변성과 순수 함수는 병렬처리를 쉽게 만들어줌
  • 단점
    • 초기 학습이 어려움
    • 최적화 어려움 : 목표를 선언하는 것은 좋지만 내부 동작을알기 어려워 최적화가 어려울 수 있음
    • 메모리 사용량 증가 가능성 : 함수형 프로그래밍에서 불변성을 유지하려면 새로운 데이터 구조를 계속 생성해야하므로 메모리 사용량이 증가할 수 있음
728x90

'Computer Science' 카테고리의 다른 글

지역 심벌과 전역 심벌  (0) 2024.07.24
링커란?  (0) 2024.07.17
컴파일 언어와 인터프리터 언어 비교  (0) 2024.07.10
Brute force(브루트 포스)란?  (0) 2024.07.09
스택(stack)과 힙(Heap)  (0) 2024.03.27

+ Recent posts