Topic 3 소프트웨어 엔트로피

소프트웨어의 무질서도가 증가할 때 우리는 이를 '소프트웨어의 부패'라고 한다. 

이를 보다 그 정적인 표현인 '기술 부채'라고 부르기도 한다. 은연중에 언제 가는 갚을 수 있다는 뉘앙스를 풍기면서 말이다. 하지만 아마 갚지는 않을 것이다.  미래에 시간을 당겨다 쓰는 느낌이랄까..? 

여기서 말하기를 소프트웨어가 부패하는 데에는  많은 요소가 관여되는데 가장 중요한 것은 프로젝트에서 발생하는 심리학적 혹은 문화적 요소라고 한다. 이 심리는 이미 쓰레기가 넘치는 코드에 내 쓰레기 하나 더 버리는 건 괜찮다는 생각을 갖기 쉽다는 내용이다. 결국 이런 부정적인 생각은 팀원들에게 퍼져 악순환이 된다.

 

말하기를 깨진 창문을 내버려 두지마라

나쁜 설계, 잘못된 결정, 혹은 형편없는 코드 등이 모두 깨진 창문이다. 발견하자마자 바로 고쳐라, 적절히 고칠 시간이 없다면 일단 판자로 덮는 것만이라도 하라. 더 이상 손상을 예방하기 위해 "아직 구현되지 않았음"이라는 메시지라도 표현하자. 그 조치로 관리되고 있다는 것을 알리자. 

 

공감이 많이 됐다. 쉽고 빠르게 구현하기 위해 작성했던 코드들이 나중에 유지보수가 불가능한 코드가 되어 개선 작업이 힘들었던 경험. 이미 깔끔하지 않은 코드 위에 깔끔하지 않은 코드 한 줄 추가하기에는 쉽지만, 누가 봐도 잘 정돈된 코드 위에는 조금 더 신경 써서 코드를 작성하려 했던 경험.

 

우선, 망가트리지 말자

문제를 해결하기 위해 부가적인 피해를 일으키지 마라. 깨진 창문은 하나라도 충분하다.

정확한 확신 없이는 오히려 건들지 말자.

 

당장 부패한 코드를 작성하지 말자. 미래에도 바꾸지 않는다.

 

 

 

반응형

Topic 2 고양이가 내 소스 코드를 삼켰어요.

실용주의 철학의 초석 중 하나는 자신과 자신의 행동에 대해 책임을 지는 것이다. 

주제만 봐도 핑계를 대는 사람의 모습이 보인다. 그건 바로 책임감과 연결된다. 이번 주제에서는 실용주의 프로그래머라면 자신의 경력 개발, 자신의 학습 및 교육, 자신의 프로젝트, 자신의 일상업무에 대해서 책임을 지고, 자신의 실수나 무지도 주저 없이 인정한다. 책임을 지는 것은 프로그래밍에서 가장 즐거운 부분은 아니지만, 자주 일어나는 것이다. 잘 나가는 프로젝트에도 철저한 테스트, 훌륭한 문서화, 탄탄한 자동화 등에도 불구하고 뭔가 잘못되는 일이 있다. 예상치 못했던 기술적 문제가 발생한다. 이런 일이 일어나면 우리는 가능한 전문가답게 처리하려고 노력한다. 이는 정직하고 솔직해져야 한다는 것이다. 

 

이 내용을 읽고 내가 느꼈던 것은 주어진 일정 안에 기획된 내용을 개발하지 못했을 때, 팀장님에게 내가 어떤 식으로 얘기를 했었지? 한번 떠 올렸다. 말도 안 되는 핑계를 되지는 않았는지, 해결하지는 못했지만 적절한 대안은 제시했는지. 과연 팀장님이 보기에 전문가처럼 얘기를 했는지..

 

팀 내 신뢰

여러분의 팀이 여러분을 믿고 의할 수 있어야 한다. 여러분도 다른 팀원 누구에게나 편하게 의지할 수 있어야 한다. 팀원끼리 신뢰하지 않는다면? 서로 의지할 수 없는 관계가 형성된다. 그리고 이런 신뢰에 구멍이 뚫리면 원상복구가 힘들다.

 

나는 이런 부분에서 신뢰를 쉽게 깨지지 않을까 생각한다. 당연히 테스트해야 하는 것들, 너무 간단한 시퀀스에도 쉽게 나오는 버그, 귀찮다고 그냥 넘어가는 것들... 이것들부터 신뢰를 지키는 중요한 시작이라고 생각한다.

 

책임지기

책임은 최선을 다하는 것이 전부가 아니다. 통제할 수 없는 위험 요소가 있지 않은지 상황을 분석해야 한다. 결과에 대한 책임을 지기로 했다면 나중에 그 결과를 감당해야 한다. 실수를 저지르거나(누구나 실수를 한다) 잘못된 판단을 내렸다면, 정직하게 인정하고 다른 방안을 제안하도록 노력하라. 다른 사람 혹은 무언가를 비난하거나 변명을 만들어 내지 말라. 모르면 모른다고 얘기하고 그지만 찾아본다고 얘기해 전문가답게 책임을 지는 모습을 보여주자

 

내가 맡은 업무가 있다면 책임지고 해결하자. 안좋은 결과가 일어났다면, 그 결과를 좋은 결과로 바꾸기 위해 노력해야 한다. 변명이나 비난은 아무 의미가 없고, 내가 해결하지 못한다고 판단되면 일찍이 도움을 요청하자

 

 

반응형

