크래프톤 정글 TIL : 1119

lazyArtisan·2024년 11월 19일
0

정글 TIL

목록 보기
142/147

📝 배운 것들


🏷️ Vector3.Lerp()

Vector3.Lerp()는 두 벡터 사이를 선형 보간(Linear Interpolation)하여 주어진 시간 비율에 따라 중간 위치를 계산하는 함수입니다. 이 함수를 사용하면 두 위치 사이를 부드럽게 이동하는 효과를 만들 수 있습니다.

Vector3.Lerp(Vector3 a, Vector3 b, float t);
  • a: 시작 위치 벡터.
  • b: 목표 위치 벡터.
  • t: 보간 계수로, 0에서 1 사이의 값을 가집니다.
    • t0이면 반환 값은 a와 동일합니다.
    • t1이면 반환 값은 b와 동일합니다.
    • t0.5ab의 중간 지점이 반환됩니다.

t 값이 0에서 1로 증가할수록 a에서 b로 점진적으로 이동하게 됩니다.


🏷️ Random.insideUnitCircle

Random.insideUnitCircle은 Unity에서 제공하는 Random 클래스의 함수로, 반지름이 1인 단위 원 안의 무작위 점을 반환합니다. 이 함수는 2D에서 원형 영역 내의 임의의 위치를 얻을 때 유용합니다. 반환되는 값은 Vector2 타입이며, 단위 원의 중심을 (0, 0)으로 기준으로 합니다.


🏷️ normalized

normalized는 벡터(Vector)의 크기(길이)를 1로 맞추면서 같은 방향을 유지하는 단위 벡터를 의미합니다. Unity의 Vector3Vector2 구조체에 포함된 프로퍼티로, 벡터의 방향을 유지하면서 길이만 1로 변경합니다.

Vector3 originalVector = new Vector3(3, 4, 0);
Vector3 normalizedVector = originalVector.normalized;

🏷️ C# 전처리문 비슷한거

C#에서는 readonly 필드나 const 필드 또는 람다 표현식을 사용해 간단히 값을 정의할 수 있습니다. 이러한 방식으로 필요한 값을 코드의 어디에서든 바로 사용할 수 있게 합니다.

1. readonly 필드 사용

다음과 같이 readonly 필드로 무작위 단위를 정의할 수 있습니다.

private readonly Vector2 RandomDirection = Random.insideUnitCircle.normalized;

이 경우 RandomDirection은 생성자에서만 설정할 수 있으므로, 필요에 따라 한 번만 초기화되는 값이라면 적합한 방식입니다. 그러나 매번 새로운 값을 필요로 한다면 이 방식은 적합하지 않습니다.

2. 람다 표현식 사용

람다 표현식을 사용해 간단히 구현할 수도 있습니다. RandomDirection을 메서드로 정의하는 대신, 아래와 같이 람다로 정의하면 함수처럼 호출하면서도 더 간결하게 사용할 수 있습니다.

private Vector2 RandomDirection => Random.insideUnitCircle.normalized;

이렇게 하면 RandomDirection을 호출할 때마다 새로운 무작위 방향을 반환합니다.

3. static 필드로 정의 (공통적으로 사용할 경우)

프로젝트에서 여러 곳에서 공통적으로 사용하는 무작위 방향이 필요하다면, static 필드로 정의할 수도 있습니다.

public static Vector2 RandomDirection => Random.insideUnitCircle.normalized;

🏷️ Renderer와 SpriteRenderer의 차이

  • Renderer: 모든 렌더러의 기본 클래스이며, 3D와 2D 렌더러를 포함하여 공통 속성에 접근할 수 있습니다.
  • SpriteRenderer: 2D 전용 렌더러로, 스프라이트를 화면에 표시하고 2D 스프라이트 전용 기능에 접근할 수 있습니다.

따라서, 2D 스프라이트를 다룰 때는 SpriteRenderer, 공통적인 렌더링 속성에 접근할 때는 Renderer를 사용하는 것이 좋습니다.



🎮 Frog on Lotus


animation 만들 때 show sample rate 하고 sample rate 조절
스프라이트 끌어당겨도 안 들어가면 시간 선에 정확히 드래그앤드랍

파리 랜덤 움직임 구현? : spline interpolation

