묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 핵심 원리 - 기본편
Primary 와 Qualifier
안녕하세요.다름이 아니라 스프링 기본편 수업을 듣고, 혼자 해보다가 궁금증이 생겨서 글을 씁니다.Primary 어노테이션을 적용하면 스프링 컨테이너에서 확인 하고 저 어노테이션이 붙은걸로 의존관계 자동 주입을 해준다는 것은 이해했습니다.자주 사용한다고 말씀 해주셔서 혼자 만들어보면서 문제 없이 사용했습니다.Qualifier같은 경우는 따로 MainDiscountPolicy를 만들어서 사용할 RateDiscountPolicy 나 FixDiscountPolicy 상단에 Qualifier를 붙여 사용한다는 것도 이해를 했는데요.최종적으로 생성자 자동주입을 사용할 땐 @RequiredArgsConstructor 를 사용하게 되면서 코드를 간소화 하기에 primary를 사용할 거 같은데 만약 qualifier를 사용하게 될 상황이 온다면@RequiredArgsConstructor 이 부분을 삭제하고 다시 생성자를 만들면서 적용을 시켜야 하는 건가요?제가 설명을 잘 못하는 거 같아서 사진도 덧붙입니다...이 상황에서 orderserviceImpl 상단에 @RequiredArgsConstructor를 제거 하고, 다시 생성자를 만들어 @Autowired를 붙여줘 @MainDiscountPolicy 사용했습니다.근데 실무에서도 이것도 사용한다고 말씀하셨는데, 그러면 테스트 코드를 작성해서 할 때마다 @RequiredArgsConstructor를 제거 하고 다시 이렇게 만들어줘서 돌리는지 궁금합니다. primary로 써도 손 쉬운데 뭔가 번거로운 거 같은데 사용하나 해서 질문 올립니다. 감사합니다
-
미해결홍정모의 따라하며 배우는 C++
27분 05초 부근 질문있습니다.
divide & conquer 전략으로 lockguard를 쓰는 thread, atomic 쓰는 thread, promise 쓰는 thread 이렇게 만드는 건데 애초에 divide & conquer 전략이 무엇인지도 잘 모르겠고 코드를 배운대로 짠 거 같은데 자꾸 오류가 나서 막막합니다. 도움을 조금 주시면 감사하겠습니다. 밑에는 제가 짠 코드입니다.// 여태까지 멀티 스레딩을 사용하는 여러가지 문법들을 배워봤다. // 이번에는 멀티 스레딩으로 벡터 내적을 계산하는 예제를 통해서 실제 문법이 어떻게 사용이 되는 지 그리고 차이가 어떻게 나는 지 등등을 한 번 직접 실험하면서 살펴본다. #include <iostream> #include <chrono> #include <mutex> #include <random> #include <thread> #include <utility> #include <vector> #include <atomic> #include <future> #include <numeric> // std::inner_product #include <execution> // parallel execution using namespace std; mutex mtx; // mutex를 꼭 전역 변수로 선언할 필요는 없다. 여러 개의 스레드가 공통적으로 접근할 수 있는 scope에 있으면 된다. // 그리고 mutex도 항상 존재할 필요는 없다. mutex로 lockguard를 만들어주고 싶은 부분이 작동할 때만 mutex가 살아있으면 된다. // 그러니깐 코딩할 때 mutex를 어떤 클래스의 멤버로 집어넣어도 되고 scope에 넣어도 된다. void dotProductNaive(const vector<int>& v0, const vector<int>& v1, const unsigned i_start, const unsigned i_end, unsigned long long& sum) { for (unsigned i = i_start; i < i_end; ++i) sum += v0[i] * v1[i]; } void dotProductLock(const vector<int>& v0, const vector<int>& v1, const unsigned i_start, const unsigned i_end, unsigned long long& sum) { //std::scoped_lock lock(mtx); // 속도를 높이기 위해 scoped_lock을 for문 밖으로 옮기면 어떨까라고 생각할 수 있다. // scoped_lock이 작동하는 범위를 scope 전체가 되도록 옮기니깐 속도가 오히려 훨씬 빨라졌다. // 그러면 오히려 밖으로 빼면 되나 생각할 수 있는데 지금 cout으로 출력된 값을 보니깐 start, end, start, end, ... 이렇게 나왔다. // 이 전체가 lock이기 때문에 병렬이 아니라, 동시적으로 실행이 된 게 아니라 순차적으로 실행이 됐다는 의미이다. // 실제로 이런 방식으로 병렬처리를 하는 것은 의미가 없다는 거다. // 오히려 스레드를 생성하는 오버헤드만 커지게 된다. cout << "Thread start " << endl; for (unsigned i = i_start; i < i_end; ++i) { std::scoped_lock lock(mtx); // C++ 17 // 초반에 말했었지만 scoped_lock은 영역이 작은 쪽에 들어가는게 좋은데 작은 영역에 들어오긴 했지만 너무 빈번하게 자주 실행이 되어버리면 오히려 느려진다. // 멀티 스레딩을 안 하느니만 못하는 최악의 결과가 나오게 된다. 그래서 멀티 스레딩을 처음 시도를 하는 경우에는 오히려 퍼포먼스가 떨어지거나 혹은 퍼포먼스는 안 떨어지는 대신에 결과가 나쁘거나 이런 식으로 작동이 될 수 있다. // 그런데 이것도 경우에 따라서 또 다르다. 락이 걸린 scope 전후로 어마어마하게 일이 많으면 상대적으로 멀티 스레딩의 효율이 높아지기도 하는데 일단은 극단적인 경우를 가지고 실수를 할 수 있는 부분에 대해서 먼저 설명을 했다. sum += v0[i] * v1[i]; } cout << "Thread end " << endl; } void dotProductAtomic(const vector<int>& v0, const vector<int>& v1, const unsigned i_start, const unsigned i_end, atomic<unsigned long long>& sum) { for (unsigned i = i_start; i < i_end; ++i) { sum += v0[i] * v1[i]; // atomic 연산이 일반연산보다 느리기 때문에 빈번하게 호출되는 곳에 atomic 연산을 넣어버리면 느려진다. } } auto dotProductFuture(const vector<int>& v0, const vector<int>& v1, const unsigned i_start, const unsigned i_end) { int sum = 0; // local sum for (unsigned i = i_start; i < i_end; ++i) { sum += v0[i] * v1[i]; } return sum; } int main() { /* v0 = { 1, 2, 3 } v1 = { 4, 5, 6 } v0_dot_v1 = 1*4 + 2*5 + 3*6; */ const long long n_data = 100'000'000; const unsigned n_threads = 4; /* initialize vectors */ std::vector<int> v0, v1; v0.reserve(n_data); v1.reserve(n_data); // reserve()로 push할 때의 효율을 높였다. random_device seed; mt19937 engine(seed()); uniform_int_distribution<> uniformDist(1, 10); for (long long i = 0; i < n_data; ++i) { v0.push_back(uniformDist(engine)); v1.push_back(uniformDist(engine)); } cout << "std::inner_product" << endl; { const auto sta = chrono::steady_clock::now(); const auto sum = std::inner_product(v0.begin(), v0.end(), v1.begin(), 0ull); // auto인데도 unsigned long long으로 자동 추론을 할 수 있게 된 이유는 0을 0ull으로 표기를 해서 넣어줬기 때문이다. const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } // 멀티 스레딩 프로그래밍을 한다면 정답을 계산을 하고 그것과 정답이 맞는지 비교하고 그리고 퍼포먼스를 또 비교하는 방식으로 작업을 하는 것이 좋다. cout << "Naive" << endl; { const auto sta = chrono::steady_clock::now(); unsigned long long sum = 0; vector<thread> threads; threads.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; // assumes remainder = 0 for (unsigned t = 0; t < n_threads; ++t) threads[t] = std::thread(dotProductNaive, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread, std::ref(sum)); for (unsigned t = 0; t < n_threads; ++t) threads[t].join(); const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } // 스레드 개수를 임의의 개수로 사용할 수 있게 하기 위해서 조금 코드가 복잡해졌다. // 실행해보면 시간도 더 걸렸고 무엇보다 답이 틀리게 나온다. 레이스 컨디션 때문에 그렇다. // sum에다가 값을 더하고 있는데 여러 개의 스레드가 동시에 값을 건드리니깐 문제가 생겨서 값이 제대로 더해지지 않고 있다. cout << "Lockguard" << endl; { const auto sta = chrono::steady_clock::now(); unsigned long long sum = 0; vector<thread> threads; threads.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; // assumes remainder = 0 for (unsigned t = 0; t < n_threads; ++t) threads[t] = std::thread(dotProductLock, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread, std::ref(sum)); for (unsigned t = 0; t < n_threads; ++t) threads[t].join(); const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } cout << "Atomic" << endl; { const auto sta = chrono::steady_clock::now(); atomic<unsigned long long> sum = 0; vector<thread> threads; threads.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; // assumes remainder = 0 for (unsigned t = 0; t < n_threads; ++t) threads[t] = std::thread(dotProductAtomic, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread, std::ref(sum)); for (unsigned t = 0; t < n_threads; ++t) threads[t].join(); const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } cout << "Future" << endl; { const auto sta = chrono::steady_clock::now(); unsigned long long sum = 0; vector<std::future<int>> futures; // unsigned long long으로 받지 않은 이유는 부분의 합은 integer 범위 안에 들어오기 때문이다. futures.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; // assumes remainder = 0 for (unsigned t = 0; t < n_threads; ++t) futures[t] = std::async(dotProductFuture, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread); // 전역 변수 역할을 하는 sum이 들어갈 필요가 없다. 왜냐하면 dotProductFuture()에서는 local sum을 계산해서 return 해주고 있기 때문이다. for (unsigned t = 0; t < n_threads; ++t) sum += futures[t].get(); // .join()을 하는 대신에 .get()을 받아서 sum에다가 더해주고 있다. const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } // future 쓰는게 무조건 좋구나 thread 나빠 이렇게 생각할 수도 있다. 그런데 꼭 그렇진 않다. //TODO: use divide and conquer strategy for std::thread, std::thread & std::atomic //TODO: use divide and conquer strategy for std::thread & std::promise /* divide and conquer strategy for lockguard */ cout << "Divide Lockguard" << endl; { const auto sta = chrono::steady_clock::now(); vector<unsigned long long> divide_sum; divide_sum.resize(n_threads); vector<thread> threads; threads.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; // assumes remainder = 0 for (unsigned t = 0; t < n_threads; ++t) threads[t] = std::thread(dotProductLock, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread, std::ref(divide_sum[t])); for (unsigned t = 0; t < n_threads; ++t) threads[t].join(); unsigned long long sum = 0; for (unsigned t = 0; t < n_threads; ++t) sum += divide_sum[t]; const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } /* divide and conquer strategy for atomic */ cout << "Divide Atomic" << endl; { const auto sta = chrono::steady_clock::now(); vector<atomic<unsigned long long>> divide_sum; divide_sum.resize(n_threads); vector<thread> threads; threads.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; // assumes remainder = 0 for (unsigned t = 0; t < n_threads; ++t) threads[t] = std::thread(dotProductAtomic, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread, std::ref(divide_sum[t])); for (unsigned t = 0; t < n_threads; ++t) threads[t].join(); unsigned long long sum = 0; for (unsigned t = 0; t < n_threads; ++t) sum += divide_sum[t]; const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } /* divide and conquer strategy for promise */ cout << "Promise" << endl; { const auto sta = chrono::steady_clock::now(); unsigned long long sum = 0; vector<std::promise<int>> proms; proms.resize(n_threads); vector<std::future<int>> futures; futures.resize(n_threads); vector<thread> threads; threads.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; // assumes remainder = 0 for (unsigned t = 0; t < n_threads; ++t) { futures[t] = proms[t].get_future(); threads[t] = std::thread([&](std::promise<int>&& prom) { prom.set_value(dotProductFuture(std::ref(v0), std::ref(v1), t* n_per_thread, (t + 1)* n_per_thread)); }, std::move(proms[t])); } for (unsigned t = 0; t < n_threads; ++t) sum += futures[t].get(); for (unsigned t = 0; t < n_threads; ++t) threads[t].join(); const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } cout << "std::transform_reduce" << endl; { const auto sta = chrono::steady_clock::now(); //const auto sum = std::transform_reduce(std::execution::seq, v0.begin(), v0.end(), v1.begin(), 0ull); const auto sum = std::transform_reduce(std::execution::par, v0.begin(), v0.end(), v1.begin(), 0ull); const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } // std::inner_product의 병렬 버전이 std::transform_reduce()이다. std::transform_reduce() 말고도 std::sort() 같은 함수들이 전부 병렬 처리를 지원해준다. 그래서 기본적인 것들을 빠르게 구현할 때는 병렬 처리를 직접 구현할 필요는 없다. // 하지만 병렬 처리 함수들을 사용하기에 앞서 멀티 스레딩을 먼저 조금 알고 있으면 사용할 때 조금 더 유리할 거고 둘째로 std에서 만들어준 코드들이 모든 문제들을 전부 병렬 처리 해주지는 않는다. 그리고 여전히 병렬 처리했을 때 문제가 생길 여지가 분명히 존재한다. return 0; }
-
미해결파이썬 알고리즘 문제풀이 입문(코딩테스트 대비)
코드 질문있습니다!
안녕하세요! 제 코드 오류 해결을 못해서 강의까지 듣고 이해했습니다. 선생님께서 하신 코드는 이해했는데 하지만 제가 짠 코드가 왜 틀리는지 잘 이해가 안 가서 질문드립니다! N, M = map(int,input().split()) List = list(map(int,input().split())) cnt = 0 x_cnt = 0 while(cnt < N ): Sum = 0 for i in range(cnt,N): Sum += List[i] # index 오류! if Sum == M : x_cnt += 1 break elif Sum > M : break cnt += 1 print(x_cnt)in 1, 2 ,3 까지는 맞지만 4, 5에서 값이 커지면sum += List[ i ] 부분에서 IndexError: list index out of range 나옵니다.왜 인덱스 범위가 벗어나는지 이유를 모르겠습니당.. 선생님 방금 추가로 얻은 정보인데요! 제가 선생님과 비슷한 방식으로 풀었다가 그것도 똑같이 인덱스 범위 오류가 나서 아예 선생님 코드를 복붙을 했는데도 인덱스 범위 오류가 나는 거에요!!이거는 제 파이썬 버전이나 컴퓨터 설정에서 문제가 있는 걸까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
초기설정 오류 질문
현재 노드 버전이 올라가서 노드도 16.17로 내리고나머지도 다 버전 내려서 버전에 맞게 설정하고yarn add next@12.1.0 react@17.0.2 react-dom@17.0.2 --exact까지 했는데 노션에 있는 것 처럼 페이지와 api 여러 등등이 뜨지 않습니다뭐가 문제일까요?ㅠㅠ
-
해결됨화이트해커가 되기 위한 8가지 웹 해킹 기술
버프 스위트 오류
fire fox에 burp suite로 네트워크 설정을 했는데 그냥 fire fox에서 하면 burp suite에 아무것도 안 떠요. 사실 원래도 버프 스위트에서 오픈 브라우저를 하면 샌드박스가 없다고 실행이 안돼서 샌드박스 없이 하는 설정을 켜서 했거든요? 혹시 이것 때문에 그런가요? 만약 그러면 샌드박스 설치하는 법도 알려주세요.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
버전이나 리뉴얼 관련해서..
작년에 사뒀는데 들으려고 보니 버전 차이가 조금 있더라고요그대로 들어도 무리가 없을지, 아니면 리뉴얼 예정이 있는지 궁금합니다 +) 타임어택 3기 예정도 궁금합니다!
-
미해결처음 배우는 리액트 네이티브
안드로이드스튜디오 EXPO 어플 튕깁니다 ㅠㅠ
IOS환경에서는 잘 작동하는데 안드로이드스튜디오로 어플을 작동할 시 잠깐 화면이 나오고 바로 튕겨버립니다.. ㅠㅠ
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
안녕하세요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]pathvariable 을 쓰는 경우와 requestparam 을 쓰는 경우가 나뉘어져 있나요? 아니면 둘의 역할이 달라 다르게 쓰는 건가요?
-
미해결자바스크립트 알고리즘 문제풀이 입문(코딩테스트 대비)
코드 리뷰 부탁드립니다!
function solution(m, product) { let count = 0; let sumResult = []; for (let i = 0; i < product.length; i++) { product[i][0] /= 2; let sum = 0; let priceSum = [...product].map((price) => price[0] + price[1]); priceSum.sort((a, b) => a - b); for (let j = 0; j < priceSum.length; j++) { sum += priceSum[j]; count++; if (sum > m) { sumResult.push(j); break; } } product[i][0] *= 2; } return Math.max(...sumResult); }4-4 졸업선물 풀어보았는데요강사님과 너무 다르게 풀어서 시간복잡도 면에서 자신이 없네요ㅜ
-
미해결실전! 스프링 데이터 JPA
JPA페이징 공부를 하다가 궁금한점이 있습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]JPA를 이용한 페이징 처리를 공부하다가 문득 궁금한점이 생겼습니다. Page 및 Slice, Sort의 처리와 더불어 Repository의 기능을 통해서 값을 처리하는것을 배웠는데요.그런데 만약 2개 이상의 테이블을 Join한 상태라면 페이징 처리를 어떤 방법으로 하는지 궁금합니다.예를들어 Page<Member, Order> 이런식으로는 어렵고, 1개의 Repository 안에 직접적인 조인쿼리 방식으로 값을 불러와서 적용해야 할까요?아니면 MappingTable을 이용하거나 Member와 Order라는 조인쿼리에서 실질적으로 보여주는 필드값들만 DTO형태로 만들어서 Page<MemberViewDTO> 이런식으로 적용해야되는것일까요?!아니면 이럴때 적용하는것이 QueryDSL이라는것인지 궁금합니다.(아직 QueryDSL을 배우진 않았고, 들어만 봤습니다.) 2개의 테이블에서 뽑아낸 DB값들을 Page 처리하기위해선 어떠한 방식으로 할 수 있는지 궁금합니다.
-
미해결카프카 완벽 가이드 - 코어편
카프카 서버기동에서 질문있습니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 강사님 카프카 서버기동에서 주키퍼와 카프카를 실행한후에 주키퍼부터 내릴경우 카프카 실행이 안되는 이유가 궁금합니다.
-
미해결일주일 완성! 3dsmax 입문 (자동차 및 캐릭터 만들기)
자동차만들기(12) 11:51 단축키 질문
복사해서 오브젝트로 떼어내는거 단축키 어떤걸 사용하셧나요? 저는 알트누르고 드래그하면 모양만 늘어나는데 단축키설정하신걸까요?
-
해결됨10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
컴파일 오류
어떻게 해야할지 모르겠어요 ㅠ 주석 제외 완전 똑같이 적었습니다
-
미해결일주일 완성! 3dsmax 입문 (자동차 및 캐릭터 만들기)
detach 사용하고나서 다시 한 오브젝트로 붙일떄
버텍스가 한 위치에 두개씩생겨서 접합이 안되있는것은 weld말고는 detach하기전 상태처럼 붙이는 방법이 없나요?
-
미해결[파이토치] 실전 인공지능으로 이어지는 딥러닝 - 기초부터 논문 구현까지
데이터 불러오기 강의에서 cd
강의에 나온 코드cd/content/gdrive/My Drive/deeplearningbro/pytorch를 하면 오류가 뜨는데 cd 로 경로 변경이 안되나요??NameError: name 'cd' is not defined 가 뜹니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
post 로 id, password 전송시 => 크롬 개발자 도구, 네트워크, Request 에 보면 id, password 가 그대로 노출되는데 숨길순 없나요?
post 로 id, password 전송시 => 크롬 개발자 도구, 네트워크, Request 에 보면 id, password 가 그대로 노출되는데 숨길순 없나요?브라우저를 사용하는 유저가 보낸 거기 때문에 보안을 안해도 상관없을까요?
-
미해결CS 지식의 정석 | 디자인패턴 네트워크 운영체제 데이터베이스 자료구조
[오탈자 문의]
안녕하세요 큰돌님! 교재 p.224 페이지교체 알고리즘 NUR 설명에 ~ 0을 찾고 0을 찾은 순간 해당 프로세스로 교체하고라고 되어있는데, 해당 프로세스가 아니라 해당 페이지가 아닌가 해서 질문 남깁니다. 강의 너무 잘 보고 있습니다. 감사합니다~
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
redux createStore deprecated....
안녕하세요 강사님 현재 리덕스 공부중에 있습니다.createStore를 쓰려고 했더니 deprecated 메시지가 뜨면서 reactjs/toolkit 패키지의 configureStore 메서드를 쓰라고 합니다. 이렇게 공부한 함수가 deprecated 되거나 잘 쓰지 않는 함수 일때는 그래도 redux를 이해하는데 기본이 되는 함수이니 계속 공부를 해야 되나요? 아니면 새로운 메소드를 공부해 보는 편이 좋나요??
-
해결됨나도코딩의 자바 기본편 - 풀코스 (20시간)
eclipse
안녕하세요. 맛보기 강의를 듣고 수강권을 구매하여 제대로 학습해 보려는 학생입니다.강의를 보니 인텔리제이로 수업이 이루어지던데 이클립스만으로도 어려움 없이 학습할 수 있을까요?? 원래 이클립스를 사용했다 보니 큰 차이가 없다면 이클립스로 공부하고 싶어서요...!
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
gradlew build 실패
gradlew build시 위와같이 fail이 뜨고 dir봤을땐 build가 없는데 어떻게 해야하나요?