나는 첫 번째 회사에서 2년 정도 경력을 쌓고 현재 직장인 이곳으로 이직을 했다. 좋은 프로젝트를 개발부터 출시까지 했다. 지금도 많은 것들을 경험하면서 배우고 있다. 내가 이 책을 처음 읽게 된 계기는 당시 팀장님과 첫 면담에 이런저런 얘기를 주고받았고, 짧은 시간이었지만 정말 배울 점이 많다고 생각했다. 그리고, 서점에서 이 책을 사주셨다. 사실 나는 프로그래밍이란 책은 언어문법이나 패턴정도의 책들만 몇 권 봤었지, 이런 종류의 책은 처음이었다.

이 책을 처음 읽을때는 이해하지 못하는 부분이 많아, 그냥 가볍게 읽었었다. 그 당시에 내년에 다시 한번 읽어봐야겠다'라는 생각을 했고, 올해 이 책을 다시 읽기 시작했다.  확실히 작년에 읽었을때 느끼지 못했던 것들이 있었다. 물론 지금도 저자가 예시를 드는 내용이며, 용어며.. 생소하고 이해하지 못하는 게 많다. (그럼 1년, 2년 후에는 점차 이해하는 부분들이 많지 않을까?) 이번에는 책의 내용들을 체득화하기 위해 내용을 정리하고, 내 생각들을 포스팅을 해보고 싶었다.


 

Topic 1 당신의 인생이다.

당신의 인생이다. 당신의, 당신이 사는, 당신이 만드는 인생이 있다. 

첫 번째 주제부터 확 와닿았다. 이 책에서 말하는 '불만 많은 개발자'를 얘기가 나는데. 공감이 됐다. 대학교를 다닐 때나, 학원에 다니며 공부하고 있을 때 불만이 많은 친구들이 꼭 있었다... 책에서 말하기를 이런 사람들은 변화를 귀찮아 피하고, 내가 발전하지 못하는 이유를 회사가 교육을 시켜주지 않는다고 투덜댄다고 한다. 내가 느끼기에도 이런 사람들은 무슨 어떠한 상황이 주어져도 불만을 갖으며, 그 이유를 동료 탓, 회사 탓으로 핑계를 댄다. 원하는 게 있으면 요구를 하고 내가 바꿀 수 없는 상황이라면 차라리 회사를 옮기는 것이 맞다.(근데 아마 이것도 귀찮아할 것이다.)

반응형

+,-,*,/ 연산자 추가하기

PIN CONVERSIONS로  타입선택

Add pin으로 더하기 피연산자 추가

Add한거 출력해보기

반응형

'언리얼' 카테고리의 다른 글

언리얼) 블루프린트 - 1 (기본 단축키 익히기)  (0) 2023.06.27

VARIABLES -> '+'버튼으로 추가

Name : 언리얼 내부에서 사용하는 변수, 빠른 검색에 용이, 용량도 적다

Text : 다국어 변환할때 용이

Tools -> Localization DashBoard

 

반응형

Print Text

=>

Event BeginPlay : 게임이 시작하고 한번 실행

EventTick : 매 프레임 실행

 

주석기능 : 드래그하고 'C'

연결된 라인 정리 : 가운데 더블클릭, ctrl누르고 이동

 

정리 : 단축키 q

반응형

'언리얼' 카테고리의 다른 글

언리얼) 블루프린트 - 3 (사칙연산)  (2) 2023.07.07

 

더보기

@page "/ranking"
@using WebApplication1.Data.Models
@using WebApplication1.Data.Service

@inject RankingService RankingService

<h3>Ranking</h3>
<AuthorizeView>
<Authorized>
@if (_gameResults == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>UserName</th>
<th>Score</th>
<th>Date</th>
</tr>
</thead>
<tbody>
@foreach (var gameResult in _gameResults)
{
<tr>
<td>@gameResult.UserName</td>
<td>@gameResult.Score</td>
<td>@gameResult.Date.ToString()</td>
</tr>
}
</tbody>
</table>

<p>
<button class="btn btn-primary" @onclick="AddGameResult">
Add
</button>
</p>

@if (_showPopup)
{
<div class="modal" style="display:block" role="dialog">
<div class="modal-dialog">
<div class=" modal-content">
<div class="modal-header">
<h3 class="modal-title">Add/Update GameResult</h3>
<button type="button" class="close" @onclick="ClosePopup">
<span ares-hidden="true">X</span>
</button>
</div>
<div class="modal-body">
<label for="UserName">UserName</label>
<input class="form-control" type="text" placeholder="UserName" @bind-value="_gameResult.UserName" />

<label for="UserName">Score</label>
<input class="form-control" type="text" placeholder="Score" @bind-value="_gameResult.Score" />
<button class="btn btn-primary " @onclick="SaveGameResult">
Save
</button>
</div>
</div>
</div>
</div>
}

}

</Authorized>
<NotAuthorized>
<p>NotAuthorized </p>
</NotAuthorized>
</AuthorizeView>

@code {
List<GameResult> _gameResults;
bool _showPopup;
GameResult _gameResult;
protected override async Task OnInitializedAsync()
{
_gameResults = await RankingService.GetGameResyltAsync();
}

void AddGameResult()
{
_showPopup = true;
_gameResult = new GameResult() { Id = 0 };
}

void ClosePopup()
{
_showPopup = false;
}

async Task SaveGameResult()
{
if (_gameResult.Id == 0)
{
_gameResult.Date = DateTime.Now;
var result = RankingService.AddGameResult(_gameResult);
}
else
{
//TODO
}

_gameResults = await RankingService.GetGameResyltAsync();
}

}

 

