묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
useRef를 사용하는 이유
todo list 구현 중 id 값을 변경할 때 useState가 아닌 useRef를 사용하는 이유가 무엇인가요? useRef를 사용하는 이유와 사용되는 경우를 아직 이해하지 못해 조금 더 자세하게 알려주시면 감사하겠습니다ㅠ
-
미해결모두를 위한 대규모 언어 모델 LLM(Large Language Model) Part 1 - Llama 2 Fine-Tuning 해보기
trainer.train() 실행했는데 API key를 입력하라고 합니다. ㅠ
trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_bionlp["train"], eval_dataset=tokenized_bionlp["validation"], tokenizer=tokenizer, data_collator=data_collator, compute_metrics=compute_metrics, ) trainer.train() 강의에서는 training 하면 바로 된다고 하셨는데, 2025년 8월 현재 입력하면 wandb: Logging into wandb.ai. (Learn how to deploy a W&B server locally: https://wandb.me/wandb-server) wandb: You can find your API key in your browser here: https://wandb.ai/authorize?ref=models wandb: Paste an API key from your profile and hit enter: 위와 같이 나옵니다. 어떻게 하면 될까요?
-
미해결자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide)
플랫폼 타입 설명 문의
안녕하세요. 플랫폼 타입 설명 중에서 라이브러리를 가져다 쓴 지점을 래핑해서 단일 지점으로 만듦으로써 이슈를 쉽게 대응한다는 게 어떤 말씀이신지 잘 이해나 상황이 그려지지 않아서.. 이게 어떤건지 예시를 통해 알려주실 수 있는지 궁금해서 질문을 남깁니다. '래핑해서 단일 지점으로 만든다'라는 개념과, 이렇게 만들면 이슈를 어떻게 왜 쉽게 대응할 수 있다는건지 이런 부분을 잘 모르겠습니다 ㅠㅠ
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
회원가입 테스트 중 빈값 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 현재 강의 8분쯤, 회원가입 테스트 할때 "이미 존재하는 회원입니다"를 방지 하기 위해 delete from member; 이후에 정상 작동 되어야 하는데, 오류가 나는 상황입니다. 회원가입 테스트 함수 내에,join 함수 실행 후에, findOne(saveId) 에서 빈값으로 확인됩니다.saveId 의 경우엔 테스트 할때마다 시퀀스가 올라서 11, 12, ... 가 확인됩니다. select * from member; 시에 빈값이고,join(member)가 정상으로 됬기 떄문에 saveId값이 오르고 있는것 같은데,findOne에서 빈값이라고 하니 get()할 값이 없어서 오류가 나는것 같은데,진도를 나가기 위해 어떻게 수정해야 할까요 ? join이 정상실행 됬다는 확인은 해당 소스 위 아래 sout "1" "2" 를 각각 붙였더니 정상 실행 되었고,findOne 위에 sout("3")까지 출력 됬지만, findOne 아래 sout("4")은 출력되지 않고 오류가 떴습니다. 그리고 오류를 찾아가기 위해, 확인하고 싶은 현 시점에 소스 상황입니다.MemberServcie 클래스에서 @Service 와빈 주입을 위한 @Autowired 는 주석처리가 되어 있는데 맞을까요 ? 12분 짜리 강의를 위해 3시간째 ㅠㅠ 버벅이고 있습니다. 도와주세요 ㅠㅠ혹시 제 질문이 부족했다면, 제가 답을 얻기위해 추가 질문이라도 부탁드립니다 ㅠㅠ
-
미해결비전공자 혼자서 하루 만에 수익화 앱 출시하기
개발 MAC 사양 및 추천 관련 질문입니다
이번에 맥을 새로 구매하려고 합니다.개발하실 때 사용한 맥 사양과 사용 경험(불편한 점은 없으셨는지)과혹시 지금 구매한다면 추천해주실 MAC 은 어느 정도 사양인지 궁금합니다
-
미해결팀 개발을 위한 Git, GitHub 입문
강의자료 부탁드립니다
yumin020293@gmail.com 강의자료 부탁드립니다
-
미해결김영한의 실전 자바 - 중급 2편
특정 index의 노드 조회하기 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]1. 특정 index의 노드 조회하기에서 index의 값을 0이나 1로 설정하고 실행시키면0으로 설정시: index0Node = [A->B->C]1으로 설정시: index1Node = [B->C]이런식으로 출력이 되는데 저희가 의도한 출력은 특정 index의 값이므로 index가 0이면 [A], index가 1이면 [B] 와 같이 출력이 되어야 맞는게 아닌가해서 질문드립니다! 메서드를 구현할 때 영한님께서는 Node x = node; 이런식으로 변수에 받아서 구현을 하시는데 제 생각에는 x라는 변수가 굳이 필요 없을 것 같아 아래 코드와 같이 작성해보았는데 잘 작동하였습니다. 변수 x에 담아서 메서드를 처리하는 의도가 따로 있는건지 궁금합니다! 감사합니다private static Node getNode(Node node, int index) { for (int i = 0; i < index; i++) { node = node.next; } return node; }
-
미해결리눅스 커널 해킹. A부터 Z까지
cred 구조체에 __randomize_layout이 적용된건가요?
cred 구조체 소스코드를 elixir를 통해 확인해보니 다음과 같았습니다. (실습 버전인 5.8.5 기준)struct cred { atomic_t usage; #ifdef CONFIG_DEBUG_CREDENTIALS atomic_t subscribers; /* number of processes subscribed */ void *put_addr; unsigned magic; #define CRED_MAGIC 0x43736564 #define CRED_MAGIC_DEAD 0x44656144 #endif kuid_t uid; /* real UID of the task */ kgid_t gid; /* real GID of the task */ kuid_t suid; /* saved UID of the task */ kgid_t sgid; /* saved GID of the task */ kuid_t euid; /* effective UID of the task */ kgid_t egid; /* effective GID of the task */ kuid_t fsuid; /* UID for VFS ops */ kgid_t fsgid; /* GID for VFS ops */ unsigned securebits; /* SUID-less security management */ kernel_cap_t cap_inheritable; /* caps our children can inherit */ kernel_cap_t cap_permitted; /* caps we're permitted */ kernel_cap_t cap_effective; /* caps we can actually use */ kernel_cap_t cap_bset; /* capability bounding set */ kernel_cap_t cap_ambient; /* Ambient capability set */ #ifdef CONFIG_KEYS unsigned char jit_keyring; /* default keyring to attach requested * keys to */ struct key *session_keyring; /* keyring inherited over fork */ struct key *process_keyring; /* keyring private to this process */ struct key *thread_keyring; /* keyring private to this thread */ struct key *request_key_auth; /* assumed request_key authority */ #endif #ifdef CONFIG_SECURITY void *security; /* subjective LSM security */ #endif struct user_struct *user; /* real user ID subscription */ struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ struct group_info *group_info; /* supplementary groups for euid/fsgid */ /* RCU deletion */ union { int non_rcu; /* Can we skip RCU deletion? */ struct rcu_head rcu; /* RCU deletion hook */ }; } __randomize_layout;이 중 마지막 __randomize_layout 이 뭔지 찾아보니 커널에서 정의한 매크로이고 구조체의 순서를 랜덤화하는 일종의 보호 기법이라는 것을 알았습니다. 실습을 따라가보니 uid, gid, suid, sgid를 순서대로 덮기 때문에 현재 커널에서 이 보호 기법이 적용되지 않았다는 것을 알 수 있었습니다. 이 매크로의 정의 부분은 총 두 부분이고 다음과 같았습니다.#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__) #define __randomize_layout __attribute__((randomize_layout)) #define __no_randomize_layout __attribute__((no_randomize_layout)) /* This anon struct can add padding, so only enable it under randstruct. */ #define randomized_struct_fields_start struct { #define randomized_struct_fields_end } __randomize_layout; #endif #ifndef __randomize_layout # define __randomize_layout __designated_init #endif첫 번째 부분에서는 flag처럼 보이는 RANDSTRUCT_PLUGIN 과 __CHECKER__ 에 cross reference(?)가 더이상 안돼서 확인은 못했습니다만, 이게 define 되어있으면 __randomize_layout 매크로를 정의하는 것 같아보입니다. 반대로 flag가 켜져있지 않아 첫 번째 부분에서 매크로 선언이 이뤄지지 않으면 두 번째 부분에서 __designated_init 으로 어쨌든 선언은 되는 것 같습니다. 마지막으로 __designated_init 의 선언 부분을 보면 다음과 같습니다.#if __has_attribute(__designated_init__) # define __designated_init __attribute__((__designated_init__)) #else # define __designated_init #endif첨부는 했지만 어떻게 동작하는건지 잘 모르겠어서 여기부터 이해가 안됐습니다... 제 질문은 다음과 같습니다. 구조체 멤버 랜덤화가 적용되어야 할 것 같은데 강의자님께서 일부러 커널을 빌드할 때 소스코드를 수정하신건가요?아니라면 __designated_init__ 이 없기 때문에 빈 매크로가 할당된 것 같은데, 이게 어떤 플래그이며 어떻게 키고 끌 수 있는건가요?커널 소스코드를 확인할 때 RANDSTRUCT_PLUGIN 과 __CHECKER__ 같이 더 이상 cross reference가 불가능한 경우는 어떻게 값을 확인할 수 있나요?정작 __randoimze_layout 이 붙었을 때 어떻게 메모리 레이아웃을 변경하는지에 대한 로직은 못찾았는데, 이런 부분은 어디서 확인할 수 있을까요?강의자님 경험상 대회나 리얼월드 커널에서 구조체 멤버 랜덤화가 잘 적용되어있는 편인가요? 질문이 길어졌는데, 답변주시면 큰 도움이 될 것 같습니다. 감사합니다.
-
미해결웹 개발의 핵심, HTTP 완벽 마스터하기!
rest api 에서의 csrf
예제에서 처럼 html 을 response 하지 않고 rest api 를 통해 fe 와 통신하는 경우에도 csrf 를 사용하는 경우가 있을까요? 만약 있다면 어떻게 사용하는지도 알고 싶습니다.
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
Gradle Build 시 에러 발생
1. 현재 학습 진도몇 챕터/몇 강을 수강 중이신가요?2-7강 여기까지 이해하신 내용은 무엇인가요?git Action CI/CD 2. 어려움을 겪는 부분어느 부분에서 막히셨나요?git push 후 workflow에서 Gradle 빌드 실패코드의 어떤 로직이 이해가 안 되시나요?어떤 개념이 헷갈리시나요? 3. 시도해보신 내용문제 해결을 위해 어떤 시도를 해보셨나요?에러가 발생했다면 어떤 에러인가요?git push 후 workflow에서 Gradle 빌드 실패현재 작성하신 코드를 공유해주세요 빌드를 진행할 때 먼저 3개의 테스트에서 실패합니다.SimpleEventListenerTest > 현재 코드 구조에서 @TransactionalEventListener는 작동하지 않는다 FAILED java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143 Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1770 Caused by: jakarta.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421 Caused by: org.hibernate.exception.JDBCConnectionException at SQLExceptionTypeDelegate.java:49 Caused by: java.sql.SQLNonTransientConnectionException at SQLError.java:111 SimpleEventListenerTest > @TransactionalEventListener는 활성 트랜잭션이 필요하다 FAILED java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143 Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1770 Caused by: jakarta.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421 Caused by: org.hibernate.exception.JDBCConnectionException at SQLExceptionTypeDelegate.java:49 Caused by: java.sql.SQLNonTransientConnectionException at SQLError.java:111 SimpleEventListenerTest > @EventListener는 트랜잭션이 없어도 정상 동작한다 FAILED java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143 Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1770 Caused by: jakarta.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421 Caused by: org.hibernate.exception.JDBCConnectionException at SQLExceptionTypeDelegate.java:49 Caused by: java.sql.SQLNonTransientConnectionException at SQLError.java:111이후, Redis에 Reconnecting 하려고 시도하지만 Connection이 Refused되면서 빌드에 실패합니다.2025-08-21T08:34:32.560Z INFO 2235 --- [xecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/127.0.0.1:32770 2025-08-21T08:34:32.570Z WARN 2235 --- [ioEventLoop-8-2] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/<unresolved>:32770]: Connection closed prematurely io.lettuce.core.RedisConnectionException: Connection closed prematurely at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:91) ~[lettuce-core-6.2.6.RELEASE.jar:6.2.6.RELEASE] // 생략로컬 환경과 AWS EC2 환경에서 동일하게 발생합니다. 해결 방법gradle build를 5번 정도 시도했는데, 5번 중 4번은 SimpleEventListenerTest에서 테스트가 실패하고, 1번은 다른 Test에서 실패하였습니다.그래서, SimpleEventListenerTest에 대해 개별 테스트를 진행해보니 통과하였습니다.전체 테스트 진행에서는 JDBC Connection 관련 오류가 발생했고, 개별 테스트 진행에서는 문제가 발생하지 않는다는 점에서 커넥션 풀 설정 문제를 의심하였습니다. spring: datasource: url: jdbc:mysql://${RDS_ENDPOINT:localhost}:3306/portfolio?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&useSSL=false&rewriteBatchedStatements=true username: portfolio_user password: ${RDS_PASSWORD:portfolio1234} driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 32@TestConfiguration public class TestDatabaseConfig { @Container private static final MySQLContainer<?> mysqlContainer;application.yml 의 최대 풀 사이즈는 32로 설정되어 있고, mySQL 컨테이너는 전역으로 설정되어 있으므로 병렬 처리 과정에서 커넥션 풀이 부족할 수 있겠다는 판단하에, maximum-pool-size를 100으로 늘려보았습니다.package ding.co.backendportfolio.config; import jakarta.annotation.PreDestroy; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.testcontainers.containers.MySQLContainer; import org.testcontainers.junit.jupiter.Container; @TestConfiguration public class TestDatabaseConfig { @Container private static final MySQLContainer<?> mysqlContainer; static { mysqlContainer = new MySQLContainer<>("mysql:8.0.33") .withDatabaseName("testdb") .withUsername("test") .withPassword("test"); mysqlContainer.start(); // A) 기본 설정 + rewriteBatchedStatements 옵션 String originalJdbcUrl = mysqlContainer.getJdbcUrl() + "?rewriteBatchedStatements=true"; // TODO: BulkInsert 모니터링 - 아래 주석을 해제해야함 // originalJdbcUrl = originalJdbcUrl + "&profileSQL=true&logger=Slf4JLogger&maxQuerySizeToLog=2147483647"; System.setProperty("spring.datasource.url", originalJdbcUrl); System.setProperty("spring.datasource.username", mysqlContainer.getUsername()); System.setProperty("spring.datasource.password", mysqlContainer.getPassword()); // 커넥션 풀 늘리기 System.setProperty("spring.datasource.hikari.maximum-pool-size", "100"); System.setProperty("spring.datasource.hikari.minimum-idle", "10"); } @Bean public MySQLContainer<?> mySQLContainer() { return mysqlContainer; } @PreDestroy public void stop() { if (mysqlContainer != null && mysqlContainer.isRunning()) { mysqlContainer.stop(); } } } 이후 테스트를 진행해보니, 기존에 작성해두신 커넥션 풀 테스트인 EventJoinWithExternalConnectionPoolTest를 제외하고 테스트에 통과하였습니다.따라서, EventJoinWithExternalConnectionPoolTest이 테스트에만 작은 커넥션 풀을 적용하도록 하였습니다.@Slf4j @IntegrationTest // 커넥션 설정 @TestPropertySource(properties = { "spring.datasource.hikari.maximum-pool-size=32", "spring.datasource.hikari.minimum-idle=5" }) class EventJoinWithExternalConnectionPoolTest {문제가 발생한 원인은, Gradle 병렬 테스트 진행 시 커넥션 풀이 부족하여 커넥션이 이뤄지지 않았던 것 같습니다.사실 최대 커넥션 풀을 100개로 늘리는 건 임시방편인 것 같고, 테스트별로 독립적인 컨테이너 환경을 만들어주는게 좋을 것 같다고 생각합니다. P.S.) GPT, 클로드코드, Cursor, ... 다 문제 원인을 파악하지 못하더라고요 ㅎㅎ
-
미해결실무자를 위한 구글애널리틱스(GA4+GTM) 활용법(25년 Update)
브랜드검색광고 utm
1.utm_term에서 {query} 의미2,{keyword}의 경우 자동으로 utm 만들어지면{keyword} 앞뒤 지워야 한다는데 {query}도 마찬가진가요?
-
미해결제로베이스부터 배우는 웹개발의 개념과 바이브 코딩
구글에드센스 velcel 상업적이용
안녕하세요.좋은강의 제공해주셔서 감사합니다. vercel 무료 티어 같은 경우 구글에드센스를 상업적 이용으로 치부하고 있어 규정에 어긋나게 되는거 같은데 다른 대안이나 방안이 있을까요?
-
미해결키샷 입문•초급 : 극 사실적인 제품 이미지를 위한 키샷 렌더링 & 후보정 Part.1
강의 파일 관련 질문!
안녕하세요 선생님! 제가 강의 파일을 다운 받고 암호 입력까지 했는데 psd파일은 안 떠서 그런데 원래 그런건가용...???
-
미해결[2025] 비전공자도 한 번에 합격하는 SQLD 올인원
문제에 문제가 있는 것 같습니다.
Part 2 > Chapter 1 단원 정리 문제문제 57번입니다.쿼리문대로라면 2번이 답같은데 답지에는 1번이라고 나와있네요
-
미해결바닥부터 시작하는 STM32 드론 개발의 모든 것
6-4 ESC Calibration
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 6-4 ESC Calibration을 하는 도중 USB port 빛이 안나오고 swc를 prescaler 2000으로 내리면 esc Calibration이 되지않습니다 usb 포트에 불이 들어와야 esc에 입력되는 걸까요?
-
해결됨김영한의 실전 데이터베이스 입문 - 모든 IT인을 위한 SQL 첫걸음(SQL부터 차근차근)
문제5번 - 함수 코드 중복 방지를 위한 방법 중 서브쿼리와 CTE의 차이
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]질문이 서론과 본론으로 구분되어 있으며, 실제 질문 내용은 본론에 있습니다! 서론안녕하세요 영한님.문제5번에서는 SUBSTRING_INDEX(email, '@', 1) 함수를 user_id와 id_length에서 두 번 반복해서 사용하게 됩니다.중복 문제를 개선하기 위해 초기에는 다음과 같이 CHAR_LEGNTH(user_id) AS id_length로 시도를 했으나 실패했습니다. -- 에러 발생 코드 SELECT email, SUBSTRING_INDEX(email, '@', 1) AS user_id, CHAR_LENGTH(SUBSTRING_INDEX(user_id) AS id_length FROM customers ;그 이유는 SELECT 절의 모든 표현식이 논리적으로 동시에 평가되기 때문이라고 판단했고, 이를 해결하기 위한 방법 중 서브쿼리와 CTE(Common Table Expression) 방식을 찾았고 이를 직접 적용해봤습니다. -- sol1. 서브 쿼리 SELECT email, user_id, CHAR_LENGTH(user_id) AS id_length FROM (SELECT email, SUBSTRING_INDEX(email, '@', 1) AS user_id FROM customers ) AS dt ;-- sol2. CTE WITH email_parts AS ( SELECT email, SUBSTRING_INDEX(email, '@', 1) AS user_id FROM customers ) SELECT email, user_id, CHAR_LENGTH(user_id) AS id_length FROM email_parts; 본론이 과정에서 "서브 쿼리와 CTE의 성능 차이가 있는가?"에 대한 의문이 들어서 리서치를 했으나 제 수준이 부족한 탓인지 이에 대한 명확한 답변을 찾지 못했는데요(현재 '상황에 따라 다르다' 수준으로만 이해한 상태입니다).혹시 실무에서는 서브 쿼리와 CTE 중 (성능, 가독성, 개발팀 관례 등의 이유로 인해) 무엇을 선호하는지 의견을 들을 수 있을까 싶어 질문 남깁니다!혹시 다음 강의에서 다루는/다룰 내용이라면 제가 추후에 해당 강의를 들을 때 학습하도록 하겠습니다!
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
@Lock(OPTIMISTIC)이 필요한 이유
안녕하세요!강의를 복습하던 중 의문이 생겼습니다. JPA에서 @Version을 사용하면 자동으로 낙관적락이 적용되는 걸로 알고 있는데 @Lock(OPTIMISTIC)이 필요한 이유가 궁금했습니다. 그래서 알아보니 @Version의 경우는 엔티티에 수정/삭제가 될 경우에만 version을 체크하기 때문에 읽기만 존재할 때도 다른 곳에서 변경이 됐는지 감지하기 위해서는 @Lock(OPTIMISTIC)을 사용하라고 하던데 이게 맞을가요? 혹시 맞다면 @Lock(OPTIMISTIC)을 사용해서 OptimisticLockException이 발생하는 예시코드 부탁드립니다. 아래와 같이 테스트코드를 작성해봤는데 테스트가 성공하지 않아서요 @Test void optimistic_lock_on_read_conflict() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(2); Callable<Void> task1 = () -> { service.readWithOptimisticLock(productId); return null; }; Callable<Void> task2 = () -> { service.updatePrice(productId, 4000); return null; }; Future<Void> f1 = executor.submit(task1); Future<Void> f2 = executor.submit(task2); f2.get(); assertThatThrownBy(f1::get) // 읽기만 했던 쪽도 커밋 시점에서 충돌 감지 .hasCauseInstanceOf(OptimisticLockingFailureException.class); executor.shutdown(); } //service.readWithOptimisticLock(productId); @Transactional(readOnly = true) public void readWithOptimisticLock(Long id) { productRepository.findByIdWithOptimisticLock(id); try { Thread.sleep(2000); } catch (InterruptedException e) { throw new RuntimeException(e); } productRepository.flush(); } //service.updatePrice(productId, 4000); @Transactional public void updatePrice(Long id, int newPrice) { Product product = productRepository.findById(id).orElseThrow(); product.setPrice(newPrice); productRepository.flush(); // flush 시점에 @Version 체크됨 }
-
미해결
평생수강권 환불규정
아직 결제전입니다.평생수강권을 등록 후 2달뒤에 수강취소를 할 수 있나요?환불은 필요없고, 지원금으로 수강하는거라 2달 이후에 수강취소 증빙자료가 필요해서 여쭙니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
데이터 패칭과 프리패칭 순서
안녕하세요 강사님,복습하는 과정 중에 Page Router 기준으로 SSR + 프리패칭 + Hydration 흐름을 제가 이해한 대로 정리해보았는데, 이게 맞는지 확인 부탁드립니다.사용자가 /a 페이지에 있을 때 <Link href="/c" prefetch> 가 있으면, 브라우저는 백그라운드에서 /c.js (코드 스플리팅된 JS 청크)만 미리 받아 캐시에 저장해둔다.→ 이 단계에서는 HTML이나 데이터(getServerSideProps 결과)는 가져오지 않는다.사용자가 실제로 /c를 클릭하면, 서버가 getServerSideProps를 실행해서 데이터를 패칭하고, 그 결과를 반영한SSR HTML + JSON을 브라우저에 내려준다.브라우저는 HTML을 먼저 렌더링해서 FCP가 나오고, 이어서 캐시에 있던 /c.js를 실행한다.그 후 React가 HTML과 JS를 매칭시켜 Hydration을 수행하여 이벤트 핸들러를 연결한다.즉, SSR 페이지 전환 시1. User 클릭 → (서버) HTML 생성 및 데이터 패칭 → (브라우저) HTML 렌더링 → JS 실행 → Hydration이고, 프리패칭은 그 전에 JS만 준비해 두는 과정으로 이해했습니다.제가 이해한 흐름이 맞을까요? 머메이드로 도식화하자면 다음과 같습니다. 위가 맞다면, 빠른 페이지 전환을 위해하는 프리패칭을 했지만 결국 데이터 패칭 및 HTML을 서버에서 다시 그려오는데 빠른 전환이 가능한건지 궁금합니다.혹시 여기서 놓치고 있는 부분이나, 실제 네트워크 요청에서 다른 점이 있다면 알려주시면 감사하겠습니다!
-
미해결Git & GitHub, 원리부터 차근차근 - 근본깃 [완성편]
Git 머지 커밋 되돌리기(revert)와 머지 방식 선택의 안전성 질문
깃에서 머지(Merge)를 되돌려 이전 상태로 돌아가려면 어떤 방법을 써야 하는지 궁금합니다. fast-forward 머지인 경우에는 git reset을 이용해야 한다는 건 알겠습니다.그런데 머지 커밋이 생성되는 일반 머지의 경우, 해당 머지 커밋에 대해 git revert를 적용해서 이전 상태로 되돌릴 수 있을 것 같은데 그렇다면 fast-forward 머지보다 머지 커밋을 생성하는 방식이 더 안전한 선택인지도 궁금합니다.