using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public int solution(int[] rank, bool[] attendance) {
int answer = 0;
Dictionary<int, int> dic = new Dictionary<int, int>();
for (int i = 0; i < rank.Length; i++)
{
if (attendance[i])
dic.Add(rank[i], i);
}
List<int> list = dic.Keys.ToList();
list.Sort();
answer = dic[list[0]] * 10000 + dic[list[1]] * 100 + dic[list[2]];
return answer;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public int[] solution(int[] arr, int[,] queries) {
var answer = new List<int>();
for (int i = 0; i < queries.GetLength(0); i++)
{
int min = arr.Max()+1;
for (int j = queries[i, 0]; j <= queries[i, 1]; j++)
{
if (arr[j] > queries[i, 2] && arr[j]< min)
min = arr[j];
}
if (min == arr.Max() + 1) min = -1;
answer.Add(min);
}
return answer.ToArray();
}
}
using System;
//+1
public class Solution {
public int[,] solution(int n) {
int[,] answer = new int[n,n];
string [,] answer2 = new string[n,1];
int num = 1;
for (int x = 0; x < n; x++)
{
for (int y = 0; y < n; y++)
{
answer[x,y] = -1;
}
}
for (int i = 0; i < n; i++)
{
//왼 >> 오
for (int r = i; r < n - i; r++)
{
if (answer[i,r] == -1)
answer[i,r] = num++;
}
//위 >> 아래
for (int d = 1; d < n - i; d++)
{
if (answer[d,n - i - 1] == -1)
answer[d,n - i - 1] = num++;
}
//오 >> 왼
for (int l = n - i - 1; 0 <= l; --l)
{
if (answer[n - i - 1,l] == -1)
answer[n - i - 1,l] = num++;
}
//아래 >> 위
for (int u = n - i - 1; 0 < u; --u)
{
if (answer[u - 1,i] == -1)
answer[u - 1,i] = num++;
}
}
for(int x =0; x < n; x++)
{
for(int y =0; y < n; y++)
{
if (y != 0) answer2[x, 0] += ",";
answer2[x, 0] += + answer[x, y];
}
}
return answer;
}
}
주변 친구들이 문제를 풀 때 나도 언젠가는 저렇게 잘 풀고 싶다는 마음을 갖고 지금까지 왔다.
일단 지금까지 푼 프로그래머스 문제들 329개. 점수는 1689점이다. 아직 한참 멀었다. 역시나 나에게 코딩 테스트는 너무나 어렵다. 도대체 사람들은 얼마나 좋은 머리를 가지고 세상을 살아가고 있는 걸까.
그래도 처음보단 점차 나아지고 있으니까 지금 이 순간보단 나은 내가 되어 가길 희망한다.
블로그를 시작하며 몇 가지 문제들을 정리해서 저장해 둘 생각이다. 0단계에서부터 2단계까지의 문제들을 풀었었고,
가장 높은 점수를 봤던 게 21점이랑 17점이었던 것 같다. 처음엔 10점 이상의 점수가 나오는 문제들도 신기했었다. 그러다 21점이랑 17점이 나와서 아주 놀랐던 기억이 있다. 지금 생각해 보면 그 정도 점수였으면 문제가 뭐였는지 기억이라도 해뒀어야 했던 게 아닌가 싶다. 아마 그땐 이 점수의 끝이 어디까지였는지 예측이 안됬던 상태가 아니었나 싶다. 내가 다시 높은점의 점수를 만날 수 있을까? 열심히 풀어보자.
특별한(발전된 형태의) SDRAM, 최근 가장 대중적으로 사용하는 RAM. 대역폭을 넓혀 속도를 빠르게 만든 SDRAM. 대역폭은 데이터를 주고받을수 있는 길의 너비
DRAM
SRAM
재충전
필요함
필요없음
속도
느림
빠름
가격
저렴함
비쌈
집적도(오밀조밀 꽉꽉)
높음
낮음
소비 전력
적음
높음
사용 용도
주기억장치(RAM)
캐시메모리
메모리의 주소 공간
(물리 주소 & 논리 주소)
CPU와 실행중인 프로그램은 현재 메모리 몇 번지에 무엇이 저장되어 있는지 알고 있을까?
NO. 메모리에 저장된 값들은 시시각각 변하기 때문. - 새롭게 실행되는 프로그램은 새롭게 메모리에 적재 - 실행이 끝난 프로그램은 메모리에서 삭제 - 같은 프로그램을 실행하더라도 실행할 때마다 적재되는 주소는 달라짐.
이러한 점을 극복하기 위해 주소 체계를 물리주소와 논리 주소로 나눈다.
물리 주소
논리 주소
메모리 입장에서 바라본 주소 말 그대로 정보가 실제로 저장된 하드웨어상의 주소
CPU와 실행 중인 프로그램 입장에서 바라본 주소. 실행중인 프로그램 각각에게 부여된 0번지부터 시작하는 주소
물리 주소와 논리 주소의 변환
CPU와 메모리 사이에 있는 MMU(메모리 관리 장치)라는 하드웨어에 의해 논리주소는 물리 주소로 변환. CPU가 이해하고 실행하는 주소는 전부 논리주소. MMU는 논리주소와 베이스 레지스터(프로그램의 기 주소, 시작 주소)값을 더하여 논리 주소를 물리 주소로 변환함.
*베이스 레지스터 : 프로그램의 가장 작은 물리 주소(프로그램의 첫 물리 주소)를 저장하는 셈. *논리 주소 : 프로그램의 시작점으로 부터 떨어진 거리 인 셈. CPU가 접근하려는 논리 주소는 한계 레지스터가 저장한 값보다 커서는 안됨.
메모리 보호 기법
1. 한계 레지스터 :
- 프로그램의 영역을 침범할 수 있는 명령어의 실행을 막음.
- 베이스 레지스터가 실행중인 프로그램의 가장 작은 물리 주소를 저장한다면, 한계 레지스터는 논리 주소의 최대 크기를 저장.
2. 주소범위 제한:
- 프로그램의 물리 주소 범위는 베이스 레지스터 값 이상에서부터 베이스 레지스터 값에 한계 레지스터 값을 더한 값 미만까지로 제한된다.
- 베이스 레지스터 값 <= 프로그램의 물리 주소 범위 < 베이스 레지스터 + 한계 레지스터 값
>> CPU는 메모리에 접근하기 전, 접근하고자 하는 논리 주소가 한계 레지스터보다 작은지를 항상 검사한다. 만약 검사를 했는데 논리 주소가 한계레지스터가 크면 인터럽트(트랩)를 발생시킨다. 이런 메모리 보호 기법을 통해 실행중인 프로그램의 독립적인 실행 공간을 확보하고, 하나의 프로그램이 다른 프로그램을 침범하지 못하게 보호한다.
CPU가 메모리에 접근하는 시간은 CPU 연산 속도보다 느리다.
저장 장치 계층 구조(memory hierarchy) : CPU에 얼마나 가까운가를 기준으로 계층적으로 나타낼수 있음
1. CPU와 가까운 저장 장치는 빠르고, 멀리 있는 저장 장치는 느리다.
2. 속도가 빠른 저장 장치는 저장 용량이 작고, 가격이 비싸다.
메모리 저장 장치 계층 구조
캐시 메모리
- CPU와 메모리 사이에 위치한, 레지스터보다 용량이 크고 메모리보다 빠른 SRAM기반의 저장장치
- CPU의 연산 속도와 메모리 접근 속도의 차이를 조금이나마 줄이기 위해 탄생.
- CPU가 매번 메모리에 왔다 갔다 하는 건 시간이 오래 걸리니, 메모리에서 CPU가 사용할 일부 데이터를 미리 캐시 메모리로 가지고 와서 쓰자.가 캐시메모리의 취지.
메모리에 접근 == 물건을 사러가는 것이라 생각하면, 메모리 == 물건은 많지만 집(CPU)과는 멀리떨어져 있어 왕복이 오래 걸리는 대형 마트 캐시메모리 == 물건이 많지는 않아도 집(CPU)과 가까이 있는 편의점 이라 생각해보면 된다.
캐시메모리는 하나가 아님. 계층적으로 구성할수 있음. CPU내부에 있을수도 외부에 있을 수도 있음.
계층적 캐시 메모리(L1 - L2 - L3 캐시) - 일반적으로 L1캐시와 L2캐시는 코어 내부에, L3캐시는 코어 외부에 있다.
L3캐시의 용량은 메모리보다 작지만, L1과 L2캐시보단 크다.
계층적 캐시 메모리까지 반영한 저장 장치 계층 구조
참조 지역성의 원리 : CPU가 미래에 원하는 데이터를 예측하여 속도가 빠른 장치인 캐시 메모리에 담아 놓는데 이때의 예측률을 높이기 위하여 사용하는 원리 >> CPU가 사용할 법한 데이터를 예측하는 방법.
- 캐시 메모리는 메모리보다 용량이 작다. 당연하게도 메모리의 모든 내용을 저장할 수 없다.
따라서, CPU가 자주 사용할 법한 내용을 예측하여 저장함.
캐시 히트
예측이 들어맞을 경우(자주 사용할 것으로 예측한 데이터가 실제로 들어맞아 CPU가 캐시메모리에 저장된 값을 활용할 경우) >> 이 경우엔 메모리에 접근하는 것보다 성능이 높아짐
캐시 미스
예측이 틀렸을 경우(자주 사용할 것으로 예측하여 메모리에 저장했지만 예측이 틀려 CPU가 메모리에 접근해야 하는 경우) >> 성능 하락!
캐시 적중률
캐시 히트 횟수 / (캐시히트횟수 + 캐시미스 횟수) >> 적중률이 높으면 높을 수록 성능 높아짐.
참조 지역성의 원리란, CPU가 메모리에 접근할 때의 주된 경향을 바탕으로 만들어진 원리.
CPU의 주된 경향 2가지 - CPU는 최근에 접근 했던 메모리 공간에 다시 접근하려는 경향(시간 지역성)이 있다. - CPU는 접근한 메모리 공간 근처를 접근하려는 경향(공간 지역성)이 있다.