1. 데이터 추가 팝업

Ranking.razor

'Add'버튼을 누르면 AddGameResult()를 통해 팝업을 열어준다.

SaveGameResult : DB에 저장 작업

 

RankingService.cs

 

Ranking.razor

 

작업 결과

Add버튼을 통해 새로운 데이터를 추가한다.

새로 추가된 데이터가 db에도 잘 들어감

반응형

'게임서버' 카테고리의 다른 글

Blazor #6 RankingApp(1)  (0) 2022.10.17
Blazor #5 Templated ComponentJavascript  (0) 2022.10.14
Blazor #4 Templated Component  (0) 2022.10.08
Blazor Binding #3 Parameter, Ref, EventCallback  (0) 2022.09.19
Blazor Binding #2  (0) 2022.09.17

DB와 연결을 수월하게 하기 위한 EntityFramework 방식

ApplicationDbContext.cs
Startup.cs

1. DB 테이블 연동하기

appsettings.json

appsettings.json파일에 기존에 있던 문자열을 지우고 연결할 연결 DB문자열을 넣어준다.

 

2. 유저 데이터 모델링

add-migration : 마이그레이션을 추가 한다.

생성 된 RankingService migration

3. DB 접근하기 위한 준비

RankingService.cs

DB를 참조하기 위한 RankingService를 생성

Startup.cs

Startup에 새로 생성한 RankingService를 DependencyInjection 해준다.

Ranking.razor

4. 데이터 입력

일단 각각 더미로 데이터를 입력해준다.

 

5. 결과

반응형

'게임서버' 카테고리의 다른 글

Blazor #7 RankingApp(2)  (0) 2022.11.06
Blazor #5 Templated ComponentJavascript  (0) 2022.10.14
Blazor #4 Templated Component  (0) 2022.10.08
Blazor Binding #3 Parameter, Ref, EventCallback  (0) 2022.09.19
Blazor Binding #2  (0) 2022.09.17

JS 연동하기

1. JS파일 추가

s파일을 생성하고 2개의 함수를 만들었다. 단순히 "Hello World" 텍스트가 있는  윈도 창이 뜨는 함수와 이용자가 입력한 string을 리턴하는 함수

 

2. host에 추가하기

추가할 js파일을 연동하기 위한 작업

 

3. 레이저 파일 추가

@page "/JSInterop" : 페이지 라우팅

@inject IJSRuntime :. NET에서 JS를 호출하려면 IJSRuntime가 필요하다

button  2개 추가

@code 부분

 

4. 웹사이트 메뉴 추가

웹사이트에 새로 추가한 블레이저 파일을 연결 작업.

 

실행결과

1번째 버튼

2번째 버튼

 

더보기

인프런 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] 강의를 듣고 정리

반응형

'게임서버' 카테고리의 다른 글

Blazor #7 RankingApp(2)  (0) 2022.11.06
Blazor #6 RankingApp(1)  (0) 2022.10.17
Blazor #4 Templated Component  (0) 2022.10.08
Blazor Binding #3 Parameter, Ref, EventCallback  (0) 2022.09.19
Blazor Binding #2  (0) 2022.09.17

c++의 templated나 c#의 generics같은 기능이라고 생각하면 된다.

@typeparam : 템플릿타입 컴포넌트를 만들기 위한 선언

RenderFragment : Header와 Row 타입을 템플릿으로 만들기 위한 타입

@Header : 아래 @code부분에 선언한 Header와 바인딩

@foreach ~ @Row : RenderFragment<Item> Row와 바인딩되었으며 어떤 식으로 작동될지 선언 부분이다.

 

템플릿 타입으로 만든 컴포넌트를 사용

 

실행 결과

반응형

'게임서버' 카테고리의 다른 글

Blazor #6 RankingApp(1)  (0) 2022.10.17
Blazor #5 Templated ComponentJavascript  (0) 2022.10.14
Blazor Binding #3 Parameter, Ref, EventCallback  (0) 2022.09.19
Blazor Binding #2  (0) 2022.09.17
Blazor Binding  (0) 2022.09.17

User.razor 전체 코드

 

컴포넌트 분리

저번 포스팅에 @code부분인 AddUser()와 KickUser()를 컴포넌트화 시키기 위해 새로운 Blazor파일을 생성해 분리하도록 해보자

ShowUser 블레이저 파일 생성

ShowUser.razor

ShowUser.razor파일을 생성해 User.razor에있던 리스트 생성과 유저 추가, 삭제하는 함수들을 옮겼다.

 

설명

User.razor

-<ShowUser></ShowUser> : 새로 생성한 ShowUser.razor를 사용하기 위한 처리

-<ShowUser User ="_users"> : ShowUser.razor의 User변수와 User.razor의 _user의 변수를 공유한다

-@ref ="_showUser" : 부모쪽에서 자식에 접근하는 방식(이 처리가 없으면 @code에 ShowUser는 null임)

CallbackTest="CallbackTestFunc" : 콜백을 사용할 때

 

ShowUser.razor

[Parameter] : 를 통해  다른 블레이저 파일에서 접근 가능하도록 명시한다.

(블레이저에서는 Action보다는 EventCallback을 추천한다. StateHasChanged()가 없어도 리프래시 처리 )

 

유저리스트에 요소 추가
유저리스트에 요소 삭제

"CallbackTest"문자가 보임 : 콜백 호출이 잘되고 있다

반응형

'게임서버' 카테고리의 다른 글

