해당 포스트를 작성하려다가 문득..

 "도대체 바인더, 바인딩, 바인드 그 의미가 뭘까?"

에서 시작되어 진짜로 그 의미를 파악하고 왔다.

독자도 궁금하다면 대충 스-윽 보고 오면 좋을 것 같다 !

2022.08.04 - [웹개발/JAVA] - [바인딩(Binding)] 바인딩 이란

혹시...

Controller 메소드에 @ModelAttribute UserForm userForm 을 파라미터로 선언하고, jsp 단에 <form:spring modelAttribute="userForm"/> 스프링 폼태그를 사용해 본적이 있는가?

이때 컨트롤러단으로 요청이 들어오면 jsp에서 입력한 값이 modelAttribute 로 지정된 객체의 필드값에 매핑 저장되어 파라미터로 넘어오는 것을 볼 수 있다. 바로 여기서 들어온 요청에 대해 modelAttribute 로 선언된 객체의 필드값이 어떻게 매핑되는지 그 과정을 생각해 본 적이 있는 분!

.

.

.

.

.

메소드에 @ModelAttribute 를 선언했을 때 처리되는 과정은 다음과 같다.

1. 파라미터 타입의 객체를 하나 생성한다.

2. HTTP 요청에서 가져온 객체의 프로퍼티에 바인딩(값을 매긴다) 해준다.
   이 과정에서 각 프로퍼티에 맞게 타입을 변환해준다.
   만약 타입 변환 오류가 생기면 BindingResult 객체에 error 를 저장하여 컨트롤러로 넘겨준다.

 

(아~~ 너무 추상적이다..)

파라미터로 넘어온 친구들에 대해 프로퍼티 바인딩을 해준다.
즉, 각 프로퍼티에 맞게 타입을 변환해준다는 거군.

(그럼 '프로퍼티에 바인딩'한다는 건 머선 말이지..)

.

.

.

.

.

프로퍼티에 바인딩한다? - 2가지 방법

프로퍼티 바인딩이란 오브젝트의 프로퍼티(필드값)에 값을 넣는 행위를 말하는 것이다.

각각의 필드에 맞게 타입을 적절히 변환하고 프로퍼티의 커스텀메소드를 호출하는 것이다.

 

스프링에선 크게 두가지 프로퍼티 바인딩을 지원한다.

1. applicationContext.xml 의 설정파일로 Bean 을 정의할 때 사용한 <property> 태그이다.

해당 태그를 통해 빈의 프로퍼티에 값을 주입했었다.

예시

<!-- Hadler Mapping -->
<bean
   class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
   <property name="order" value="1" />
</bean>

<bean
   class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
   <property name="order" value="0" />
</bean>

2. Http request 파라미터를 모델 객체로 변환하는 경우이다.

.

.

여기서 잘 생각해보면, 저 value 에는 문자열이 아닌 Class 타입이 들어가는 경우도 있다.

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
   <property name="annotationClass" value="org.mybatis.spring.annotation.MapperScan"/>
   <property name="sqlSessionTemplateBeanName" value="sqlSession"/>
</bean>

이런 경우 value 에 문자열로 클래스명을 전달한다. 하지만 잘 바인딩 된다.

이는 스프링에서 제공되는 프로퍼티 바인딩 기능을 사용했기 때문이다.

스프링은 프로퍼티 바인딩을 위해 두 가지 API 를 제공한다고 한다.

 

PropertyEditor

스프링에서 제공하는 기본적인 프로퍼티 바인딩 API 이다. 

PropertyEditor 는 스프링 API가 아니라 자바빈 표준에 정의된 API이다.
GUI 환경에서 비주얼 컴포넌트를 만들 때 사용하도록 설계되었고, 기본적인 기능은 문자열과 자바빈 프로퍼티 사이의 타입 변환이다.
스프링은 이 PropertyEditor 를 문자열-오브젝트 상호변환이 필요한 XML 설정이나 HTTP 파라미터 변환에 유용하게 사용할 수 있다고 판단하여 이를 일찍부터 사용해왔다.

핵심은 이 디폴트 PropertyEditor들은 바인딩 과정에서 파라미터 타입에 맞게 자동으로 선정되어 사용된다는 것이다.

디폴트 프로퍼티 데이터에 등록되지 않은 타입을 파라미터로 사용하고 싶다면 직접 PropertyEditor 를 구현하여 등록하고 사용할 수 있다.

 

WebDataBinder

직접 구현한 에디터를 구현하기 전에 Controller 에서 메소드 바인딩하는 과정을 먼저 살펴보자.

AnnotationMethodHandlerAdapter 는 @RequestParam, @PathVariable, @ModelAttribute 와 같이 HTTP 요청을 변수에 바인딩하는 어노테이션을 만나면 먼저 WebDataBinder 라는 것을 만든다.

