172만명의 커뮤니티!! 함께 토론해봐요.
미해결
죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
... @Slf4j @Configuration @RequiredArgsConstructor public class LogProcessingJobConfig { private final JobRepository jobRepository; private final PlatformTransactionManager transactionManager; private final String BASE_PATH = "C:\\Users\\user\\Desktop\\batch\\section3\\flatfileitemwriter"; @Bean public Job logProcessingJob( Step createDirectoryStep, Step logCollectionStep, Step logProcessingStep ) { return new JobBuilder("logProcessingJob", jobRepository) .start(createDirectoryStep) .next(logCollectionStep) .next(logProcessingStep) .build(); } @Bean public Step createDirectoryStep(SystemCommandTasklet mkdirTasklet) { return new StepBuilder("createDirectoryStep", jobRepository) .tasklet(mkdirTasklet, transactionManager) .build(); } @Bean @StepScope public SystemCommandTasklet mkdirTasklet( @Value("#{jobParameters['date']}") String date ) { SystemCommandTasklet tasklet = new SystemCommandTasklet(); tasklet.setWorkingDirectory(BASE_PATH); String collectedLogsPath = "collected_ecommerce_logs\\" + date; String processedLogsPath = "processed_logs\\" + date; try { tasklet.setCommand("cmd.exe", "/c", "mkdir", collectedLogsPath, processedLogsPath); tasklet.setTimeout(3000); } catch (Exception e) { log.error("mkdirTasklet error: ", e); } return tasklet; } @Bean public Step logCollectionStep(SystemCommandTasklet scpTasklet) { return new StepBuilder("logCollectionStep", jobRepository) .tasklet(scpTasklet, transactionManager) .build(); } @Bean @StepScope public SystemCommandTasklet scpTasklet( @Value("#{jobParameters['date']}") String date ) { SystemCommandTasklet tasklet = new SystemCommandTasklet(); tasklet.setWorkingDirectory(BASE_PATH); String processedLogsPath = "collected_ecommerce_logs\\" + date; StringJoiner commandBuilder = new StringJoiner(" & "); for (String host : List.of("localhost")) { // Windows 환경에서 해당 코드를 적용하려면 ssh 관련 설정들을 찾아야 해서 주석 처리 // String command = String.format("scp %s:~/ecommerce_logs/%s.log %s\\%s.log", host, date, processedLogsPath, host); String sourcePath = BASE_PATH + "\\ecommerce_logs\\" + date + ".log"; String command = String.format("copy %s %s\\%s.log", sourcePath, processedLogsPath, host); commandBuilder.add(command); } tasklet.setCommand("cmd.exe", "/c", commandBuilder.toString()); tasklet.setTimeout(10000); return tasklet; } @Bean public Step logProcessingStep( MultiResourceItemReader<LogEntry> multiResourceItemReader, LogEntryProcessor logEntryProcessor, FlatFileItemWriter<ProcessedLogEntry> processedLogEntryJsonWriter ) { return new StepBuilder("logProcessingStep", jobRepository) .<LogEntry, ProcessedLogEntry>chunk(10, transactionManager) .reader(multiResourceItemReader) .processor(logEntryProcessor) .writer(processedLogEntryJsonWriter) .build(); } @Bean @StepScope public MultiResourceItemReader multiResourceItemReader( @Value("#{jobParameters['date']}") String date ) { MultiResourceItemReader<LogEntry> resourceItemReader = new MultiResourceItemReader<>(); resourceItemReader.setName("multiResourceItemReader"); resourceItemReader.setResources(getResources(date)); resourceItemReader.setDelegate(logFileReader()); return resourceItemReader; } private Resource[] getResources(String date) { try { String formattedBasePath = BASE_PATH.replace("\\", "/"); String location = "file:///" + formattedBasePath + "/collected_ecommerce_logs/" + date + "/*.log"; PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); return resolver.getResources(location); } catch (IOException e) { throw new RuntimeException("Failed to resolve log files", e); } } @Bean public FlatFileItemReader<LogEntry> logFileReader() { return new FlatFileItemReaderBuilder<LogEntry>() .name("logFileReader") .delimited() .delimiter(",") .names("dateTime", "level", "message") .targetType(LogEntry.class) .build(); } @Bean public LogEntryProcessor logEntryProcessor() { return new LogEntryProcessor(); } @Bean @StepScope public FlatFileItemWriter<ProcessedLogEntry> processedLogEntryFlatFileItemWriter( @Value("#{jobParameters['date']}") String date ) { String outputPath = Paths.get(BASE_PATH, "processed_logs", date, "processed_logs.jsonl").toString(); ObjectMapper objectMapper = new ObjectMapper(); JavaTimeModule javaTimeModule = new JavaTimeModule(); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"))); objectMapper.registerModule(javaTimeModule); return new FlatFileItemWriterBuilder<ProcessedLogEntry>() .name("processedLogEntryJsonWriter") .resource(new FileSystemResource(outputPath)) .lineAggregator(item -> { try { return objectMapper.writeValueAsString(item); } catch (JsonProcessingException e) { throw new RuntimeException("Error Converting item to JSON", e); } }) .build(); } @Data public static class LogEntry { private String dateTime; private String level; private String message; } @Data public static class ProcessedLogEntry { private LocalDateTime dateTime; private LogLevel level; private String message; private String errorCode; } public enum LogLevel { INFO, WARN, ERROR, DEBUG, UNKNOWN; public static LogLevel fromString(String level) { if (level == null || level.trim().isEmpty()) { return UNKNOWN; } try { return valueOf(level.toUpperCase()); } catch (IllegalArgumentException e) { return UNKNOWN; } } } public static class LogEntryProcessor implements ItemProcessor<LogEntry, ProcessedLogEntry> { private static final DateTimeFormatter ISO_FORMATTER = DateTimeFormatter.ISO_DATE_TIME; private static final Pattern ERROR_CODE_PATTERN = Pattern.compile("ERROR_CODE\\[(\\w+)]"); @Override public ProcessedLogEntry process(LogEntry item) throws Exception { ProcessedLogEntry processedLogEntry = new ProcessedLogEntry(); processedLogEntry.setDateTime(parseDateTime(item.getDateTime())); processedLogEntry.setLevel(parseLevel(item.getLevel())); processedLogEntry.setMessage(item.getMessage()); processedLogEntry.setErrorCode(extractErrorCode(item.getMessage())); return processedLogEntry; } private LocalDateTime parseDateTime(String dateTime) { return LocalDateTime.parse(dateTime, ISO_FORMATTER); } private LogLevel parseLevel(String level) { return LogLevel.fromString(level); } private String extractErrorCode(String message) { if (message == null) { return null; } Matcher matcher = ERROR_CODE_PATTERN.matcher(message); if (matcher.find()) { return matcher.group(1); } // ERROR 문자열이 포함되어 있지만 패턴이 일치하지 않는 경우 if (message.contains("ERROR")) { return "UNKNOWN_ERROR"; } return null; } } } 윈도우즈에서는 scp 명령어 관련해서 windows 서비스에서 open-ssh-server 실행 현재 사용하고 있는 사용자(windows 사용자) 가 관리자 권한을 보유 할 경우 programdata/sshd_config 파일 수정 필요 기타 파일 권한 정리 필요 로 인하여 scp 프로그램을 windows 환경의 intellij idea 에서 id, 비번치게끔 ide 콘솔에서 지원하지 않는거 같아. 그래서 제미니가 추천해준대로 실습 환경에서 scp 접속 단을 copy 로 그냥 퉁치는 것으로 바꿔놨어. 나처럼 windows 환경인 사람들이 있으면 혹시나 참고했으면 좋겠네. ObjectMapper, JavaTimeModule 같은 경우는 org.springframework.boot:spring-boot-starter-json 의존성 추가 필요
java spring spring-boot spring-batch backend
qlghwp123
2026-04-09T03:43:12.602Z
댓글 2
좋아요 1
조회수 94
미해결
2026 코딩테스트 올인원 [JAVA]
학습 관련 질문을 남겨주세요. 구체적으로 적을수록 좋아요! 마크다운과 단축키를 활용하면 글을 더 편하게 작성할 수 있어요. 커뮤니티 질문 & 답변에 비슷한 내용이 있었는지 먼저 검색해보세요. 편하게 질문주세요:) 직접 답변 드리도록 하겠습니다~ 안녕하세요. 제가 DFS/BFS부분이 많이 약해서 ㅠㅠ 질문입니다. lockers = [[1, 2], [3], [], [0]] 이런 이중행렬인데 인접리스트로 코드 변환 안하고 생각해도 괜찮다는 의미 인거죠…? 감사합니다.
java 코딩-테스트 알고리즘 data-structure
제비꼬리
2026-04-08T23:56:15.371Z
댓글 2
좋아요 1
조회수 78
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
CPU 스케줄링에서 SRTF(Shortest Remaining Time First)에 대해 질문 있습니다. 실제 시험에서 SRTF or SRT or SRF 셋 중에 하나를 쓰면 정답인가요? 시중에 있는 기출문제집의 해답에서는 SRT라고 되어 있어서 질문 드립니다.
python java c 정보처리기사 정보처리산업기사
준상
2026-04-08T10:50:10.814Z
댓글 2
좋아요 0
조회수 75
미해결
윤파고의 정보처리기사 DB/프로그래밍 All-In-One
col2만 세어야 하니까 3이죠,,?
python java c dbms/rdbms 정보처리기사
andrew98038@gmail.
2026-04-08T06:00:14.442Z
댓글 1
좋아요 0
조회수 46
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
10. 프로그래밍 언어 활용 에서 3.java 관계연산자/비트연산자의 문제풀이 보시면 F | T 할때 F 를 0000 T를 1111로 표현하던데 true는 0001 아닌가요? F|T -> 0000 | 1111 -> 1111 -> T 라고 되어잇고 XOR 연산자에도 T를 1111 로 표기해서 묻습니다.
python java c 정보처리기사 정보처리산업기사
최민영
2026-04-08T02:21:57.161Z
댓글 2
좋아요 0
조회수 89
미해결
김영한의 실전 자바 - 기본편
@Override public void print() { super.print(); System.out.println("- 저자: " + author + ", isbn:" + isbn); } 다름이 아니고 @Override를 하는 이유가 부모에서 사용하는 메서드를 자식에서 재사용을 위해서 사용하신다고 했는데 궁금한 게 강의 내용 중에 객체를 생성하고 메서드를 사용할 경우 먼저 자식을 보고 그다음에 없으면 부모를 보신다고 하셨는데 그러면 이미 자식에는 print가 있으니까 저렇게 super.print();를 붙이면 굳이 @Override를 안 붙여도 상관없지 않나요? 관례가 있어서 많은 개발자분들께서 붙인다고 하셨는데 저 경우에는 재사용이 아니고 바로 자식 쪽에서 메서드가 있으니까 굳이 부모까지는 갈 필요가 없지 않나요??
탕면이
2026-04-07T12:57:02.544Z
댓글 1
좋아요 0
조회수 71
해결됨
서버개발자 과제전형 완벽가이드 - 1편
학습관련 질문을 남겨주세요! 상세히 작성주시면 더 좋아요 🙂 안녕하세요, 강사님 🙂 이번 질문도 혼자 먼저 구현 후, 강사님의 강의를 들으며 리팩토링을 진행하며 궁금증이 하나 생겨 질문 드립니다. 저는 search-api 모듈의 com.library.repository의 NaverBookRepository.class 위치를 강사님과 다르게 external:naver-client 에 위치시켰습니다.(NaverBook/KakaoBook은 external 에 종속된 구현체라고 생각) 그러다 보니, naver-client 모듈이 search-api 모듈에 있는 BookRepository, PageResponse, SearchResponse 를 알아야 했으며, naver-client 모듈이 search-api 모듈을 implementation('...') 으로 의존?참조? 하게 되었습니다. // search-api 모듈 public interface BookRepository { PageResponse<SearchResponse> search(...); } 이렇게 external -> search-api 로 흘러가는 의존 방향에 이질감이 듭니다.(외부 API 가 app 을 안다..?) 그래서 모듈간 의존 방향이 search-api -> external 되도록 강사님 강의처럼 NaverBookRepository 를 search-api 모듈에 위치 시켜도 NaverClient 때문에 search-api에 feign 종속성이 생긴 다는 것이 모듈간 의존성 격리가 되지 않아서 멀티모듈의 장점이 퇴색되었다고 생각합니다. 강사님은 과제가 아닌 실무에서 search-api 와 external 간의 모듈 격리를 어떻게 하시며, 의존 방향을 어떻게 하시는지 궁금합니다. 저의 부족한 지식을 확장할 수 있게 강사님의 인사이트 공유해주시면 감사하겠습니다!
java spring spring-boot database
종혁
2026-04-07T12:19:15.382Z
댓글 2
좋아요 1
조회수 73
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
안녕하세요 31분 50초 Child() 함수에 this(5000) 이 있는데 부모를 호출 할 수 있나요? 저는 super, this 아무것도 없을때 명시적으로 super 는 없지만 자동으로 부모를 호출한다 super 가 있으면 부모를 호출한다. super, this 는 함께 못 쓰인다. 이렇게 알고 있어서, 문제를 풀 때 super 가 명시적으로 없어도 항상 숨어있다고 생각하고 접근했습니다. 그래서 Child() 생성자에 this 가 있으면 super 는 실행되지 않는다고 생각해서 부모 생성자 호출 과정을 제외하고 풀었는데, 결과가 다르게 나와서 헷갈렸습니다 this 가 있는데도 부모 호출이 맞는지 궁금합니다. 그리고 부모를 호출한다면 child() -> parent() -> parent(int x) -> child(int x) 순서가 맞는지도 알려주세요
python java c 정보처리기사 정보처리산업기사
whks
2026-04-07T08:54:30.481Z
댓글 2
좋아요 0
조회수 78
미해결
실전! Querydsl
plugins { id 'java' id 'org.springframework.boot' version '4.0.5' id 'io.spring.dependency-management' version '1.1.7' id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } group = 'study' version = '0.0.1-SNAPSHOT' description = 'querydsl202604' java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-h2console' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-webmvc' implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa-test' testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' // test 롬복 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' // Querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" } tasks.named('test') { useJUnitPlatform() } clean { delete file('src/main/generated') } // querydsl 추가 def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile querydsl { jpa = true querydslSourcesDir = querydslDir } sourceSets { main.java.srcDir querydslDir } configurations { querydsl.extendsFrom compileClasspath } compileQuerydsl { options.annotationProcessorPath = configurations.querydsl } 이렇게 하면 build 폴더에도 Q붙은 엔티티들 나오고요. 테스트 코드 짤 때도 Q붙은 엔티티들 불러올 수 있습니다. 참고하세요.
2026-04-06T11:31:48.840Z
댓글 2
좋아요 0
조회수 250
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
v1.0 이론을 업로드해주신다고 하였는데, 혹시 언제쯤 업로드될까요?
python java c 정보처리기사 정보처리산업기사
osoh63
2026-04-06T04:16:12.665Z
댓글 3
좋아요 0
조회수 159
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
이번에 2026년 8월 실기준비하고 있는데 들어도될까요 ?
python java c 정보처리기사 정보처리산업기사
co choi
2026-04-05T13:56:45.306Z
댓글 1
좋아요 0
조회수 123
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
(기출)2025년 3회 코드해설 14분 40초 리스트, 딕셔너리, 튜플에 대해 말씀해주시는데, python부분을 모두수강하였는데 이 부분은 따로 들은 기억이 없어 혹시 어디에 이부분 설명이 있는지 궁금하여 질문남깁니다. 좋은 강의 잘듣고있습니다. 감사합니다.
python java c 정보처리기사 정보처리산업기사
hangil lee
2026-04-05T08:31:35.425Z
댓글 2
좋아요 0
조회수 68
해결됨
2026 벼락치기 합격! 기출문제 집중 정보처리기사 실기
안녕하세요 수업노션자료파일에 보면 자료 다운로드 가 있는데 받으면 empty zip 파일만 생깁니다. 파일 받을 수 없는건가요? 보내주신 메일로 받아도 똑같다고 제가 다시 확인 후 메일 보내 달라고 요청했는데 회신이 없습니다 .확인 부탁 드립니다.
python java c 정보처리기사 database
violin_ku
2026-04-05T04:39:02.115Z
댓글 2
좋아요 0
조회수 91
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
Java: 상속을 정리하는 문제 10개 Java 강의를 들으면서 자식을 호출할 때 부모 기본 생성자 또는 부모꺼를 호출 후 자식 것을 호출해야한다는 내용과 자식만 호출해도 되는 경우의 내용이 섞여서 나오는데 자식을 호출할 때 부모 기본 생성자 또는 부모꺼를 호출 후 자식 것을 호출하는 경우가 어떤 것이 있는지 정리해서 알려주실 수 있을까요?
python java c 정보처리기사 정보처리산업기사
dhkdxo12
2026-04-05T03:50:48.643Z
댓글 2
좋아요 0
조회수 77
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
Java: 상속을 정리하는 문제 10개 7:29 obj.show(); 출력 관련해서 부모 클래스에 있는 void show()는 출력안하고 자식 클래스에 있는 void show()만 출력하는 것에 대해서 원래는 자식 클래스 출력을 할 시 부모 클래스에 기본 생성자를 출력하고 자식 클래스 출력을 해야한다고 알고 있는데 이 문제 경우에는 void로 되어 있어서 부모꺼는 출력하지 않고 자식꺼만 출력하는건가요?
python java c 정보처리기사 정보처리산업기사
dhkdxo12
2026-04-05T02:42:55.880Z
댓글 2
좋아요 0
조회수 53
미해결
김영한의 실전 자바 - 중급 1편
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 네 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 아니오 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 네 9번에 ==연산자와 equals 메서스 둘다 물리적 동일성 이라고 해야 맞는거아닌가요? 오버라이딩 되지 않은 기본 equals 는 ==으로 비교하고 논리적 동등성은 String 변수.equals 한정 아닌가요??
wxd8339
2026-04-04T07:52:32.274Z
댓글 2
좋아요 0
조회수 57
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
시키는 대로 다 하겠습니다. 벼락치기 2주 계획은 어떻게 잡으면 좋을지 궁금합니다. C, java, python 모두 뜨문뜨문 기억나서 기출 해설 강의는 한 40% 이해하는 것 같습니다.
python java c 정보처리기사 정보처리산업기사
이치우
2026-04-04T05:14:42.029Z
댓글 2
좋아요 0
조회수 150
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
2025년 1회 1/3 첫번째 ASCII코드 문제(10분경) 마지막 for문 증감식이 i++가 아니라 ++i인데 그러면 BACDE가 아니라 ACDE가 출력되어야 하는게 아닌가요?
python java c 정보처리기사 정보처리산업기사
zyk4749
2026-04-03T13:03:15.751Z
댓글 2
좋아요 0
조회수 57
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
안녕하세요 Python에서만 있는 연산자들 텍스트 강의입니다. 짧은 문자열, -5~256 범위 내의 숫자, None, bool 값은 is로 비교시에 동일하게 True로 나옵니다. 라고 적혀있는데 -5 부터 맞을까요? 이해가 잘 안되어서 질문드립니다.
python java c 정보처리기사 정보처리산업기사
안녕1233
2026-04-02T15:03:52.796Z
댓글 2
좋아요 0
조회수 58
해결됨
(2026 최신!) 일주일만에 합격하는 정보처리기사 실기
12:50의 업캐스팅 문제 예시4는 super.paint()이 전에 A를 먼저 참조하고 Constructor of A를 쓰는데 15:39의 업캐스팅 문제 예시6은 왜 super(10)이 있는데 바로 생성자 of AA10이 되나요?? super.paint와 super(10)의 차이인가요?
python java c 정보처리기사 정보처리산업기사
뽀로
2026-04-02T08:44:56.171Z
댓글 2
좋아요 0
조회수 72