Blazor #6 RankingApp(1)  (0) 2022.10.17
Blazor #5 Templated ComponentJavascript  (0) 2022.10.14
Blazor #4 Templated Component  (0) 2022.10.08
Blazor Binding #2  (0) 2022.09.17
Blazor Binding  (0) 2022.09.17

@code 부분

OnInitialized() : 웹이 시작할때 시작되는 함수 (유니티 awake()나 start()정도로 생각하면 될듯하다)

AddUser() : 리스트 요소 추가 함수

KickUser() : 리스트 요소 삭제 함수

 

웹코드 부분

"list-group"

- @foreach (var user in _users)<li>는 리스트갯수별로 추가해줘야 하지만 동적으로 추가,삭제 되기 때문에 foreach로 처리 되도록 한다.

- @onclick="(()=>KickUser(user))을 통해 리스트 요소옆에 해당 요소를 제거하는 버튼을 추가하는 내용이다

 

"container"

- <input class="form-control" placeholder="Add User" @bind-value="_inputName" : 처음에 뜨는 텍스트는 "Add User", "_inputName"을 바인딩 처리

- <button class="btn btn-primary" type="button" @onclick="AddUser">Add user</button> : AddUser를 실행처리

 

결과화면

반응형

'게임서버' 카테고리의 다른 글

Blazor #6 RankingApp(1)  (0) 2022.10.17
Blazor #5 Templated ComponentJavascript  (0) 2022.10.14
Blazor #4 Templated Component  (0) 2022.10.08
Blazor Binding #3 Parameter, Ref, EventCallback  (0) 2022.09.19
Blazor Binding  (0) 2022.09.17

 

"oninput"을 넣어주면 슬라이드를 움직일때 실시간으로 값이 갱신된다.

step : 몇 단위로 증감시킬건지

bind-value : @code에있는 _value값을 처리

 

웹에서 표현되는 Value는 @code부분에 _value값을 보여주고 슬라이더로 _value값을 접근하여 변경할 수있다.

반응형

'게임서버' 카테고리의 다른 글

Blazor #6 RankingApp(1)  (0) 2022.10.17
Blazor #5 Templated ComponentJavascript  (0) 2022.10.14
Blazor #4 Templated Component  (0) 2022.10.08
Blazor Binding #3 Parameter, Ref, EventCallback  (0) 2022.09.19
Blazor Binding #2  (0) 2022.09.17

1. 

실행결과

Start TestAsync가 불리고 3초 뒤에 EndTestAsync가 불리고 바로 while start가 불렸다. 만약 TestAsync에서 매우 긴 시간 동안 대기가 걸리면 그 이후 코드들이 실행되지 않게 된다.

2.

실행결과

await를 사용하여 대기하지 않고 바로 다음 코드가 실행되도록 할 수 있다.

 

3. await 활용방법

https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/async/

 

C#의 비동기 프로그래밍

async, await 및 Task를 사용하여 비동기 프로그래밍을 지원하는 C# 언어에 대해 간략히 설명합니다.

docs.microsoft.com

eggs, eggs, toast는 각각 연관이 없는 동작이다. 그렇기에 await키워드를 통하여 동시에 작업이 가능하도록 할수 있다. 이 사진에 문제점은 3가지 작업 중 toast가 끝난 뒤에 juice작업과 "Breakfast is read!"가 출력되도록 되어있다. toast가 가장 먼저 끝난다는 전제가 있다는 것이다. (우리는 어떤 작업이 먼저 끝날 줄 모른다.)

 

whenAny

3가지 작업을 List로 만들어 while문을 통해 끝난 작업들을 표시해주는 방법이 있다.

반응형

인덱스 칼럼 순서에 따른 탐색 시간 비교해보기

 

0. 테이블생성

 

1. 정렬하기

1) ORDER BY EmployeeID, OrderDate;

EmployeeID로 정렬된 뒤에 OrderDate 순으로 정렬되어있다.

2) ORDER BY OrderDate, EmployeeID;

OrderDate , EmployeeID 순으로 정렬되어 있는 것을 알 수 있다.

 

2. 특정 조건으로 찾기

SELECT *
FROM TestOrders WITH(INDEX(idx_emp_ord))
WHERE EmployeeID = 1 AND OrderDate = CONVERT(DATETIME, '19970101');

SELECT *
FROM TestOrders WITH(INDEX(idx_ord_emp))
WHERE EmployeeID = 1 AND OrderDate = CONVERT(DATETIME, '19970101');

인덱스 조건이 다른 두 개 코드는 탐색 결과가 차이가 없는 걸 알 수 있다.

3. 범위 조건으로 찾기

범위가 늘어나면 점점 큰 차이가 나게 된다. idx_emp_ord로 정렬한 뒤에 OrderDate범위는 바로 접근할 수 있는 반면에 idx_ord_emp로 정렬된 두 번째는 OrderDate를 범위를 찾은 다음에 다시 EmployeeID를 찾아야 하기에 더 오랜 시간이 걸리게 된다.

 

=> Index(a,b,c)로 구성되었을때, 선행 between사용하면 후행은 인덱스 기능을 살싱하게 된다.

반응형

'STUDY > 데이터베이스' 카테고리의 다른 글

[SQL] 연습 Clustered / NonClustered  (0) 2022.07.16
[SQL] 연습 복합인덱스 #4  (0) 2022.07.12
[SQL] 연습 DATABASE 작성 #3  (0) 2022.06.30
[SQL] 연습 ORDERBY #2  (2) 2022.05.17
[SQL] 연습 SELECT,WHERE #1  (0) 2022.05.10

1. NonClustered 인덱스 추가

