좋은 개발자가 되려면 - 개발편

9 minute read

水滴石穿 (수적석천) - 물방울이 돌을 뚫는다는 뜻으로, 미미(微微)한 힘이라도 꾸준히 노력(努力)하면 큰 일을 이룰 수 있음을 비유(比喩ㆍ譬喩)해 이르는 말


좋은 개발자가 되려면 어떻게 해야할까?

2011년도 11월부터 개발을 시작해서 지금까지 항상 머리속에 있는 고민이다. “좋은 개발자가 되려면 어떻게 해야할까” 사실 정확히는 비 전공자로 시작해서 2011년부터 2016년도까지는 이런 생각할 틈새도 없이 회사일에 파묻혀 지나오고 보니
어느정도 나를 돌아보게 되었을 때, 내가 가고 있는 길은 맞는가라는 의문 부호가 내 머릿속을 떠나지 않았다.

다른 사람들이 보기에는 그런 생각을 이제와서 하기에는 꽤나 늦은 시간이 아닌가라고 생각할 수 있지만, 현재 10년차에 개발자로 살아가고 있는 나에게는 지금도 가장 고민이 되는 부분이다. 어떻게 하면 좋은 개발자가 될 수 있을까? 어떻게 하면 내가 좀더 성장 할 수 있을까? 이에 대한 답을 찾은 건 아니지만, 그간의 경험과 나의 생각들을 녹여 그 의견을 2가지 파트로 준비해보고자 한다.

당연히 개인적인 생각과 경험들에 근거했기 때문에 정답이라고 이야기할 수는 없지만, 나 스스로에 대해서 정리하며, 같이 공유할 정도는 되지 않을 까 생각했다.

내가 생각하는 좋은 개발자

  • 개발 편
  • 사람 편

이번 Post에서는 개발편에 대해서 책을 통해서, 경험을 통해서 얻고 느낀점을 공유해보겠다.

회사의 업무를 깊이 있게 파악하라. 그래야 제대로된 개발이 가능하다.

개발자로써 하루의 삶의 대부분은 특정 기업/단체에 속해서 일하는 경우가 대부분이다. 사실 그렇다. 개발자 본인이 스스로 기업/단체를 만드는 경우를 제외하면 대부분의 개발자들은 속해있는 곳의 사업 아이템/도메인을 개발하고, 개선하고, 확장시키고, 유지보수를 수행하는 업무를 할 수 밖에 없다. 프리랜서의 경우에도 결국엔 특정 도메인의 프로젝트 수행을 위해서 일을 하는 것이라 보기 때문에 모든 개발자들에게 적용된다고 생각한다.

그렇다면 특정 도메인 내에서 본인의 원하는 개발을 하고자 하면 어떻게 해야하는가? 결국엔 해당 도메인에 대한 깊은 이해 없이는 제대로된 개발을 할 수 없다. 내가 해야할 업무를 정확히 이해하지 못하고 작성한 코드는 결국 서비스의 결함 또는 이슈가 발생할 수 있는 요소가 생기게 되고, 이는 아무래 해당 개발자가 개발을 잘하더라도, 전혀 인정 받을 수 없는 상황이 초래된다.

개발을 위한 Skill Up, 당연히 너무 중요하며 개발자에게 공부란 평생을 함께 해야할 동반자와 같기에 이를 게을리 하라는 이야기가 아니다.
하지만, 결국 모든 개발은 비즈니스를 위핸 개발이 있는 것이지 개발을 위한 개발은 있을 수 없다고 나는 자신있게 이야기하고 싶다. 본인에게 주어진 업무에 대해서 명확하게 이해하고, 이를 사용하는 대상의 특성에 따라서 적합한 개발 방법을 선정하는 것이 중요하다.

신입이든 경력이든 입사후 본인에게 주어진 업무에 대해서 이해해야한다. 나아가서 단순히 파편화되어 있는 업무만 받을 수 있는데, 전체의 흐름과 대상 고객, 비즈니스에 대해서 진지하게 이해하려고 노력해야 한다.