https://www.youtube.com/watch?v=7j_BNf9s0jM
spline interpolation

    [SerializeField] private Transform pointA;
    [SerializeField] private Transform pointB;
    [SerializeField] private Transform pointAB;

    private float interpolateAmount;
    private void Update()
    {
        interpolateAmount = (interpolateAmount + Time.deltaTime) % 1f;
        pointAB.position = Vector3.Lerp(pointA.position, pointB.position, interpolateAmount);
    }

선형 보간

    private void Update()
    {
        interpolateAmount = (interpolateAmount + Time.deltaTime) % 1f;
        pointAB.position = Vector3.Lerp(pointA.position, pointB.position, interpolateAmount);
        pointBC.position = Vector3.Lerp(pointB.position, pointC.position, interpolateAmount);
        pointCD.position = Vector3.Lerp(pointC.position, pointD.position, interpolateAmount);

        pointAB_BC.position = Vector3.Lerp(pointAB.position, pointBC.position, interpolateAmount);
        pointBC_CD.position = Vector3.Lerp(pointBC.position, pointCD.position, interpolateAmount);

        pointABCD.position = Vector3.Lerp(pointAB_BC.position, pointBC_CD.position, interpolateAmount);
    }

앵커와 핸들

    private float interpolateAmount;
    private void Update()
    {
        interpolateAmount = (interpolateAmount + Time.deltaTime) % 1f;
        /*
        pointAB.position = Vector3.Lerp(pointA.position, pointB.position, interpolateAmount);
        pointBC.position = Vector3.Lerp(pointB.position, pointC.position, interpolateAmount);
        pointCD.position = Vector3.Lerp(pointC.position, pointD.position, interpolateAmount);

        pointAB_BC.position = Vector3.Lerp(pointAB.position, pointBC.position, interpolateAmount);
        pointBC_CD.position = Vector3.Lerp(pointBC.position, pointCD.position, interpolateAmount);

        pointABCD.position = Vector3.Lerp(pointAB_BC.position, pointBC_CD.position, interpolateAmount);
        */

        pointABCD.position = CubicLerp(pointA.position, pointB.position, pointC.position, pointD.position, interpolateAmount);
    }

    private Vector3 QuadraticLerp(Vector3 a, Vector3 b, Vector3 c, float t)
    {
        Vector3 ab = Vector3.Lerp(a, b, t);
        Vector3 bc = Vector3.Lerp(b, c, t);

        return Vector3.Lerp(ab, bc, interpolateAmount);
    }

    private Vector3 CubicLerp(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float t)
    {
        Vector3 ab_bc = QuadraticLerp(a, b, c, t);
        Vector3 bc_cd = QuadraticLerp(b, c, d, t);

        return Vector3.Lerp(ab_bc, bc_cd, interpolateAmount);
    }

리팩토링

  1. 서로 간의 거리가 가까운 점 A, C와 거리 제한 없는 B 점을 생성한다.
  2. 2중 보간 경로를 따라 A에서 C로 파리를 보낸다.
  3. 파리가 C에 도착하면 또 다시 동일한 조건의 점 A,B,C를 생성한다.
  4. 2중 보간 경로를 따라 A에서 C로 파리를 보낸다.
  5. 반복

찾아보니까 UnityEngines.Splines 있는데 using 써보니까 안됨.
패키지 깔아야 되는듯. 근데 여기까지 다 따라해놓고 딸깍은 좀.

렌더러나 콜라이더 바운드 가져올 수 있구나

gameObject.position이 아니라 gameObject.transform.position이구나 (물론 gameObject는 생략하고 바로 transform.postion도 가능)

오늘 한 거 최종


public class RandomFly : MonoBehaviour
{
    private Vector2 RandomDirection => Random.insideUnitCircle.normalized;
    private Vector2[] Course;
    private float interpolateAmount;
    [SerializeField] private GameObject SpawnArea;

    void Awake()
    {
        // 스폰 위치 정해놓고 그 안에서만 랜덤하게 스폰
        Bounds SpawnBounds = SpawnArea.GetComponent<Renderer>().bounds;
        float randomX = Random.Range(SpawnBounds.min.x, SpawnBounds.max.x);
        float randomY = Random.Range(SpawnBounds.min.y, SpawnBounds.max.y);
        transform.position = new Vector2(randomX, randomY);
        Course = RandomNewCourse(transform.position, 10f);
    }