특징 : Clustered Index가 없으면 데이터는 Heap Table이라는 곳에서 저장하고 Heap RID를 통해 Heap Table에 접근해서 데이터를 추출한다.

2. Clustered 인덱스 추가

HEAP RID가 없어졌으며 UNIQUEFIRE(같은 OrderID를 식별도록)가 생성됐다.

특징: HeapTable이 없으며, Leaf Table에 실제 데이터가 있고, Clustered Index의 실제 키값을 가지고 있다.

반응형

'STUDY > 데이터베이스' 카테고리의 다른 글

[SQL] 인덱스 컬럼 순서  (0) 2022.07.20
[SQL] 연습 복합인덱스 #4  (0) 2022.07.12
[SQL] 연습 DATABASE 작성 #3  (0) 2022.06.30
[SQL] 연습 ORDERBY #2  (2) 2022.05.17
[SQL] 연습 SELECT,WHERE #1  (0) 2022.05.10

테이블 복사하기

 

복합 인덱스 추가하기

 

추가된 인덱스 정보 보기

인덱스 적용 1

인덱스 적용2

인덱스 적용3

 

인덱스 적용4

 

결과가 1~3번까지와(Index Seek) 4번이 다른 이유는 인덱스 OrderId, ProductId 생성한 순서에 영향이있다.

위그림처럼 첫번째로 만들어준 OrderId로 탐색하고 그 뒤에 ProductID로 탐색하게된다. (정렬된 OrderID와 다른 ProductID)

 

=> 결과 : 인덱스(a,b)사용중이라면 인덱스(a)는 없어도 되지만 (b)로도 검색이 필요한 경우는 (b)도 별도로 인덱스에 추가해 줘야한다.

 

 

+) 인덱스를 가공해서 찾을 경우 인덱스덕을 못볼수 있음

가공해서 찾기
그냥 찾기

 

반응형

'STUDY > 데이터베이스' 카테고리의 다른 글

[SQL] 인덱스 컬럼 순서  (0) 2022.07.20
[SQL] 연습 Clustered / NonClustered  (0) 2022.07.16
[SQL] 연습 DATABASE 작성 #3  (0) 2022.06.30
[SQL] 연습 ORDERBY #2  (2) 2022.05.17
[SQL] 연습 SELECT,WHERE #1  (0) 2022.05.10

1. 데이터베이스 만들기

- UI를 통해서 만들기

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

- SQL구문으로만 생성

실행 후 -> refresh를 눌러준다.

 

2. 데이터베이스 만들기

Desin을 보면 생성된 테이블을 볼 수 있다.

3. 삭제 하기

해당 구문을 실행하면 테이블이 삭제된다. (경고없이 바로 삭제되니 주의)

 

4. 테이블 내용 추가하기

5. 테이블 내용 삭제하기

 

6. 테이블 내용 변경하기

7. 제약 PRIMARY KEY

 

- 테이블 생성할때 지정하기

- 구문으로 지정하기

=> 결과

결과

제약 사항이 없을때 

 

제약 사항이 있을때

PRIMARY KEY가 있는 경우는 c#딕셔너리(자세하게는 다름 이진트리, 해쉬)를 사용하는것과 비슷하고 PRIMARY KEY가 없는 경우는 List에서 찾는것과 비슷하다.

반응형

'STUDY > 데이터베이스' 카테고리의 다른 글

[SQL] 인덱스 컬럼 순서  (0) 2022.07.20
[SQL] 연습 Clustered / NonClustered  (0) 2022.07.16
[SQL] 연습 복합인덱스 #4  (0) 2022.07.12
[SQL] 연습 ORDERBY #2  (2) 2022.05.17
[SQL] 연습 SELECT,WHERE #1  (0) 2022.05.10

정렬하기

SELECT *
FROM players
WHERE birthYear IS NOT NULL
ORDER BY birthYear DESC, birthMonth DESC, birthDay DESC;

birthYear가 NULL값을 제외하고 내림차순으로 정렬한다. birthYear값이 같다면 birthMonth ,birthDay 까지 비교하여 내림차순 정렬처리한다.

 

SELECT TOP PERCENT*

데이터중 5퍼센트만 뽑아내기

 

SELECT TOP 100*

TOP 100개 뽑아내기

 

OFFSET 100 ROWS FETCH NEXT 100 ROWS ONLY;

100개행을 건너뛰고 그 다음 100개 행을 출력하기

반응형

'STUDY > 데이터베이스' 카테고리의 다른 글

[SQL] 인덱스 컬럼 순서  (0) 2022.07.20
[SQL] 연습 Clustered / NonClustered  (0) 2022.07.16
[SQL] 연습 복합인덱스 #4  (0) 2022.07.12
[SQL] 연습 DATABASE 작성 #3  (0) 2022.06.30
[SQL] 연습 SELECT,WHERE #1  (0) 2022.05.10

1.

SELECT  nameFirst, nameLast, birthYear

FROM players
WHERE birthYear = 1866

players파일에서 nameFirst, nameLast, birthYear중 birthYear가 1866인 데이터들만 추려내도록 하였다.

더보기
블록을 지정해서 실행하면 WHERE 문을 실행시키지 않음

 

2. WHERE 조건 조합하여 체크하기

 

3. 패턴 이용하기

- 'New Yor' 이후 한 글자 까지 찾기

- 'New York%'  New Yor으로 시작하는 모든 데이터 찾기

반응형

'STUDY > 데이터베이스' 카테고리의 다른 글