여기에서 가장 중요한 것은 “도메인을 이해하는 접근방식/능력/경험”은 차곡차곡 쌓여 앞으로 살며 만나게 될 다양한 도메인에 대해서 “이해하는 스스로의 방식”을 만들어 나가는 것이 중요하다는 것이다.

개발을 위한 개발을 들먹이며, 마치 개발이 업무를 이끌어가는 것 같은 늬앙스를 풍기지마라. 결국 여러분의 월급을 주는 것은 여러분이 속해 있는 비즈니스를 사용하는 고객에게 있기 때문이라는 것.

절대 개발이 고객보다 우선될 수 없음을 인지하라.

나도 어디서 들은 이야기이다.

A 회사와 B 회사에게 아래와 같은 일이 들어왔다. 100층 정도의 빌딩에서 운영되는 엘리베이터의 속도가 너무 느리다는 것이다. 그래서 엘리베이터의 속도를 20% 이상 상승시켜달라는 것의 고객의 요구사항이었다. A 회사는 이 요구사항을 아래와 같이 수행했다. 해당 빌딩의 엘리베이터의 개선을 이해서 몇억의 비용을 들여, 엘리베이터의 속도를 대폭 끌어올렸다. 하지만 사용자들의 입장에서는 크게 빨라진 것을 체감하지 못하게 되었다.

B 회사는 이 요구사항을 달리 수행했다.
해당 빌딩의 엘리베이터에 전신을 볼 수 있는 거울을 몇백만원의 비용을 들여 설치했다. 사용자들은 엘리베이터 속의 거울 속의 자신의 모습을 체크하며, 체감상으로 빨라졌다고 느꼈다.

위의 일화는 책이나 동영상에서 소개 되었던거 같은데, 이해가 가는가?

나는 위의 일화를 듣고 생각이 든 것은 고객의 니즈가 비즈니스를 위해서 구성된 개발 방식을 고수하여 확장 및 개선 시키는 것보다, 아예 개발을 하지 않을 수 있는 방법이 있다면 그게 더 나은 것이 아닌가하는 생각이었다. 외부 프로젝트나 협력 개발사들과 이야기할 때 위의 사례와 같은 경우들을 상당히 많이 봤었다. 꼭 그렇게 “개발”만을 고집하여 문제를 해결하려 하기 보다, 고객의 요구사항에 부합하며 개발을 하지 않더라도 해결할 수 있는 방법이 있다면 과감히 적용해야 한다.

그리고 그렇게 빠르게 해결이 된다면 그 “시간”을 팀내, 회사내의 개발자들에게 좀 더 좋은 아이디어/개발을 위한 시간을 할애해주는 것이 좋지 않을까 하는 생각이다.

고객에게 “시간”은 “금”이다. 그 “시간”은 개발자들에게도 매우 “소중”한 것이다.

개발자라면 내가 가지고 있는 기술을 뽐내기 보다, 우리의 도메인을 이용하는 고객을 위해서 좋은 방법을 찾는 것이 좋지 않겠는 가?

“개발”이 꼭 키보드로 쳐야만 되는 것은 아니지 않겠느냐 하는 말이다.

에러를 절대 그냥 무시하고 지나가지 마라.

내가 퇴근하려고 짐을 싸는데 한 직원이 질문을 했다. “팀장님, Spring Boot 기동 시에 에러가 나서 문제가 있는데 어떻게 해결해야 하는지 모르겠습니다.”

나의 왈 “발생하는 에러의 로그는 봤어요?”

팀원 왈 “음~ Spring Boot 기동이 안되는 거 같아서 구글링해서 스프링 부트 기동 시 체크사항을 보고 있었습니다.”

나의 왈 “IDE에 찍히는 Stack Trace Log 한번 확인해봐요”

위의 예는 그냥 하나의 예일 뿐이고, 위와 같은 상황은 숱하게 발생한다. 에러가 발생하는데 StackTrace 로그도 안보거나, 심지어 로그를 찍지않는 경우도 허다하다.