    void Update()
    {
        interpolateAmount += Time.deltaTime;

        Debug.Log("interpolateAmount = " + interpolateAmount);

        if (interpolateAmount > 1f)
        {
            interpolateAmount = 0;
            Course = RandomNewCourse(transform.position, 10f);
        }

        transform.position = QuadraticLerp(Course[0], Course[1], Course[2], interpolateAmount);
    }

    // 2중 보간
    private Vector2 QuadraticLerp(Vector2 a, Vector2 b, Vector2 c, float t)
    {
        Vector2 ab = Vector2.Lerp(a, b, t);
        Vector2 bc = Vector2.Lerp(b, c, t);
        return Vector2.Lerp(ab, bc, t);
    }

    // 시작점에서 가까운 점 C를 고르고, 멀 수도 있는 점 B를 고른다.
    private Vector2[] RandomNewCourse(Vector2 start, float maxDistance)
    {
        float d_close = Random.Range(0, maxDistance);
        float d_far = Random.Range(0, maxDistance * 2);

        Vector2[] NewCourse = new Vector2[3];
        NewCourse[0] = start;
        NewCourse[1] = start + RandomDirection * d_far;
        NewCourse[2] = start + RandomDirection * d_close;

        return NewCourse;
    }
}

일단 이제 날아다니긴 함. 이상하게 날아다니는게 문제지.



🎤 구직 준비


문제를 해결하는 연습을 더 하고,
문제를 해결하는 능력을 내세울 것.
다른 것은 부차적이다.

이력서 피드백

면접관은 바쁘기 때문에 첫 30초 이후에 읽을지 말지를 결정한다.

첫번째 장
: 일단 블로그 링크는 넘김. 이건 나중에 흥미가 생겼을 때 유의미한 정보가 됨.
첫번째 장에서 유의미한 키워드는 운영체제, 스케줄링, 시스템 콜, 가상 메모리 정도.
이렇게 많은 지면을 할애해서 남는게 정보 4개밖에 없음.

두번째 장
: 유니티 써봤구나, 웹으로 뭔가 게임 만들어봤구나.
이력서 보는 사람이 컴공 아니면 red black tree도 모를 수도.
web server 구현했다는 것도 오해의 소지가 있음. 근데 뭔가 c를 이용해서 해봤나보네.
핀토스가 뭔지 면접관은 모름. 운영체제를 책으로 배웠다고 오해할수도.

  • 핀토스는 '미니 운영체제 커널 개발' 이렇게 적어야 뭔지 안다. 정글도 뭔지 모름.
  • 게임 설명들은 이해됨. 근데 오히려 디테일해야 하는데 많이 요약된 느낌.
  • 개인 프로젝트에도 기능을 적어라.
  • creation은 지금은 뺄 것. 회사를 봐가면서 개발자인데 창의력이 요구될 것 같으면 넣어도 될듯.

세번째 장
: (원래는 여기까지도 안 가지만) 여기엔 유의미한 정보가 좀 있네. 이런 것들 할 줄 알구나.

  • Work Experience랑 Education은 묶어서 '이력'으로 합치기. Work Experience도 한 줄로 만들기.
  • SAS, Excel 이런거 빼고 DB로 만들기. 개발자로써 유의미한 능력으로 안 쳐줄 것.
  • 그냥 단순히 학습이라고 적는 건 의미가 없음. 인사이트가 있어야 함. ex) 쓰레드를 통해서 어떤 인사이트를 얻었다.

종합

  • 두괄식으로 써라.
  • 면접관에게 들어올 정보에 집중해야 한다.
  • 첫 장에 하고 싶은 얘기가 다 들어오게 해라. 나 이런 거 할 줄 아는 기술자라는 걸 알려줘야 함.
  • 책을 보면 목차-내용 순인 것처럼, 첫 페이지에 자신의 기술 경험을 적고 그 다음 장들에 디테일하게 적기.
  • pdf가 정석이니까 pdf로 봤을 때 형식 맞도록 노션 말고 pdf로 하는게?

새로 쓰면

  • about me 굳이 쓰고 싶다면 2,3줄로 짧게.
  • 사진과 연락처 공간을 줄이기.
  • 스킬을 첫 페이지로 빼기.
  • 프로젝트 제목, 한줄 설명, 기술 스택