[SQL] 인덱스 컬럼 순서  (0) 2022.07.20
[SQL] 연습 Clustered / NonClustered  (0) 2022.07.16
[SQL] 연습 복합인덱스 #4  (0) 2022.07.12
[SQL] 연습 DATABASE 작성 #3  (0) 2022.06.30
[SQL] 연습 ORDERBY #2  (2) 2022.05.17

 

이 시점(현재 경력)에서 이런 글을 작성하는데 시간을 쓰는 것보다, 자료구조 공부 또는 알고리즘 문제를 한 문제 더 푸는 것이 더 좋다고 생각도 했지만 하지만 이렇게 나의 생각을 한 번쯤은 정리해보고 싶은 생각이 들었다. 

좋은 코드를 작성하는 방법은 무엇일까?

좋은 코드란? 좋은 코드는 빠르게 읽히고 유지보수가 쉬우며 수정사항이 있을 때 몇 개의 함수 호출로 원하는 기능을 수정/추가가 가능한 코드일 것이다.

하지만 기업에서 많은 사람들의 협업을 통해 업무가 진행되는 프로그램에서 이런 코드는 현실적으로는 힘들어 보인다.

 

버그를 수정할 때는 현재 수정하려는 부분에서 코드들의 한 줄 한 줄 의미를 파악해야 하며 수정했을 때 발생할 사이드 이펙트에 관해서도 꼼꼼히 살펴야 한다. 이 코드는 그럴 것이다~ 또는 누군가가 작성한 함수의 이름만 믿고 그런 기능을 하는 함수겠지 하는 생각으로 대충 리딩하고 버그를 수정하다 보면 나중에 크게 데일수 있다.. 그렇기 때문에 우리는 좋은 코드를 작성하려고 노력해야 한다.

 

이런 좋은 코드들이 나중에 프로그램이 실제로 서비스됐을 때 버그 수정에서도 빠르게 수정이 됐었고, 그 좋은 코 드위에서 작업을 할 때도 그렇지 않은 코드보다 훨씬 시간이 감축됐다. (어느 위치에, 어느 함수에 있어야 할 기능이 딱딱 있었다.)

 

좋은 코드를 작성하는 방법은 주어진 상황에 맞는 판단하여 작성하는 코드가 아닐까 한다. 

서비스하려는 프로그램을 만들다 보면 당연히 현재 코드가 실제 서비스됐을 때 새로운 기능은 쉽게 수정/추가/제거가 가능한지, 발생 가능한 이슈들을 예상하며 만들게 된다. 이러한 코드 작성은 당연히 시간이 많이 소요된다.

 

근데, 이 상황에서도 우리가 지향하는 좋은코드로 작성하는 게 맞을까?

예를 들어, 나에게 업무가 할당됐다. 그 업무는 이틀 안에 3가지 프로토타입을 발표하고 그중에서 선택받은 프로그램으로 본격적인 개발을 하기로 했다. 

 

그런데 미래 확작성을 고려한 베이스 코드부터 여러 기능을 미리 만들어 놓고 유지보수도 생각하면서 개발하다 설계과정에서부터 많은 시간이 소요돼 기한 내에 업무를 처리하지 못할 수 있다. 정작 결국에 사용하지 않을 코드나 기능을 만드는데 시간을 쓴 것이다. 그렇다면 코드로만 봤을 때 좋은 코드일 수는 있어도 좋은 코드 작성방법에서는 맞지 않는다고 생각한다. 

 

당연히 프로토타입을 만드는 과정에서도 수정사항과 여러 이슈가 발생할 수 있다.

말하고 싶은것은 작성하려는 상황에서 개발 속도와 그 상황에 어느 정도 예상되는 유지보수성까지만 살려 적절하게 작성하는 것이다.

시간이 돈으로 연관되는 이런 상황에서 이 두 개의 중점을 잡기는 힘들다. 업무를 하면서 이런 판단을 해야 할 일들이 많았고 또, 그 판단 결과가 만족스럽지 않은 적이 많았다. 이런 판단을 하려고 노력하다 보면 이 경험들이 점차 좋은 판단력을 얻어지지 않을까 생각한다.     

 

 

  

반응형

제한된 이미지 사이즈 안에서 들어가야 할 글자가 초과될 경우 사용하면 될듯하다.

좌우 방향 설정과 속도조절이 가능하다.

 

 

깃허브 링크

https://github.com/hahahohohun/PublicCode/blob/main/README.md#-cmovetextcs

 

GitHub - hahahohohun/PublicCode

Contribute to hahahohohun/PublicCode development by creating an account on GitHub.

github.com

+) 특정 상태에 따라 흐를 것인가 멈출 것인가를 기능을 넣으면 좋을 듯

반응형

선택한 오브젝트를 제외한 오브젝트의 SetActive를 false처리한다. 단축키는 Ctrl + Shift + Q

 

같은 부모 오브젝트 아래에서 작동

 

최상단 오브젝트에서 작동

 

-----------------------------------------------------------------------------------

2021.12.13

단축키를 사용하기전에 애초에 꺼져있는 오브젝트는 다시 켜지지 않도록 처리

1.Ctrl + Shift + Q

2.해당 오브젝트의 포지션값 변경

3.Ctrl + Shift + Q (꺼져있던 오브젝트 다시 활성화)

-----------------------------------------------------------------------------------

 

 

https://github.com/hahahohohun/PublicCode/blob/main/README.md#eccustomtoolscs

 

반응형

오브젝트에 인덱스를 추가하여 이름을 변경이 필요할때!

