-
24년 5월 1일 TIL공부 기록 2024. 5. 2. 00:05
컬렉션에 대해서
컬렉션은 배열과 비슷한 데이터보관 방법이다. 컬렉션은 선언과 동시에 초기화를 해줘야 하고, namespace.Collection을 선언 해줘야 한다. 배열은 Length가 있지만 Collection은 없다. Count를 사용 해줘야 한다. 컬렉션은 여러가지가 있지만 대표적으로 5개를 많이 사용 한다.
먼저 ArrayList이다.
Add. 등으로 인덱스를 추가 하고 Remove 등으로 추가 돼 있는 것을 삭제 할 수 있다. 그리고 다른 여러가지 기능들도 있다.
배열과 다른 점은 값이 고정 돼 있지 않아, 유연 하게 사용 할 수 있다는 것이다.
배열은 만들어줄 때 몇 개의 배열로 만들 것인지 정하는데 컬렉션 같은 경우는 정해주지 않아도 된다. 넣는 만큼 생긴다.
그리고 ArrayList의 경우 추가를 하는 자료형의 종류도 따로 정해져 있지 않다. int자료형, string 자료형 등 아무거나 막 추가를 할 수 있다. 이렇듯 컬렉션의 ArrayList는 사용자에게 편의성을 제공 해주지만 주의 해야 할 점이 있다.
ArrayList의 경우 자료형의 형태 상관 없이 아무거나 넣을 수 있어서 편하지만, 애초에 메모리 자체가 크고, 자료를 넣을 때마다 엄청나게 많은 연산, 뺄 때도 연산, 등 엄청나게 많은 연산을 하게 되고 다른 메모리구조보다 많은 과부화를 줄 수 있게 된다. 이 부분을 유의 하면서 사용을 해야 한다. 이러한 점을 보완 해서 만들어진 게 List 이다.
List
ArrayList와 기능은 거의 동일하다고 보면 된다. 차이점은 ArrayList를 제너릭 형태로 만든 것이라고 생각 하면 된다.
List< 자료형 > list = new List < 자료형 > 이렇게 선언을 하고 사용 한다. 사용법은 ArrayList와 동일 하다.
컬렉션의 기능들
RemoveRange( 1, 5) -> Index 1번 부터 5번까지 한 번에 제거 하는 기능
RemobeAt(3) -> 3번 쨰 인덱스를 지움
Clear -> 인덱스를 모두 지운다.
Contains -> 특정 값이 있는지 확인 할 수 있는 메서드다. true와 false 값을 받을 수 있다.
Equals -> 특정 값과 같은지 아닌지 확인 할 수 있는 메서드다.
Insert ( 1, 5 ) -> 1번 뒤에 5라는 값을 추가 시킨다.
IndexOf - > 인덱스를 통해서 특정값을 불러올 수 있다.
이 말고도 여러 기능들이 있다.
그리고 Collection에는 List와 ArrayList 말고도 자주 쓰는 것이 또 있다. HashTable 이다.
HashTable
다른 Collection과 비슷 하지만 다른 점이 있다.파라미터를 입력 할 때 2개의 값을 넣어줘야 한다. Add(" 원강나이 ", 27) 이런 식으로 넣어주어야 한다. 그리고 이 차이로 인해 List와 ArrayList와 사용법이 달라진다.
List나 ArrayList는 사용 할 때 보통 인덱스의 번호를 통해 호출을 하게 되는데 HashTable은 파라미터 첫 번째 값으로 호출을 한다. HashTable["원강나이"] 이렇게 하면 27이 나오는 것이다. 이것을 키값을 통해 찾는 다고 한다. 그 외에는 다른 것과 유사하다.
그리고 HashTable 또한 자료형을 마음대로 넣을 수 있게 되는데 위와 같이, 사용 할 때마다 다른 것보다 많은 연산을 하게 된다. 그래서 이것 또한 제너릭 형태로 만들어진 것이 있다. 그것이 바로 Dictionary다.
Dictionary
HashTable 과 거의 동일 하다고 보면 된다. 제너릭 형태로써 사용 할 때 자료형만 정해주면 된다.
형식)
Dictionary< 자료형, 자료형 > list = new Dictionary<자료형, 자료형>() ;
list.Add( 자료형, 자료형)
ArrayList와 HashTable이 사용하기에는 쉬울 것이지만 과부화 및 연산 속도에 차이가 있기 때문에 적절히 설계를 잘 해줘야 할 것이다.
그리고 다른 방식으로 사용 되는 Collection이 있다. Queue와 Stack을 말한다.
이 것들은 참조는 못 하고 넣고 빼는 것만 가능 한데 Queue는 선입선출형 방식, Stack은 후입선출형 방식으로 사용 된다.
얘네는 자료형을 명시를 안 해도 된다.
그리고 두 가지는 넣고 빼는 기능들의 이름이 다르다. Queue는 Enqueue로 값을 넣고, Dequeue로 값을 빼준다.
Stact은 Push로 값을 넣어주고 Pop으로 빼준다.
형식)
Queue<int> qu = new Queue<int>();
qu.Enququ( 5); -> 5라는 숫자가 첫 번째로 들어감. qu.Dequeue() -> 첫 번째로 들어간 값이 나온다.
이 때 앞에 인덱스가 빠져 나가면 Queue에 인덱스들은 앞으로 한 칸씩 땡겨간다.
그리고 여기서 Queue 에 주의점이 있다. 인덱스가 없는 경우에 Dequeue를 하게 되면 오류가 생긴다. 이 부분을 보완 해줘야 한다.
if ( qu.Count != 0) 을 사용 해서 코드를 보완 해주도록 하자.
그리고 Stact 또 한 사용법이 Queue와 동일 하다고 볼 수 있다.
Stact<int> sat = new Stact<int>();
sat.Push(6) -> 6이란 값이 첫 번 째로 들어감. sat.Pop() -> 마지막에 들어간 순으로 빠진다.
Queue와 Stact 같은 Collection은 어떻게 사용 해야 할지 감이 안 올 수가 있다. 보통 먼저 들어간 게 먼저 빠져야 하는 구조를 만들 때, 예를 들면 손님 대기줄 같은 것을 구현 할 때 Queue를 사용 하면 될 것이고, 탄창 같은 것을 만들 때 나중에 넣은 것이 먼저 빠지는 것을 구현 할 경우에 Stact을 사용 하면 될 것이다.
Collection은 배열과의 메모리사용이 차이가 있을 수 있다고 하는데, 요즘은 거의 없다고 보는 게 맞다고 한다. 하지만 아무래도 메모리 구조면에서 배열이 더 빠른 건 있다.
namespace에 대해서
Class들의 집합이 namespce다. 우린 이 namespace를 using을 통해 가져와서 다른 사람들이 미리 만들어둔 기능들을 사용 할 수 있는 것이다.
형식)
namespace 이름{ }
우리가 이 공간에 class들을 만들고 여러 Mathod들을 만들어 주고, 이 namespace를 가져와 내가 만든 기능들을 다른 곳에서도 사용 할 수 있을 것이다.
그리고 namespace 안에 namespace를 또 만들 수 있다.
왜 사용 하는지 감이 안 올 수가 있는데, 나중에 정말 큰 프로젝트를 하고 많은 사람과 협업을 할 경우에 필요 해진다.
왜냐하면 사람들마다 엄청 많은 Class들을 만들 것이고 그것들에 이름이 완전 똑같은 경우가 있을 수 있다.
이러면 한 쪽이 전부 바꾸던가 해야 한다. 하지만 그러지 않고 namespace를 사용 하면 간단하게 해결 할 수 있게 된다.
namespace Oneriver
{Class Person{};
}
namespace Tworiver
{
Class Person{};
}
이렇게 똑같은 Class를 갖고 있다면, 객체를 생성 할 때 Oneriver.Person 이런 식으로 가져와서 중복문제를 간단 하게 피할 수 있게 된다.
만약 namespace안에 namespace를 만들어 줬고, 안에 있는 namespce에 있는 Class를 가져오고 싶은 경우, 객체를 생성 할 때 안에 있는 namespace로 가져와 주면 된다.
namespace Oneriver
{
namespace Tworiver
{
Class Person{};
}
}
using Oneriver.Tworiver <- using 문 선언
person = new Tworiver.Person();
이렇게 작성을 해주면 된다.
Action과 Fuc 에 대해서
우린 Deligate를 사용 할 때 public Deligate void Deligat 어쩌구 저쩌구 복잡하게 만들어서 사용을 했다.
이걸 되게 간단하게 해주는 것이 Action과 Fuc이다.
Action과 Fuc는 Deligat 형식을 만들어 주는 것이다. 우리가 했던 건 직접 형식을 만든 것이다.
이 Action과 Fuc 또한 누군가 미리 만들어둔 기능이다. 우린 변수 선언만 하면 된다.
Action은 일반적으로 사용 하면 되고, 반환형식이 필요 할 때 Fuc를 사용 하면 된다. 그리고 둘 다 <T>, Genarics 형태도 사용을 할 수가 있다.
형식)
Action() deligate ;
deligate += Sum();
이렇듯 매우 간단하게 deligate 형식을 만들 수 있게 된다. 굳이 직접 deligate 형식을 만드는 경우는 거의 없다.
예외처리 에 대해서
우린 코드를 작성 하다 보면 오류가 발생 할 수 밖에 없는 일이 생길 수 있다. 그럴 때 오류를 출력 하는 대신 다른 걸 실행 하게 할 수가 있다. 그것을 예외처리 해준다고 한다.
형식)
try { 오류 발생 원인의 코드 }
catch ( 오류명 변수명 ) {} < - 여러 개 선택 할 수 있다./ 여기에 선택 된 오류가 실행 됐을 경우 오류 대신, 안에 적은 코드가 실행 될 것이다. 그리고 변수명은 일반적으로 ie로 적는 게 관례이다.
{ 오류 대신 구현 할 행동 }
finallry { 코드 } finallry 는 오류가 나오든 말든 무조건 실행 되게 하는 Mathod 다.
예외처리를 해줌으로써 오류 없는 플레이를 할 수 있게 해준다. 그리고 각각의 오류들마다 다르게 실행을 할 수도 있다.
오류들이 뭐뭐 있는지도 알아야겠다. NullReference는 비었다는 뜻... zero어쩌구는 0때문에 오류..,
그리고 일부러 오류를 일부로 일으키게 하는 Mathod도 있다. 알아만 두자. 쓰로우 머시기였는데..,
값형과 참조형 에 대해서
개념을 잡기가 어렵다. 비교만 알아두자.
값형은 값을 줄 때 본인의 값을 복사해서 넘겨준다.
참조형은 본인이 참조 하고 있는 주소를 준다.
참조형은 값이 바뀌면 같이 바뀌고, 값형은 복사 된 다른 메모리이므로 같이 변하지 않는다.
값형의 대표주자는 Struct, 참조형의 대표주자는 Class.
Class 외에는 거의 다 값형이라고 생각 하면 편하다.
물론 제대로 알고 있다면 좋을 것이다. 하지만 그럴려면 심화적인 지식이 필요하다.. 난 멀었다.
박싱과 언박싱
값형을 참조형으로 바꾸는 것이 박싱, 참조형을 다시 값형으로 바꾸는 것이 언박싱이다.
그런데 박싱과 언박싱이 반복이 되는 것 자체가 성능에 영향을 준다.
그리고 참조형이 됐을 경우 가비지컬렉터가 데이터를 삭제 할 수도 있다. 참조형 자체가 많으면 좋지 않다.
그러니 굳이 사용 하려고 하지 말고 박싱, 언박싱이 일어나게 코드를 짰을 경우 수정을 해주거나 최대한 박싱과 언박싱이 생기지 않게 코드를 설계 해주는 것이 좋다.
LINQ 에 대해서
Linq에 대해서 공부를 하려다 나의 담당 1찐 튜터님이 그런 건 배우지 않아도 된다고 하셨다. 가독성을 되게 좋게 하고, 간단하게 코드를 작성 할 수 있지만 사용 하지 않는 것이 좋다고 하셨다.
나는 처음에 성능이 저하 된다고 들었는데 그것 때문인가라고 물었다. 아니라고 한다. 성능도 요즘엔 떨어진다고 보기 어렵다고 하셨다. 그런데 왜 사용을 하면 안 되는 것이냐.
그것은 바로 사람들이 사용 하는 방식 때문이다.
이 LINQ 자체가 개발자들을 편하게 만들어 주려고 만든 것인데 성의 없는 개발자들이 자기들 마음대로 남용을 해서 오히려 더 힘들어졌다고 한다. 쉽게 말 해 쓰는 사람 본인만 편하다는 것이다.
그래서 튜터님은 LINQ 에 대해 기본적으로 좋지 않게 생각을 하고, 그건 현업에 갔을 때 시니어분들도 마찬가지일거라고 하셨다. 그래도 정 사용 하고 싶을 때가 생길 것이라고, 몇 가지 사용 해도 되는 것들을 알려 주셨다.
첫 번째 first다. 조건에 맞는 거 제일 먼저 하나 가져 오는 기능이다.
ex) list가 있고 아이템 17번을 갖고 오고 싶은데 막 섞여 있고 찾기 힘들 때 아이템 1231번인 걸 찾아라 이런 느낌.
주의 할 점은 값을 갖고 오라고 했는데 없을 경우 오류가 생긴다.
그래서 first or defalut 를 사용 한다. 이건 값이 없을 경우 null이 나온다. 이건 쓰면 좋다고 한다.
내 담당일찐 튜터님도 이건 쓴다고 한다.
두 번째 Select다. 어떠한 조건에 따라서 그 조건에 맞을 경우 특정 값을 갖고 오게 할 수가 있다.
어떤 값에서 새로운 값으로 바꿔 주는 것. 맵핑 함수 라는 개념과 비슷하다.
아이템이 엄청 많이 있는데 어떤 조건에 맞는 것만 어떠한 값을 갖고 온다. 이게 select다. 대충 적겠다.
세 번째 where 이 것도 굉장히 편하다고 한다. 필터링 하는 것이다. list나 뭐 데이터에서 필터에 맞는 것만 가져와라 이런 느낌이다.
네 번째 OrderBy 이 건 정렬 하는 것이다. 특정한 기준에 정렬한다. 목록을 정렬 하는 기능.
이렇게 총 4개를 알려주셨는데 튜터님이 말씀대로 사용 하는 건 별로 좋지 않을 것 같다. 그러니 LINQ란 데이터들을 정렬 및 필터 등을 이용해서 정리 해주는 것이다. 라는 정도만 알고 있자. 글을 대충 적은 이유와 같다.
구구절절한 데이터 로직을 간단 하게 만들어 줄 수 있는 구문.
out 에 대해서
out은 return 과 비슷한 기능이다. 하지만 out은 뒤에 오는 것에 반환을 해준다. TryParse에서 out 이 사용 되는 것도 이 이유다. (return은 뒤에 오는 것을 반환)
이 점을 이용 해서 Mathod를 이용 할 때 parameter에 out 을 사용 하면 값형인 데이터의 값을 변경 해줄 수 있다.
ex)
void Aaaa( int a, int b, out Asdf, out dss)
{
Asdf = a * b;
dss = a / b;
}
Start()
{
int num;
int num2;
Aaaa( 10, 5, out num, out num2);
}
이렇게 하면 원래는 바뀌지 않는 num과 num2가 out을 통해 값을 반환 받아서 값이 바뀌게 된다.
주의 할 점은 parameter에 out 형식을 사용 하게 되면 Mathod 안에서 값을 할당 하게 해야한다. 반환형식이기 때문이다.
ref 에 대해서
ref도 parameter에 값을 넣어줄 때 많이 사용 하는데 특이한 점은 값을 넘기는 게 아니라 주소를 넘겨주는 거라고 생각 하면 된다. 그렇기에 위에 적은 out 예시 처럼 필드의 값도 바뀌게 할 수가 있다. 차이점은 주소를 넘긴 다는 것!
보통 swap Mathod를 따로 만들어서 사용 한다. a와 b의 값이 바뀌게 하는 것.
Nullable 연산자 에 대해서
우린 자료형을 사용 할 때 값이 null인 경우가 있을 수 있다. 이 경우 오류가 발생 하는데 오류를 발생 시키지 않고 그 null인 상태로도 연산을 하게 할 수 있는 기능이 있다. 그게 Nullable 연산자다.
자료형 뒤에 ?를 붙여줘서 null 값도 할당 할 수 있게 해주는 것이다.
string? name;
Nullable 형식으로 만들어 준다면 null을 조건문으로써 사용도 할 수 있게 된다. name != null
그리고 병합 연산자라고 null일 경우에 아니 경우에 값을 따로 할당 해줄 수 있게 하는 기능이 있다. 삼항연산자와 유사 하다.
??를 사용 해주는 것인데
int 변수명 = null형식의 변수 ?? 0;
이렇게 사용 해주면 null형식의 변수가 null이라면 0을 할당 하고, null이 아닐 경우 그 변수의 값이 할당 되게 한다.
상황에 따라 유용 하게 사용 할 수 있다.
stringBuilder 에 대해서
프로그래밍을 함에 있어서 우리는 문자열을 사용 하게 되는데 컴퓨터는 이 문자열을 '나중에 또 쓰겠지?' 라는 느낌으로 계속 남겨두게 된다. 그리고 우린 +연산자를 통해 문자열을 합치는 일도 있는데 이럴 때마다 새로운 문자열을 생성한다. 그러면 그것도 남겨지게 된다. 그러면 나중엔 엄청 많은 데이터가 남겨지게 될 수도 있다.
이 때 유연하게 문자열을 생성 및 관리를 할 수 있게 하는 게 stringBuiler다.
형식)
stringBuilder 변수명 = new stringBuilder();
이렇게 변수를 선언 하고 여러가지 함수들을 사용 해서 관리를 할 수 있게 한다.
Append(추가) -> 변수명.Append("메롱") -> 메롱을 추가 한다.
Insert(순서, 내용) -> 변수명 Insert(3, "메롱") 3번째 문자열부터 적힌 메롱을 추가 한다.
Replace(문자열, 문자열) -> 변수명.Replace("메롱","반사") 메롱인 문자열을 반사로 바꾼다.
Remove(순서, 얼만큼) -> 순서부터 얼만큼 지울 수 있게 한다.
이거 말고도 여러 기능들이 있다.
그리고 이렇게 문자열을 만들어 주고 사용 할 때는 string 형식으로 바꿔줘야 한다. ToString을 사용 해주면 된다.
ex) 변수명.ToString();
사용 할 날이 오겠지? 흠
잡다한 것
generics : 형식매개변수 형태인 것을 제너릭형이라고 말 할 수 있다.
static : 공유자원으로 만들어 주는 느낌이다. 객체를 생성 하지 않아도 직접 접근을 할 수 있다. 그렇기에 메모리를 적게 사용 하며 성능도 더 뛰어나다. 하지만, static은 공유자원으로써 계속 메모리에 남아있게 된다. 사용을 하지 않아도 계속 남아있다. 그리고 인스탄스를 생성 하게 되면 생성 된 static도 계속 남아 있게 된다.
static 필드는 그 필드를 가지고 있는 클래스가 처음으로 사용 될 때 Heap에 할당 된다.
이런 부분을 참고 해서 static을 사용 할 것인지 사용 안 할 것인지 사용자가 선택을 해야 한다.
주로 Utility나 save에 사용 된다.
람다식 : deligate에 말고도 그냥으로도 간단 함수 작성 해서 사용 할 수 있다. deligate에서만 호출 할 수 있는 것은 무명Mathods다. 이 것들은 1회용 함수다.라고 보면 된다.
잡다한 것
- 꿀팁 : for 탭 두 번 치면 자동완성 바로 된다.
- 형식매개변수는 두 개도 넣어줄 수 있다. 고정된 관념을 버리자. 그래야 방법을 떠올리 수가 있는 것.
- 코드가 두 개 이상일 경우에는 중괄호가 필요 하다.
- 담당일찐 튜터님이 코드 예시로 칠 때 (조건) 이런 식으로 치지 말고 정말로 예시 만들면서 치라고 했다.., 맞말입니동..
- string형 return을 할 때 int형과 조합을 할 경우 int를 굳이 바꿔 줄 필요 없이 둬도 string과 합쳐지면서 string형식이 된다. 새로운 문자열을 만드는 것. ex) return idx + "번 입니다."; -> idx번입니다 라는 문자열 생성.
- 튜터님이 횡성수설 하는 나를 보고, 설명을 할 때 핵심을 먼저 말하라는 깨달음을 주셨다. 그렇게 나는 말 하기까지 10초 정도의 시간이 걸리게 되었다.
- 튜터님이 나보고 타자 칠 때 영어를 영어로 쓰라고 하셨다. 맞다 .., 습관을 들이자..., 그래서 오늘 TIL은 2시간이 걸렸다..ㅋ 영어 때문은 아님
드디어 주어진 기초공부를 다 한 것 같다. 후.. 이제 지루한 시간은 끝났고 재미있게 코드 치면서 공부 해야지..,
알고리즘이란 건 언제 해보냐
'공부 기록' 카테고리의 다른 글
24년 5월 3일 TIL (2) 2024.05.03 24년 5월 2일 TIL (1) 2024.05.02 24년 4월 30일 TIL (3) 2024.04.30 24년 4월 29일 TIL (0) 2024.04.29 24년 4월 28일 TIL (1) 2024.04.28