종합적으로 : 내가 어떤 '기술자'인지에 대한 설명을 보여줘야 하고, 실력을 길러야 한다.

CS랑 포폴 준비(기술 스택 공부)는 내가 부족하다 싶은 부분에 비중 더 두면 되는 것.

요새 면접 대비용 CS 책들 잘 나와있는거 있으니까 그거 보면

면접 준비

코치님의 피드백

  • 일단 이것보단 기술 면접 질문이 중요하긴 하다. 기술 면접 잘 보면 이런 질문들은 의미 없을 수도. 말 좀 못해도, 심지어는 인성이 별로여도 실력이 출중하면 어느 정도 가려진다. 반대로 말 잘하고 협업 능력 좋아도 실력 안 좋으면 탈락.
  • 1. 문제 해결 능력, 2. 성장 가능성 이 두 가지를 물어보려고 하는 것. '이러면 나한테도 계속 물어보러 오겠네?' 라는 생각 안들게. 검색하고 gpt한테 물어보는게 끝? 이면 면접관이 부정적으로 볼 것.
  • 손흥민은 일단 축구를 잘해서 인기가 있는 것. 축구 선수는 축구를 잘해야 한다. 마찬가지로 개발자는 문제 해결을 잘해야 한다.

1분 자기소개
안녕하세요! (회사이름) (직무)에 지원한 OOO입니다.
저는 학부 때 OO을 전공했고, OO에서 OO으로 1년 반 가까이 근무했습니다.
( 회사에 지원한 이유 ).
저는 빠르게 성장하는 개발자입니다. ( 근거 ).
저는 성실하게 성장하는 개발자입니다. 현재 5개월 가까이 하루도 빠짐없이 TIL을 작성하고 있습니다.
저는 기초를 중요시하는 개발자입니다. 개발자로의 이직을 결정하고 나서 크래프톤 정글이라는 부트캠프에서 컴퓨터 공학을 배우며 기초를 먼저 쌓았습니다.
( 회사에 입사한다면 어떤 부분에서 기여하고 싶은지 말하기 )

본인에게 가장 큰 영향을 준 프로젝트는 무엇인가요?

  • VBA로 업무를 자동화했을 때 뿌듯함이 느껴지면서 개발자를 해야겠다는 생각이 들었습니다.

10년 후에 어떤 개발자가 되고 싶나요?

  • 만들고 싶은 건 무엇이든 만들 수 있는 개발자가 되고 싶습니다.

왜 프로그래밍을 시작했나요?

  • 아이디어를 실현시키는 것에 매력을 느꼈습니다. ( 근거 )

최근 읽은 기술 책은 무엇인가요?

  • 운영체제 가장 쉬운 세 가지 이야기.

본인의 강점은 무엇인가요?

  • 아이디어를 잘 내고, 분석을 잘 하고, 성실합니다. ( 근거 )

프로젝트 일정을 계산할 때 팁이 있나요? 혹은 산정을 잘못한 경험을 얘기해주세요

  • 이제까지의 경험으로 미루어 견적을 내봅니다. 크래프톤 정글에서 팀 프로젝트를 할 때 해본 적 없는 일에 대해 견적을 잘못 냈던 경험이 있습니다.

모르는 기술의 경우 어떻게 학습합니까?

  • 검색해서 관련된 자료를 전부 읽어본 뒤 의문이 가는 부분들을 추가로 학습하거나 의문이 풀릴 때까지 gpt에게 질문합니다. 검색이나 gpt로 한계가 있는 부분은 잘하는 사람에게 가서 물어봅니다.

원격 협업을 어떻게 생각하시나요?

  • 팀의 성향과 상황에 따라 다르다고 생각합니다. 관리만 잘 이루어진다면 오프라인으로 하는 것보다 훨씬 능률이 올라갈 수 있다고 생각합니다.

만약 불가능한 이슈를 수행해야 한다면 어떻게 하겠는가?

  • 불가능한 이슈 중에서도 가능한 부분과 불가능한 부분을 찾아보고, 불가능한 부분에 대해서 또다시 문제를 잘게 쪼개어 무엇이 문제의 핵심인지 파악한 뒤 그것을 해결할 수 있는 방안을 최대한 모색해봅니다. 생각보다 시간이 길어져서 제 역량으로는 아직 건드리기 어려운 이슈라는 판단이 들면 시니어에게 여쭤보거나 결정권자에게 해당 상황을 정리하여 설명드리겠습니다.