ctrl + D 를 통해 생성한 오브젝트는 (1),(2),(3)~~~ 이름 마지막에 이렇게 숫자가 붙는다. 하나 하나 바꾸기 번거롭기때문에 이것을 한꺼번에 변경이 가능한 간단한 툴을 만들었다.

 

https://github.com/hahahohohun/PublicCode/blob/main/README.md#ecnamingcs

 

반응형

파란색 : 풀면서 어려웠던 부분 or 고려해야 될 부분

빨간색 : 해결방법

초록색 : 느낀점

문제

상근이가 가지고있는 숫자중 제시된 숫자의 갯수를 구하는 문제이다.

풀이 : 내가 작성한 코드

            int[] arry = new int[20000001];
            int n = int.Parse(Console.ReadLine());
            string[] nstr = Console.ReadLine().Split(' ');

            int m = int.Parse(Console.ReadLine());
            string[] mstr = Console.ReadLine().Split(' ');
            int nIdx = 10000000;
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < nstr.Length; i++)
            {
                arry[nIdx + int.Parse(nstr[i])]++;
            }
            for (int i = 0; i < mstr.Length; i++)
            {
                stringBuilder.Append(arry[nIdx + int.Parse(mstr[i])] + " ");
            }
            Console.WriteLine(stringBuilder.ToString());

단순히 이중for문으로 풀수도있지만 시간초과가 날수 있기 때문에 카운트소팅으로 문제를 해결했다. 카운트할 갯수를 저장한 배열을 선언하다 범위가  [-10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다] 이기 때문에 배열크기를 20,000,001로 할당했다. 

예를들어 -9000000 이 값이 나오면 10000000을 더해 1000000인덱스에 접근하여 1을 더해준다.

 

그렇게 하면 다른 조건처리 없이 배열의 값을 할당할 수 있기 때문이다. 20,000,000이 아닌 20,000,001인 이유는 0의 카드도 나올수 -10000000인 카드가 나오면 배열의 인덱스는 0을 가리키기 때문이다. 

 

https://www.acmicpc.net/problem/10816

 

10816번: 숫자 카드 2

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,

www.acmicpc.net

 

반응형

파란색 : 풀면서 어려웠던 부분 or 고려해야 될 부분

빨간색 : 해결방법

초록색 : 느낀 점

문제

스택을 활용하는 문제이다.

풀이 : 내가 작성한 코드

            int length = int.Parse(Console.ReadLine());
            int[] nArray = new int[length];
            for (int i = 0; i < length; i++)
            {
                nArray[i] = int.Parse(Console.ReadLine());
            }

            int nCount = 0;
            int nIdx = 1;
            StringBuilder stringBuilder = new StringBuilder();
            Stack<int> stack = new Stack<int>();
            stack.Push(nIdx);
            stringBuilder.Append("+\n");

            while (nCount != length)
            {
                while (true)
                {
                    if (stack.Count != 0 && nArray[nCount] == stack.Peek())
                    {
                        int nPop = stack.Pop();
                        stringBuilder.Append("-\n");
                        nIdx = nPop > nIdx ? nPop : nIdx;
                        break;
                    }
                    else
                    {
                        nIdx++;
                        stack.Push(nIdx);
                        stringBuilder.Append("+\n");
                    }
                    if (nIdx > length)
                    {
                        Console.WriteLine("NO");
                        return;
                    }
                }

                nCount++;
            }
            Console.WriteLine(stringBuilder.ToString());

신경 써야 할부분은 스택에서 pop 된 후 바로 다음으로 나열되어야 하는 수가 peek에 있지 않으면 답은 "NO"가 출력되어야 한다.

처음에는 Idx로 push 할 때 +1해 주고 pop 할 때 -1을 했지만 그렇게 되면 pop 됐던 값이 다시 push 되기 때문에 nPop을 통해 방금 꺼낸 pop 된 값이 크면 nIdx값을 변경해줬다. 

 

예상된 수열로 불가능한 예시

 

https://www.acmicpc.net/problem/1874

반응형

문제

BFS문제로 인접한 배추들의 갯수를 그룹이 몇개있는지 체크하는 문제이다.  

풀이 : 내가 작성한 코드

public static void Main()
    {
            int length = int.Parse(Console.ReadLine());
            for (int i = 0; i < length; i++)
            {
                string[] str = Console.ReadLine().Split(' ');
                int x = int.Parse(str[0]);
                int y = int.Parse(str[1]);
                int count = int.Parse(str[2]);
                Queue<(int, int)> queue = new Queue<(int, int)>();

                int[,] arry = new int[x, y];
                int[,] vis = new int[x, y];

                for (int k = 0; k < count; k++)
                {
                    string[] strpos = Console.ReadLine().Split(' ');
                    arry[int.Parse(strpos[0]), int.Parse(strpos[1])] = 1;
                }

                int[] dx = new int[] { 1, 0, -1, 0 };
                int[] dy = new int[] { 0, 1, 0, -1 }; // 상하좌우 네 방향을 의미
                int nG = 0;
                for (int z = 0; z < x; z++)
                {
                    for (int v = 0; v < y; v++)
                    {
                        if (vis[z, v] == 1 || arry[z, v] == 0)
                        {
                            continue;
                        }

                        queue.Enqueue((z, v));
                        nG++;
                        while (queue.Count != 0)
                        {
                            var cur = queue.Dequeue();
                            int curx = cur.Item1;
                            int cury = cur.Item2;
                            //시작 확인

                            // 상하좌우 칸을 살펴볼 것이다.
                            for (int dir = 0; dir < 4; dir++)
                            {
                                int nx = cur.Item1 + dx[dir];
                                int ny = cur.Item2 + dy[dir]; // nx, ny에 dir에서 정한 방향의 인접한 칸의 좌표가 들어감
                                if (nx < 0 || nx >= x || ny < 0 || ny >= y)
                                    continue; // 범위 밖일 경우 넘어감
                                if (vis[nx, ny] == 1 || arry[nx, ny] != 1)
                                    continue; // 이미 방문한 칸이거나 배추칸이 아닐경우

                                vis[nx, ny] = 1; // (nx, ny)를 방문했다고 명시
                                queue.Enqueue((nx, ny));
                            }
                        }
                    }
                }
                Console.WriteLine(nG);
            }

              
    }