WebDataBinder 는 여기서 HTTP 요청 문자열을 파라미터로 변환하는 기능을 한다.

-> WebDataBinder (이 친구) 때문에 바로 이 글을 시작할 때 언급했던 ModelAttribute 를 선언한 메소드의 객체 필드에 매핑이 되는 것이다.

이때, 직접 구현한 PropertyEditor 를 사용하려면 이 WebDataBinder 에 직접 등록해줘야 한다.

근데 WebDataBinder 의 변환 과정이 외부로 노출되지 않으므로, 직접 등록해줄 방법은 없다.

그래서 스프링이 제공하는 WebDataBinder 초기화 메서드를 사용해야 한다.

.

.

.

.

@InitBinder

Controller 클래스에 아래와 같이 @InitBinder 어노테이션이 부여되고, WebDataBinder 를 매개변수로 받는 메소드를 하나 생성해 봅니다.

@Controller
public class Controller {
    // 모든 요청이 들어올때마다 해당 method 를 거친다.
    // 모든 컨트롤러 내에서 변환 하려면 ConfigurableWebBindingInitializer 를 설정해서 사용해야 한다.
    // 특정 컨트롤러 내에서만 변환 하려면 컨트롤러에 @InitBinder가 붙은 메서드를 작성하여 사용하면 된다.
    @InitBinder
    private void initBinder(WebDataBinder binder) {
        // , 구분자로 배열화하는 것을 방지한다.
        binder.registerCustomEditor(String[].class , new StringArrayPropertyEditor(null));
    }
    .
    .
    @RequestMapping("json/binder.do")
    public String binder(@RequestParam(value = "param", required = false) String[] param) {
     //...    
    }
 }

initBinder 메서드는 클래스내의 모든 메서드에 대해서 파라미터를 바인딩하기 전에 자동으로 호출된다.
바인딩 적용 대상은 @RequestParam, @PathVariable, @CookieValue, @RequestHeader, @ModelAttribute의 프로퍼티 이다.

기본적으로 PropertyEditor는 지정한 타입과 일치하면 항상 적용된다.
여기에 프로퍼티 이름을 추가 조건으로 주고, 프로퍼티 이름까지 일치해야만 적용되게 할 수 있다.
이러한 타입의 PropertyEditor는 이미 PropertyEditor가 존재할 경우 사용한다.
WebDataBinder는 바인딩 시 커스텀 PropertyEditor가 있을 경우 이를 선적용하고, 없을 경우 디폴트 PropertyEditor를 적용하기 때문이다.

.

.

.

.

.

 

+) 추가 예시 설명

binder.registerCustomEditor(String[].class , new StringArrayPropertyEditor(null));

해당 customEditor 를 등록해주지 않은 경우

@RequestParam 에 배열타입으로(String[ ]) 들어오는 파라미터에 쉼표(,) 구분자가 있는 경우 디폴트(PropertyEditor)가 적용되어 무조건  쉼표(,) 구분자(쉼표가 default인 듯)에 의해 배열화 된다.

 

registerCustomEditor 인자로 String[].class , new StringArrayPropertyEditor(null) 값을 넣으면,

String [] 배열 타입에 대해 어떤 구분자로도 배열화하지 않겠다고 선언하는 것이다. (null 자리의 인자값은 seperator임)

 

필자가 원하는 값은 파라미터에 쉼표가 존재하더라도 하나의 문자열로 보고 구분하지 않도록 하는 것이었기 때문에 위와 같이 적용해주었다.

 

[registerCustomEditor 사용전]

@InitBinder
private void initBinder(WebDataBinder binder) {
    //binder.registerCustomEditor(String[].class , new StringArrayPropertyEditor(null));
}

@RequestParam(value="to") String[] to

입력 값 "테, 스트"<test01@ttestt.kr>
기대 값 to[0] = ""테, 스트"<test01@ttestt.kr>"
결과 to[0]=""테"
to[1]="스트"<test01@ttestt.kr>"

 

, 쉼표 구분값으로 배열화된다.

 

[registerCustomEditor 사용후]

@InitBinder
private void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(String[].class , new StringArrayPropertyEditor(null));
}
입력 값 "테, 스트"<test01@ttestt.kr>
기대 값 to[0] = ""테, 스트"<test01@ttestt.kr>"
결과 to[0]=""테, 스트"<test01@ttestt.kr>"

, 로 배열화 하지 않음

, 쉼표로 배열화하지 않고 한 덩어리로 넘어온 것을 확인 할 수 있다.

 

 

참고 출처 : https://joont92.github.io/spring/%EB%AA%A8%EB%8D%B8-%EB%B0%94%EC%9D%B8%EB%94%A9%EA%B3%BC-%EA%B2%80%EC%A6%9D/