논쟁이 벌어지면 어떻게 해야 하나요?

  • 서로의 주장을 뒷받침하는 근거들을 교환하는 것이 가장 핵심이라고 생각합니다. 주장이라는 건 각자가 경험했던 것들과 알고 있던 것들의 결과물이라는 사실을 서로 인지하는 것도 중요하다고 생각합니다. 그 이후엔 서로의 근거에 대한 검토와 숙고를 마친 뒤, 결정권자가 결정을 내리든, 만장일치가 될 때까지 마라톤 회의를 하든, 조직의 형태에 따라 결정을 하면 된다고 생각합니다.

팀원간 의견 불일치가 생긴 경험과 해결한 경험이 있나요?

  • 10명이서 5대5를 하는 게임을 즐겨 했었는데, 게임 중에 화내던 팀원을 게임이 끝나고 나서 차분하게 대화로 풀어 사실 서로의 의견이 달랐을 뿐이라는 걸 납득시킨 적이 몇 번 있습니다.

리더에게 필요한 것은 무엇인가요?

  • 리더에게 필요한 것은 사람을 다루는 능력입니다. 어떻게 다룰 것이냐는 직종마다, 조직의 크기에 따라, 팀원 개개인의 성향에 따라 천차만별이겠지만, 공동의 목표를 위해 해당 팀의 능력을 최대한 이끌어낼 수 있도록 의견을 조율한다던가, 적절한 피드백을 준다던가 할 수 있어야 한다고 생각합니다.

바빠 보이는 상대방에게 꼭 도움을 청해야 한다면 어떻게 하나요?

  • 조직 전체로 봤을 때 제 일이 병목 현상을 일으키고 있다거나 좀 더 급한 일이라고 생각되면 상황을 간략하게 설명드리고 상대방에게 양해를 구하고 어쩔 수 없이 도움을 요청할 것 같습니다.

기술 스택은 어떻게 정하나요?

  • 서비스의 규모와 특성에 따라 결정합니다. 빨리 만들어야 하면 기능을 타협한 프레임워크를 사용하고, 큰 부하를 감당해야 하는 서비스라면 개발 속도를 타협하고 성능을 중요시한 프레임워크를 사용할 것 같습니다.

프로젝트를 함에 있어서 "빠른 호흡"에 대해 어떻게 생각하나요?

  • 초기 아이디어를 시험할 땐 반드시 빠른 호흡으로 해야 한다고 생각합니다. 어느 정도 서비스가 안정화됐더라도 정말로 신중해야 할 때를 제외하곤 빠른 호흡으로 고객과 대화하며 니즈를 빠르게 맞춰야 한다고 생각합니다.

마지막으로 회사에 궁금한 것이 있나요?

  • (회사마다 다르게)


🖥️ CS 공부


추상 자료형과 자료 구조의 차이

추상 자료형 : 뭐를 하라는 것만 정의돼있음. 어떻게 하는지는 자유. 스택이나 큐를 뭘로 만들던 상관이 없다. 그냥 FIFO랑 LIFO만 지키면 됨. 리스트도 add, remove, get만 되면 됨. 배열로 만들었는지 연결 리스트로 만들었는지 궁금하지 않음.

자료 구조 : 실제 구현



⚔️ 백준


📌 2447 별 찍기 - 10

이게 이렇게 오래 걸릴 문제가 아닌 것 같은데 하

N=int(input())
for i in range(N):
    for j in range(N):
        temp_i, temp_j = i, j
        flag = False
        if temp_i % 3 == 1 and temp_j % 3 == 1:
            flag = True
        
        while temp_i >= 3 and temp_j >= 3:
            temp_i //= 3
            temp_j //= 3            
        
            if temp_i % 3 == 1 and temp_j % 3 == 1:
                flag = True

        if flag:
            print(" ",end="")
        else:
            print("*", end="")
    print("")

if문 while에서 밖으로 뺐더니 일정 크기 이상은 찍어주질 못함
안으로 넣었더니 정상 작동

맞았다고 생각해서 제출했더니

시간 초과

내일 다시 하자...
쉬운거라고 생각해서 풀고 가려고 한 거였는데
예상보다 늦어진데다 맞았습니다도 못 띄움

0개의 댓글