BFS문제에서는 칸의 어떤 상태(배추:1,빈공간:0)인지 체크하는 부분과 큐에 들어간 칸(배추 가 심어져있는)이 어디까지 방문할수 있는지, 이미 방문한 위치인지 체크한다.

이문제는 흰지렁이가 포함할수 있는 범위를 묻는 문제는 아니고 몇개의 범위를 폼할수 있는 문제이기 때문에 큐에 입력될때 마다 카운팅을 했다. 

 

 

문제

https://www.acmicpc.net/problem/1012

반응형

파란색 : 풀면서 어려웠던 부분 or 고려해야 될 부분

빨간색 : 해결방법

초록색 : 느낀 점

문제

https://www.acmicpc.net/problem/10808

 

10808번: 알파벳 개수

단어에 포함되어 있는 a의 개수, b의 개수, …, z의 개수를 공백으로 구분해서 출력한다.

www.acmicpc.net

알파벳 소문자로만 이루어진 단어 S가 주어진다. 각 알파벳이 단어에 몇 개가 포함되어 있는지 구하는 작성하는 문제이다. 

풀이 : 내가 작성한 코드

 

 처음 생각했을 때는 입력된 string값을 기준으로 또 다른 a~z을 체크하여 입력된 string요소의 알파벳이 해당하는 수를 카운팅 해서 추 출력하려고 했다. 그러면 총 O(N^2) 시간 복잡도였다. 다른 방법으로는 미리 a~z의 해당하는 26개 크기를 가지는 배열을 미리 생성했다. 그렇게 하면 a~z까지 각각의  string요소의 해당하는 알파벳에 위치가 정해 지므로, 입력값의 요소로 for문을 돌리면서 해당하는 알파벳에 1씩 증가해 주면 된다. 

느낀 점

단순히 정답을 출력하는 풀이식보다는 좀 더 최적화여 값을 구하는 연습을 해야겠다. 

 

반응형

파란색 : 문제점

빨간색 : 해결방법

초록색 : 느낀 점


문제

여러 장소에서 작업하기 위해 코드를 깃에 올려놓고 다운로드하였는데 아래와 같은 오류가 발생했다. 무엇인가 연결이 끊겨서 파일 요소를 로드할 수 없는 상태인 것 같다.

 

sln파일을 메모장으로 열어봤다.

Server.sln

sln안에는 내가 생성한 cs파일들의 프로젝트 파일들의 경로가 적혀있다.  sln은 경로 된 파일들을 로드하는데, 그중에 ServerCore에 는 csproj파일이 없었다.  우선 이 파일이 어떤 형태인지 알아보기 위해 얘도 메모장으로 열어봤다. 

Server.csproj

csproj 설명https://docs.microsoft.com/ko-kr/visualstudio/msbuild/how-to-use-project-sdk?view=vs-2019


오류 해결방법

ServerCore에 는 csproj파일을 만들어주면 된다. 안에 내용은 다른 프로젝트와 다르지 않기 때문에 복사해서 이름만 바꿔주도록 한다. 

사실 작업을 하다 보면 콘텐츠에 구현하는데만 신경 썼었다. 프로젝트 파일이 어떤 식으로 구성되고 어떤 확장자가 어떤 기능을 하는지 알아볼 생각도 하지 못했다. 지금도 정확하게 알지는 못하지만 이런 오류를 해결함으로써 빌드 파일의 구성에 대해 조금이나마 알게 되었다.

 

 

반응형

파란색 : 풀면서 어려웠던 부분 or 고려해야 될 부분

빨간색 : 해결방법

초록색 : 느낀 점

문제

https://programmers.co.kr/learn/courses/30/lessons/42587

우선순위를 정하여 먼저 출력할 인쇄물의 대한 처리를 하는 문제이다. 

풀이 : 내가 작성한 코드

우선순위와 인덱스를 갖는 Task라는 클래스를 만들어서 Queue에 넣도록 했다.  그런 후 foreach로 하나씩 검사하여 자기보다 뒤 에이 있는 값이 우선순위가 높다면 반복문을 빠져나와 맨뒤로 넣도록 했다. 선입선출이기 때문에 큐를 사용했다. 모든 값들을 정렬할 필요가 없기 때문에 nNow인 순서를 체크하는 변수와 매개변수 location이 같으면 값을 출력해준다. 

풀이 : 다른 사람이 작성한 코드

나는 큐에 우선순위와 인덱스 값을 저장할 클래스를 따로 만들었지만 이 코드에서는 KeyValuePair를 사용했다. While문을 돌리면서 큐에 들어가 있는 값들 중에 가장 높은 우선순위의 값이 큐의 맨 처음에 입력된 값과 우선순위를 비교한다. 가장 큰 값이 현재 입력 순서라면 매개변수 location과 비교한다.  그 값이 location도 아닌데 가장 큰 값이면 answer를 하나씩 증가한다. 출력 순서가 아니란 얘기다. 

반응형

+ Recent posts