'웹개발 > Spring' 카테고리의 다른 글

[Mybatis] resultMap  (0) 2022.09.04
[Mybatis] Mybatis 기술의 탄생! (feat.ORM)  (1) 2022.07.30

도대체 개발에서 말하는 바인딩이란 뭘까?

"WebDataBinder, BindingResult, initBinder ...... 바인드... 그게 머선 말이고???????"

1. 본디 태초부터 돌아가 그 뜻을 알라!

영어 bind 의 사전적 의미

- (기본적으로) 묶다.

- (정보통신) 두 개의 정보를 서로 연결하는 작업.

- (오픈사전) 지정된 시간 동안 두 개 이상의 프로그래밍 개체 간에 연결을 만드는 것.

 

그러니까 본디 그 뜻을 보아하니.. 뭔가 연결시키고, 연관시키고, 하나로 꽉 묶고, 결합시키고 하는 건가보네?

 

개발적 언어의 의미

속성과 개체 사이 또는 연산과 기호 사이와 같은 연관이다. ( -_- 무슨 말? )
즉, 바인딩(binding) 이란 프로그램의 어떤 기본 단위가 가질 수 있는 구성요소의 구체적인 값, 속성을 확정하는 것(줄로 꽉 묶는다는 뜻 연상)을 말한다. ( 오케이, 앞에거 모르겠고. 일단 느낌은 "값을 매긴다, 확정한다"  요거 구먼. )

2. 예를 들어보자면~

프로그램의 기본 단위인 변수를 예로 들면,

int num = 123;

여기서 int 는 변수의 자료형, num 은 변수 이름, 123 은 변수의 자료값이다.

즉, 데이터 타입이 int 라는 것으로 바인딩되고,
a 라는 변수명에 바인딩 되고,
1 이라는 값이 바인딩 되는 것이다.

(아하 ~~ 너낌 와쒀. 한마디로 정리해서)

이름, 자료형, 자료값에 각각 num, int, 123 이라는 구체적인 타입, 이름, 값이 정해지고
메모리 할당하는 것 각각의 과정을 바. 인. 딩. 이라고 한다.

3. 두가지 바인딩

조금 더 깊이 들어가자면, 일반적으로 바인딩은 일어나는 시간에 따라 크게 정적 바인딩, 동적 바인딩으로 분류한다.

 

정적 바인딩(Static Binding)

컴파일 시간에 일어나며, 실행 중 변하지 않고 유지된다.

- 함수의 정적 바인딩은 컴파일 시간에 호출될 해당 함수의 주소가 결정되어 바인딩 된다.
 즉, 실행 파일에 호출할 함수가 위치한 메모리 주소가 이미 확정 기록된 것이다.

 

동적 바인딩(Dynamic Binding)

- 실행시간 (run time) 중에 일어나며, 프로그램 실행 도중에 변경이 가능하다.

- 말그대로, 실행 파일을 만들때 호출할 함수의 메모리 주소가 확정되지 않고, 이후 실제로 실행되는 그 시간에 호출할 함수의 주소가 결정된다. 

- 그렇기 때문에 이 주소를 저장할 공간을 미리 확보해둔다.

- 실행될지 안될지 확정되지 않았기에 일단, 해당 함수를 위해 저장공간을 할당해야한다는 점에서 메모리 관리에 비효율적이다.

(쏼라~쏼라~~ 메모리 관리에 효율적이냐 비효율적이냐를 말한것이군.. 아무튼 한줄 요약하자면~~)

실행 이전(컴파일될때)에 값이 확정되면 정적 바인딩 ,
 이후(진짜 코드가 실행될때)에 값이 확정되면 동적 바인딩인 것이다.

4. 결론

아주 쉽고 간단하게 말해서, 개발에서 말하는 바인딩은 값이 확정되어 최종적으로 값이 매겨지는 것을 말하는 것이다.

 

 

출처 : https://medium.com/pocs/%EB%B0%94%EC%9D%B8%EB%94%A9-binding-4a4a2f641b27

 

1. 데이터 접근 기술

-> 데이터를 효과적으로 저장하기 위해 발전한 독립적인 기술

자바에서 관계형 데이터 베이스를 사용하기 위해서는 서로 다른 기술 패러다임 간의 인터페이스가 필요하게 되는데,

그게 바로 데이터 접근 기술이며, 그 중 가장 중요한 jdbc sql mapper 그리고 orm 에 대해서 알아보자!

2. DB 에 접근하는 방법

DB Connection 얻기 커넥션 연결
SQL 전달 및 실행 서버는 DB에게 원하는 동작을 SQL로 표현하여 연결된 커넥션을 통해 DB 에 전달
DB Connection 닫기 DB는 전달된 SQL 을 수행하고 그 결과를 응답한다.
서버는 응답 결과를 활용하고 커넥션을 닫는다.