왜 에러 로그를 보지 않는가? 프로그램에서 발생하는 모든 에러는 에러가 발생하는 위치의 추적경로를 남긴다.


Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
16:48 ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [lines/connection/db/DataSourceConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1109)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
	at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:62)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
	at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140)
	at lines.comm.starter.ApplicationStarter.run(ApplicationStarter.java:153)
	at lines.LinesModularMonolithApplication.main(LinesModularMonolithApplication.java:61)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:176)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1224)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1255)
	at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:378)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792)
	... 17 common frames omitted
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
	at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100)
	at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
	... 34 common frames omitted

Process finished with exit code 1


Spring Boot를 기동할 때 위와 같은 에러가 가면 어찌해야하겠는가?

에러가 발생하는 가장 이슈가 가장 명확하게 표시되어 있는 것은 Error 로그의 제일 마지막 부분이다.

그럼 여기에서는 아래의 로그가 결국엔 에러가 발생한 원인이 될 텐데,


Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

위의 위치부터 에서 발생하는 에러를 복사해 구글링을 시작한다. 그리고 자바의 stacktrace을 아래에서 부터 위로 읽어가면서 에러가 발생한 위치에 대해서 Java Library 내의 라인도 확인해봐야한다.

개발자는 많은 에러를 발생시키고, 이를 해결하면서 성장한다. 발생한 에러의 정확한 이유를 확인하지 않고 그냥 급급하게 해결하고 또 동일한 이슈가 발생하면 경험을 통해서 해결하면 성장할 수 없다.
왜 에러가 발생했는가를 찾다보면 어떻게 프로세스가 구성되어 있고, 그 속에서 내가 잘못한 부분을 이해한다면 코드를 이해하는 능력 과 문제해결능력이 향상된다.

그렇기 때문에 반드시 발생하는 에러를 그냥 지나치지 마라.

에러가 났었는데, 다시 동작시켰더니 되더라하는 것은 개발자가 제일 피해야할 사항이다.

샘플코드를 기반으로 하여 개발을 수행하라.

샘플코드는 곧 나의 자산이다. 내가 수행하는 업무를 위해서 코드를 작성하는 방식은 반드시 샘플 코드가 우선되어 작성되어야 하고, 이를 바탕으로 업무에 코드를 적용해야 한다.

샘플 코드를 작성해서 관리하는 습관은 결국엔 나중에 동일한 이슈가 생겼을 때 이를 활용할 수 있는 기본이 된다.

하지만 가만보면, 업무 소스에 직접 코딩을 하면서 개발하는 개발자도 흔히 볼 수 있는데, 그렇게 자신이 있는지 모르겠다.

아무리 뛰어난 개발자라 할 지라도 Sequence Diagram이나 머리에 있는 로직을 한번에 풀어서 완벽하게 작성하는 개발자는 있다고 보지 않는다.

샘플 코드를 작성하는 습관을 기르자

Method 만 보더라도 해당 프로세스를 이해할 수 있게 만들어라.

우리가 작성하는 코드도 소설가들이 쓰는 글과 같이 누군가가 읽는다. 그런데 많은 코드들이 읽을 수가 없다.

아니 정확하게는 읽기가 싫어진다. 분명 코드를 작성한 사람은 이해가 갈 것이다. 하지만 그 사람도 몇 개월이 지나고 자신의 코드를 보면 이해할 수 있을지는 의문이다.

내가 말한 그런 코드는 아무것도 정리되어 있지 않다.

특히 아래의 것들이다.

  • 여백 (들여쓰기 규칙)
  • 주석
  • 명명법

내가 생각하기에 잘 작성된 코드는 함수 하나만 읽어도 이 코드가 무엇을 하는지 말해주는 코드다.

코드를 다른 사람이 읽기 쉽게 잘 짜는 것. 이건 정말 어렵다. 많은 고민과 연습, 경험이 필요하다. 하지만 이건 정말 중요하다. 본인이 소설가라고 생각한다면 아무도 이해할 수 없는 글을 쓰고 나는 정말 글을 잘쓴다라고 말할 수 있는가. 여기서 글을 잘 쓴다는 것은 코드를 어떻게 배치하고, 이름 짓는 법, 여백 등이 조화롭게 이루어져 코드를 보는 사람으로 하여금 스토리(이야기)가 보일 수 있게 해주는 것이 좋은 개발자로 갈 수 있는 비결이라고 생각한다.

이를 돕기 위해서 다양한 책들이 출간되었다. 나는 여기에서 “Clean Code”라는 책을 추천한다.

객체지향과 절차지향의 적절한 조화가 필요하다.

객체 지향의 장단점과 절차 지향의 장단점에 대해서 명확하게 이해해야 한다.

절차적인 코드의 경우에는 기존의 자료구조를 변경하지 않으면서 새 함수를 추가하기 용이하고, 반면 객체지향 코드는 기본 함수를 변경하지 않으면서 새 클래스를 추가하기 쉽다.
즉, 반대로 말하면 절차지향 코드는 새로운 자료구조를 추가하기 어렵다. 그러려면 모든 함수를 고쳐야 한다. 객체 지향 코드는 새로운 함수를 추가하기 어렵다. 그러려면 모든 클래스를 고쳐야 한다.

위의 내용이 “Clean Code”라는 책에 소개된 내용으로 나는 절차적인 코드와 객체지향적인 코드의 Trade-Off가 무엇보다 중요하다고 생각하게 되었다.

객체 지향과 절차지향의 적절한 Trade-Off 것에 있어서는 경험적인 부분도 상당히 많이 작용하고, 실제로 코드를 작성하는 과정에서 깨닫게 되는 경우도 많다.

다만, 가장 중요한 것은 특정 패러다임이 무조건 적일 수 없다는 것이고, 요구사항에 따라 변경될 수 있다는 것이다.

코딩한다고 밤새지마라.

필자도 코딩하면서 밤을 많이 샜다. 비전공자라서 기본 원리도 모르는 상태에서 개발하다보니 몰라서, 쉽게 될일도 밤새가며 코딩한 경험이 많다.
하지만 여기에서도 가장중요한 것은 코딩하면서 밤새지 말라는 것은 회사와 관련된 일에 대해서 더욱이 그렇다는 것이다. 대부분 코딩하면서 밤을 샐일은 본인이 신입 개발자인 경우에 초기 회사에 입사에서 업무를 진행하는 과정이라고 생각한다. 여기서 마감시한에 맞춰 진행되는 철야 등에 대한 부분은 아니다. ( 하지만 마감시한에 맞춰 코딩하느라 밤을 샌다면 더 문제라고 본다. ) 왜 밤을 새야하는가? 만약 입사하게 된 팀의 내부 구성 상에 자신과 같이 프로젝트를 진행할 상급자가 없이 본인 모든 것을 떠 맡아야 한다면 그건 “Doby is Free!!”를 외치며 떠나야 하는 상황이고 그게 아니라면 내가 생각하기엔 시행 착오를 최소화하기 위해서 선임자에게 물어봐야 한다.

당연히 질문의 가치에 따라서 질문의 받는 사람의 대응은 달라지겠지만, 결론적으로는 물어보지 않고 혼자 끙끙 싸멜시간에 물어보고 그 다음 스탭을 진행하는 것이 옳다고 생각한다.

여기서 이야기하지만 질문의 가치가는 것이 있다고 생각하는데, 그냥 “잘 모르겠어요”는 결국엔 아무 도움도 받을 수 없다. 하나의 업무를 수행함에 있어서 30분~1시간 정도의 시간을 가지고 분석하고, 방향을 잡고, 그에 따른 결과로 나온 질문을 들고 이야기할 수 있다면, 분명 밤샐일도 많이 줄지 않겠는가 하는게 내 생각이다. ( 다만 요새도 밤새서 코딩을 시키는 회사에 있다는 것도 또 다른 고민할 문제겠지만… )