☞  여기서 문제!
각 DB 마다 Connection 연결 방법, SQL 전달 방법, 응답 결과 받는 방법이 모두 다르다는 점이다.

- DB 를 다른 DB로 변경하게 되면 서버에 개발된 DB 코드도 모두 변경해야함.

- 개발자가 각각의 DB마다 커넥션 연결, SQL 전달, 결과 응답 방법을 새로 작성해야함. 

 

흠 데이터 접근 방법이 통일된다면 내가 DB 를 mysql 사용하다가 oracle 로 변경해도, 다른 DB 를 추가해도 DB 연결을 수정하지 않아도 될텐데 말이에요.

3. 아하!그래서 JDBC (Java DataBase Connectivity) 가 등장했구나

데이터 저장기술을 DataSource 라는 '추상화된 인터페이스(하나의 규격)'를 통해서 접근할 수 있도록 한다.

자바를 이용해서 다양한 데이터 저장 기술에 '일관적'으로 접근할 수 있는 데이터 접근 기술 인 것이다.

 

<동작 과정>

1. DB Connection 얻기 Connection con = null;
try{
  Class.forName("DB별 드라이버 네임")
  conn = DriverManager.getConnection(url,id,pw)
}
2. Statement 생성 String sql = "Select * from users where userid = ?";
PreparedStatement ps = con.prepareStatement(sql)
ps.setString(1,"test01")
3. 쿼리 실행 ps.executeQuery();
4. ResultSet 처리 ResultSet rs = ps.exexuteQuery();
if ( rs.next() ) {
  String name = rs.getString("name") ;
  String age = rs.getString("age") ;
  String job = rs.getString("job") ;
}
5. Connection 닫기 } finally {
 if( ps != null ) {
  ps.close(); 
 }
 if ( con != null ) {
  con.close();
 }
+) 예외처리 catch ( Exception e ) { 
 return null ; 
 }

그렇지만... JDBC  너도 불편해!

1. 반복되는 데이터 접근 관련 코드
 - 위 동작과정의 1번 ~ 5번까지의 일정한 작업이 반복된다.

2. 핵심/비핵심 관심사 미분리
 - 핵심 관심사 는 DB가 수행할 동작을 표현한 SQL 이다. (CRUD)
 - 위 동작과정과 같이 비핵심 관심사가 공존하게 된다.

3. JAVA Code 내 SQL 직접 전달 문제

 - JDBC 가 사용하는 SQL 은 단순 문자열로 컴파일 체크가 불가능하다.
 - 문법 오류 및 오타 발생 확률이 굉장히 높다.

 - 또한 자바 어플리케이션 내 다른 언어인 SQL 을 포함되어 SQL 이 핵심 로직을 담당하는 주객전도 현상이 발생한다.


3. ORM (Object Relational Mapping) 그게 먼데?

Object Relational Mapping, 객체-관계 매핑
- 프로그래밍 언어의 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 하나의 도구 또는 기법이다.

4. ORM 을 왜.. 사용하는거지 ?

- 객체지향 프로그래밍은 클래스를 사용하고, 관계형 데이터베이스는 테이블을 사용하는데 객체 모델과 관계형 모델 간의 불일치가 존재한다.(참고 https://coco-log.tistory.com/155 https://hibernate.org/orm/what-is-an-orm/ )

- ORM 을 사용해서 객체 간의 관계를 바탕으로 SQL 을 자동으로 생성하여 불일치를 해결한다.

- ORM 을 사용해서 데이터베이스 접근을 프로그래밍 언어 관점에서 맞출 수 있다!

  > 비즈니스 로직에 좀 더 집중할 수 있고, SQL 의 절차적인 접근이 아닌 객체 지향적인 접근으로 인해 생산성이 증가된다.

- ORM 을 사용해서 SQL 자동 생성을 통해 엔티티를 객체로 표현할 수 있다.

- ORM 을 사용해서 객체를 통해 간접적으로 데이터베이스를 다룬다.

 

그렇다면 잘 사용하고 있다가 굳이 이런 새로운 개념이 나온걸까?

-> 그 배경에는 개발을 함에 있어서 "기본에 충실하자" 를 지키자는 것, 그 기본이 바로 객체지향적인 중심의 프로그래밍을 하자는데에 그 출발점이 있다.

 

예를 들어, 어떤 사이트의 사용자를 만든다고 하면 관련 정보를 사용자(User)라는 객체에 담아 보관한다.

해당 객체에는 이름,생년월일,직업,직급,소속 등 정보들이 저장될 것이다.

이렇게 생성한 사용자 라는 객체를 영구적으로 저장하기 위해 데이터베이스에 입력(insert)한다는 것은 객체와 그와 연결된 데이터베이스 테이블에 저장한다는 것을 의미한다.

이때, 여기서 문제가 발생하는데 바로 테이블과 입력한 객체 간의 이질성이 발생하게 되는 것이다. 즉 객체 모델과 관계형 모델 간의 불일치가 존재하는 것이다. ( 검색해보니까 이걸 '객체지향 모델과 관계형 모델의 패러다임 불일치' 라고 하고 있다. )

이 문제를 해결하기 근본적으로 ORM 기법을 사용하는 이유 중 하나인 것이다.

 

출처 : https://hanamon.kr/orm%EC%9D%B4%EB%9E%80-nodejs-lib-sequelize-%EC%86%8C%EA%B0%9C/

 

[데이터베이스] ORM이란? (Node.js ORM Lib Sequelize 소개) - 하나몬

⚡️ ORM (Object Relational Mapping) ❗️ORM 이란? ORM은 Object Relational Mapping(객체-관계-매핑)의 약자이다. ORM은 객체와 데이터베이스의 관계를 매핑해주는 도구이다. ORM은 프로그래밍 언어의 객체와 관

hanamon.kr

출처 : https://hello-bryan.tistory.com/318

 

ORM 이란

펌글입니다. : http://www.incodom.kr/ORM#h_702209f3f35878a32ee91352ddc6bbe7 ORM이란? ORM(Object-relational mapping)을 단순하게 표현하면 객체와 관계와의 설정이라 할 수 있다. ORM에서 말하는 객체(Obje..

hello-bryan.tistory.com

'웹개발 > Spring' 카테고리의 다른 글

[Mybatis] resultMap  (0) 2022.09.04
[@InitBinder 어노테이션-WebDataBinder]  (0) 2022.08.05

개발자로서 이메일 작성해야 할 때 막막한 순간이 한두번이 아니다.
오늘은 그 어려움을 공유하고자 글을 끄적이게 되었다.

나 . 름 . 문과 출신이라 글쓰기는 문제없겠거니~ 생각했지만, 개발 분야에서는 완~전 신생아 걸음마 수준의 글쓰기 능력으로 전락해버렸다. (사실이늬?)

필자가 이메일을 작성하면서 어려움을 느끼는 순간은 다음과 같은 경우이다.

(일단 쫌 있어보이게, 쫌 전문적으로, 적어도 내가 신입티는 나지 않게 작성해야한다는 생각을 가지고 시작한다.)

1. 나는 이해됐는데.. 이걸 어떻게 설명하지..? 아니 이걸 글로 어떻게 써야돼..? 하는 순간들
- 대상
 > 고객인 경우 : 문의 요청을 하거나 문의 답변을 작성할 때
 > 상사인 경우 : 이슈 사항에 대해 보고할 때

2. 개발자언어를 사용자언어로 전환해야 하는 순간들
 - 개발적이지만 너~~~무 개발적인이지 않은 단어를 선택해서 전달해야할 때

3. 1번 2번 둘 다 상황일 때.. ( 최악이다.. ㅜ0ㅜ )

예를 들어서 )

상황 : 스토리지에 연결해서 저장되어 있는 메일 파일을 가져와서 보여줘야 하는데 보이지 않는 장애가 발생함.

원인은 업로드 시 스토리지에 한 번 연결하여 업로드 후, 완료되면 연결을 끊어줘야 하는데 끊어주지 않아서 다음 스토리지 연결할 때 연결 오류가 발생하여 메일이 열리지 않았던 것이다.

근본적인 원인을 찾아보니 소스상에서 InputStream 사용을 해놓고, close 해주지 않아 발생한 문제였다. (try-catch에서 finally{} 부분의 자원해제.. )
곧바로 누락된 close 처리를 하여 해결할 수 있었다.

이런 장애 이슈 발생 시,  사용자에게 해당 상황과 원인/해결을 개발적으로 전문적이면서 그렇게 개발적인 언어를 사용하지 않고 어떻게 설명을 해야할까.

필자가 초안으로 작성했던 건 다음과 같다.
<수정 전>

장애 일시 : 2022년 00월 00일
처리 일시 : 2022년 00월 00일
장애 현상 : 메일이 열리지 않음
상태 : 스토리지 연결 불가
원인 : 오브젝트 스토리지 inputstream close 처리 누락으로 연결되지 않음.
조치 : inputstream close 처리하여 리소스 누수 발생하지 않도록 조치함.

나름 스스로 잘 작성했다고 생각하고 동료에게 검토요청을 하였으나, 수정할 부분이 꽤 있었다..
제일 중요한 부분은 원인과 조치 사항 부분이다.

원인이 저건 맞지만, 저렇게 작성하였을 때 문제는 고객(사용자)에게 '우리 소스가 애초에 개발이 잘못되었다.' 라는 걸 너.무. 솔직하게 이실직고 하는 것밖에 안되는 것이었다. 우리회사의 신뢰성을 깨뜨리는 것밖에..

업무 처리를 하면서 상황에 맞게 처리하는 것을 우리는 "유연성"이라고 하는데, 필자가 작성한 부분이 딱 그 유연성이 떨어지는 문장이었다.

동료가 제안한 문장은 '커넥션 풀부족으로 인한 오류' 였다.
inputStream 이니, close 니 하는 너~~무 개발적인 언어가 아니면서 동시에 전문적인 개발 언어를 사용자화한 문장이었다.
여기서 말하는 사용자는 전문적으로 개발을 잘 아는 사람은 아니지만 비슷한 분야에서 일하고 있는 전산관리자일 가능성이 매우 크다.
그렇게 생각해보면 관리자 입장에서 충분히 이해할 수 있는 문장일 것이라는 생각이 들었다.
어떻게 저런 문장을 생각할 수 있었는지.. 놀라울 따름이었다. 동료의 조언을 받고 다음과 같이 수정하였다.
<수정 후>

장애 일시 : 2022년 00월 00일
처리 일시 : 2022년 00월 00일
장애 현상 : 메일이 열리지 않는 오류
제품 상태 : 스토리지 연결 불가
원인 : 오브젝트 스토리지 커넥션 풀 부족으로 인한 연결 오류
조치 : 커넥션 풀 유지되고 있는 항목 끊고 연결할 수 있도록 조치함.

한층 간결해졌다.

예시를 들어 설명하다 보니, 앞으로 메일을 작성할 때 어떤 부분을 더 고려해야할지 조금은 알 것 같다.

개발기술 관련된 서적을 많이 찾아보는 것도 도움이 될 것 같다.
우리가 이해하고 소스적인 부분을 어떻게 공통(대상이 누구든 이해할 수 있는) IT 용어로 전환해서 작성했는지도 눈여겨 봐야할 것이다.

읽어주셔서 감사합니다 :-)

+) 가끔씩 이렇게 메일 작성하면서 곤란하거나 어려웠던 부분을 공유해보겠습니다.!

[사람-관계-]
힘들다. 사람도, 일도 모든 것에 지쳐가고 있다.
몇 번이나 다시 일어서려 했지만 얼마 못 가 자꾸 주저앉게 된다.
무엇이 문제인지 모르겠다. 사실은 아는데 모르는 척하는 걸까.
모든 것이 싫어지는 요즘이다.
내가 뭘 잘하는지도 모르겠고, 일을 하면서 내 자존감이 너무 낮아져서 회사에 출근하기가 싫은 마음도 생긴다.


[ '나' 분석 ]
나는 왜 우울한가.
지금
왜 이렇게도 우울한가.
왜 이렇게도 기분이 다운되어 있나.
왜 이렇게도 무기력한가.
스스로 답답함을 느끼는 순간
- 상대방이 한 말을 한 번에 이해를 하지 못한다.
- 한 번 얘기한 걸 기억하지 못하고, 두 번 이상 말하게 만든다.
- 이해가 느리다.
=> 결과 : 나의 부족함 때문에 자신감이 사라지고 -> 그러니까 자존감이 낮아지고..
 -> 회사가기 싫고. -> 부정적인 생각이 들고. 악순환이네;ㅜ


.

.

.

.

[근본적인 원인과 해결책]
이렇게 글을 작성하면서 느낀 건데, '속도의 차이' 에서 해결책을 찾을 수 있을 것 같다.

나는 비전공 개발자이다.

비전공에 대한 편견이 싫어서 스스로 구분 짓는 걸 너무나 싫어하는데, 가끔은 정말로 전공자와 비전공자의 차이가 있는 것인지 의심이 들 때가 있다. 특히 동료를 보면 그렇게 느껴진다.
자격지심일까.
그 친구는 이해가 정말 빠르다. 자기가 이해한 것을 남에게 설명을 잘한다.
가장 큰 장점은 문제에 대한 핵심을 정말 잘 파악한다. 그래서 해결을 하기 위한 솔루션도 금방 찾는다.
빠르게 문제의 핵심을 파악해서 어디 부분을 어떻게 고쳐야 할지 정확하게 아는 것이다.
일 잘하는 사람은 이렇구나를 이 친구에게서 느끼고 있다.

실무를 접하며 개발자라는 직업이 단순히 기능을 만드는 것이 아님을 알게 되었다.
이 직업의 가장 큰 핵심 역량은 문제 파악과 해결 능력이다..
하지만, 생각해보면 모든 직업이 그렇지 않을까?
우리가 마주하는 모든 상황에는 늘 문제가 존재한다. 마케팅도, 영업도, 기획도, 경영도, 모두 분야에서 말이다.
그 어떤 직업에서든 요구하는 핵심 역량은 문제 해결 능력인 것이다.
실무를 하다 보니까 취업준비 때 왜 그렇게도 기업들이 문제 해결 능력이라는 역량에 대해서 보고 싶어 했는지 알겠다.
이 역량이 정말로 선천적으로 타고나야만 가능할까? 그건 아닌 것 같다.
어떤 문제를 파악하는 데에 유전적 요소가 있는 것은 아니니까.
내가 내린 정답은 '빠른 이해도'이다..
이해도 이해지만, 기업은 ‘빠른 이해를 추구한다. 우리에게 주어진 시간은 한정적이기 때문이다.
문제를 정확히 파악해도, 주어진 시간 내에 ‘빠르게’ 하는 것은 능력인 것이다.
주변에 일 잘하는 동료들을 보면 얼추 맞아떨어지는 얘기라고 생각된다.
반면, 나는 말이지... 빠르게......가 안된다...
속도가 느리다.
속도는 노력으로 되는 부분일까?
.
.
.
.( 생각 중 )
.
.
.
- 나는 된다고 생각한다!
왜 그런지는 먼저 일 잘하는 그들을 분석해보자.

그들은 왜 그렇게도 속도가 빠를까?
- 깊은 지식과 다양한 경험이 그것의 기반이지 않을까.
: 지식은 그들이 배운 전공 지식과 다양한 프로젝트에서 비롯된 경험들인 것이다.
그럼 나는 그들의 언저리라도 가려면 어떤 노력을 해야 하는가?
- 부지런히 (정확한)개념을 쌓아야 한다. ( 전공지식이든, 뭐든, 정확한 개념 숙지를 하며 기반을 다져야 한다. )
- 다양한 프로젝트 경험을 해야 한다.
나의 문제는 정. 확. 히. 부족한 나의 지식과 경험에서 비롯된 일처리의 어려움 이 그것이었다. (이마 탁!)
정답은?
-> 시간을 내어 지식과 경험을 쌓으면 된다.

 

단지 이것이 정말 어렵다는 것이다. 그래서 어쩌면 나는 문제에 대한 정답을 알고 있었으면서 모른 척하지 않았던 게 아닐까 의구심이 든다. 나는 그들의 하이라이트만 보고 있었던 것이다.
비유하자면 탑스타의 화려한 모습만 보고, 그 자리에 오르기까지의 과정은 보지 않은 것과 같은 것이다.
그들도 분명 시간을 들여 공부하고 시행착오를 겪었던 경험이 있었을 텐데 말이다.
어쩌면 내 스스로가 자존감을 갉아먹고 있었던 것이 아닐지도 모른다는 생각이 들었다.
그래서 비전공자는 전공자보다 더 많은 노력을 기울여야 한다.
이 사실은 저명한 사실이지만, 자꾸 잊어버리게 된다.
이 분야로 진로를 변경할 때 나는 어떤 초심이었는지 되새겨볼 필요가 있다.

뒤늦은 성장에는 뼈를 깎는 고통이 수반되어야하는 것임을 느끼는 요즘이다.

글의 시작은 우울했지만, 이렇게 나를 분석하고 (사실은 알고 있었던) 정답을 알게 되니까 다시 자신감이 생긴다.
내일은 또 어떤 면박을 당할지, 어떤 예상치 못한 일들이 기다리고 있을지 정말 두렵고 마주하기 싫지만,
그럼에도 불구하고 내일은 오며, 머피든 샐리든 둘 중의 하나의 법칙에 따라 일어날 일은 일어나므로,
굴하지 않고! 자신감 있게! 모르면 알면 되니까! 마인드로 헤쳐나가 보겠다.

'개발실무 너 참 쉽지 않구나? > 아직 적응기' 카테고리의 다른 글

아직도 적응중 CH.1  (0) 2022.07.15

마운트가 몬가요?

기본적으로 우리는 윈도우의 하드디스크, CD롬, 플로피디스크 이런 것들에는 익숙하나,
리눅스의 마운트 관련해서는 굉장 낯설다.
윈도우에 외장하드디스크나 CD롬 같은 디바이스들을 추가하거나 USB 를 꽂으면 우리의 시선은 자연스레 폴더를 열기 알림이 뜨는 우측하단으로 향한다. 이게 바로 윈도우에서 사용자가 마운트를 하지 않아도 되는 이유이다. 윈도우에서 알아서 자동으로 E:\ , D:\ 이런식으로 폴더를 잡아주기 때문이다.
이와 같이 물리적인 장치를 특정 디렉터리에 연결시켜주는 것을 마운트라고 한다.
윈도우에서는 이걸 자동으로 실행해준다고 하니.. 그동안 리눅스처럼 직접 마운트해줄 일이 없었던 것이다.
윈도우의 드라이브 당 하나의 디렉터리 트리 구조를 갖는다고 볼 수 있다.
리눅스에서 마운트를 해주기 위해선 파티션설정 과 포맷에 대한 선작업이 이뤄져야 한다.
디바이스(윈도우의 하드디스크라고 생각하면 될 것 같음)에 연결시켜줄 /drv 디렉터리를 만든다.
mount /dev/sdb1/drv
-> /dev/sdb1 디바이스를 /drv 디렉터리에 마운트(매핑) 시키겠다. 라는 뜻이다.
FileSystem 1K-blocks Used Available Use% Mounted On
/dev/sdb1 6377478 555 555453 1% /drv
mount -t ext4 -o ro /dev/sdb1 /mnt
-> 파일시스템이 ext4인 /dev/sdb1을 /mnt 디렉터리에 읽기 전용으로 마운트 한다.
출처 : https://jhnyang.tistory.com/12

출처 : https://techblog.woowahan.com/8484/

 

우테코에서 찾은 나만의 효과적인 공부법 | 우아한형제들 기술블로그

{{item.name}} 안녕하세요. 테크코스교육개발팀 이원미입니다. 어느덧 우아한테크코스 (이하, 우테코) 4기도 과정의 중반을 지나가고 있습니다.(시간이 왜 이렇게 빠르게 흘러가는지..) 기수가 더해

techblog.woowahan.com

어느 날 기술블로그 라는 것에 꽂혀 찾아보다가 해당 글을 발견했고, 그분들의 소중한 경험이 녹아있는 공부방법 글을 읽다가 감명받아 몇 글자 끄적여 보았다. (중간중간 그분들의 글을 인용하였습니다.) 

개발 철학에 대한 고민

"어떤 개발자가 끝까지 살아남을 수 있을까.
어떤 개발자가 유능한 리더가 될 수 있을까.
어떤 개발자가 효율적으로 일을 할 수 있을까."

좋은 개발자가 되기 위해서는 어떤 노력들이 필요할까.

학습방법
개발에 대해서 나만의 공부 방법을 아직 찾지 못한 것 같다. 어떻게 해야할지는 알겠으나, 그 방법을 온전히 나의 것으로 만들지 못했다. 나만의 학습방법을 찾는 것이 중요할 것 같다.

기억장치
개발을 잘 하는 것은 내가 짠 코드에 대한 기억, 내가 배운 개념의 기억이 모두 탑재되어 있어야 한다.
적어도 내가 짠 코드, 내가 진행하고 있는 프로젝트에 대해서는 정확한 구조 및 상세 내용을 암기해서라도 내 머릿속에 박혀 있어야한다. 그게 일 처리 속도를 올려주며, 소통을 원활하게 할 수 있게 해줄 수 있는 지름길 같다.

왜라는 이유
내가 코드를 그런 방식으로 짠 이유. 즉 논리가 머릿속에 박혀야 한다. 그래야 나만의 소신으로 의견을 낼 수 있기 때문이다. 그렇지 않으면 말문이 막히게 되는 그런.. 마주하기 싫은 상황에 내놓이게 될 것이다.
항상 모든 상황에는 근본적인 문제가 있다. 그 문제를 해결하기 위해 기능 위에 기능이 얹어지고 덩치가 불어난게 아닐까.
왜라는 질문에 왜를 붙이며 생각을 넓혀 나가자.

개발을 바라보는 태도
"지금 내가 해야하는 일은 완벽한 정답을 찾는 것이 아닌 계속해서 틀리며 이게 왜 틀린지 알아는 것이 정말 중요하다."
그것들은 정확히 내 머릿속에 입력해야되고, 잊어버리지 않아야 한다. 계속해서 리마인드 하는 것이 정말정말 중요하다. 특히 나같은 경우는 말이다.

"누군가는 정말 섬세하게 공부하고, 누군가는 개발자로서의 신념이 뚜렷하며, 누군가는 정말 재미있게 개발 자체를 즐긴다. 또 누군가는 커뮤니케이션을 정말 잘하고, 말을 상냥하게 하며, 리더쉽이 있다. 이렇게 제 각기로 빛나는 사람들 사이에 있다 보면 끊임없이 스스로를 되돌아보게 되고, 더 좋은 개발자를 넘어서 더 좋은 사람이 되어갈 수 있을 것 같은 기대감에 휩싸인다."

비난 받는 것에 두려워 하지 말며, 좋은 기회로 발판 삼자. 

나는 할 수 있다.

'개발실무 너 참 쉽지 않구나? > 아직 적응기' 카테고리의 다른 글

아직도 적응중 CH.2  (0) 2022.07.24

+ Recent posts