밤새지마라. 몸이 상한다. 몸이 상하고 건강이 약해지면 정신도 약해지고, 부정적인 생각만 든다. 젊어서는 괜찮겠지? 하는 분들은 시간이 조금만 지나보면 안다.

다른 사람을 가르칠 수 있는 능력을 키워라.

다른 사람을 가르칠 수 있는 것은 무엇보다 중요하다. 다른 누군가를 가르치기 위해서는 결국 스스로 어떤 방식으로는 이해하지 못하면 가르칠 수 없다.

그 순간 교육자가 교육생보다 더 성장하게 되는 경우이다. 흔히 일러 가르치면 가르치는 사람은 2번을 배운다고 하는데, 나도 그 말에 동감하는 바다.

내가 잘 모르는 주제 일지라도 관심을 가지고 누군가에게 교육하고자 하면 그 주제에 대해서 공부하고, 이해하고자 하는데 그 순간들에 공부한 내용들이 기억속에 오래 남게 된다.

남 앞에서 자신있는 언어로 라이브 코딩은 할 수 있어야하지 않겠는가?

라이브 코딩은 개발 실력을 키울 수 있는 좋은 방법이다. 우리가 흔히 말하는 라이브 코딩이라는 것도 사전에 공부하고, 준비해서 진행하는 것이기에 그 모든 준비 과정과 실제로 라이브로 코딩한 주제에 대해서는 뇌리에 오래 남는다. 또한 누군가에게 라이브로 코딩을 하면서 보여줄 수 있다는 것도 나름의 즐거움이 될 수 있기 때문에 라이브 코딩을 할 수 있는 능력을 기르면 좋다.

너가 이해하지도 못한 부분에 대해서 남에게 시키지 마라.

내가 하기 싫은 것을 남에게 시키지 말라는 말과 일맥상통하는데, 본인 스스로 이해하지 못하고, 잘 모르는 부분에 대해서 다른 사람에게 절대 시키지마라. 흔히 이와 같은 이슈는 시니어 개발자와 주니어 개발자 사이에서 발생할 수 있는데, 말만 번지르르하게 하고, 자신도 잘 모르는 것을 해보라고 시키는 개발자가 본인의 상급자라면 탈주를 생각해보라. 말은 쉽다. “해보지도 않고 어떻게 아냐”는 말이 나는 정말 싫다. 시니어 개발자로서 주니어 개발자들을 이끌어 가는 사람이라면 적절한 방향성과 가이드를 제공해야한다. 당연히 새로운 것을 배우고, 익혀나가야 하지만 회사 내의 업무와 연관된 개발 과제 및 기술 적용 사항은 사전의 시행착오를 줄여주는 것이 중요하다.

배움에 있어서는 위 아래가 있어서는 안된다.

내가 모르는 것을 신입 직원이 안다면 상하고하와 상관 없이 같이 배우고 이해하려 해야한다. 본인이 이해하지 못한다고 해서 “비난”을 하는 사람이 있는데, “비난” 과 “비평”의 차이는 스스로의 이해도에서 나온다. 본인이 잘몰라서 그냥 “비난”만 하고 보는 사람들이 있다. 그러지 말자. 우리가 어떻게 모든 것을 다알 수 있는가, 시간이 지나면 당연히 모르는 것도 많이 생긴다. 스스로 이를 받아들이고, 배우려는 겸손한 자세를 직급에 상관 없이 취한다면 좋은 결과가 있을 것이라고 생각한다.

개발한 자료들은 반드시 보관한다.

본인이 회사업무를 하면서 공부하거나, 찾은 자료에 대해서 그냥 그 순간에만 쓰고 지워버리면 아무런 도움이 되지 않는다. 매일매일 개발하는 항목에 대해서 이력을 관리해야하고, 업무에 적용하거나 토이 프로젝트를 만들면서 생성된 프로젝트는 샘플로 체계적으로 관리하자.

해당 자료들은 언젠가 반드시 힘이된다.

Tags:

Categories:

Updated: