#include <bits/stdc++.h> using namespace std; int N; map<int, vector<int>> mp; int tmp, d, ret; void removeAll(int key){ // if not leaf node -> recursive remove if(!mp[key].empty()) { for(int c: mp[key]) removeAll(c); } // erase itself mp.erase(key); } int main(){ cin >> N; // make graph for(int i = 0; i < N; i++){ mp[i]; cin >> tmp; if (tmp != -1) mp[tmp].push_back(i); } // input node to be deleted cin >> d; removeAll(d); if (mp.size() == 1) ret = 1; else if (mp.size() == 0) ret = 0; else { // for all key in map for(auto it: mp) { int key = it.first; // if the remaining value empty => plus if (mp[key].empty()) ret++; } } cout << ret; } 다음과 같이 map과 재귀를 풀어서 1068번 트리 문제를 풀었는데, 어디가 오답인지 감이 안옵니다.
선생님 안녕하세요, 예시문제 작업형 2번 문제 풀다가 궁금한 점이 있어서 질문 남깁니다. train, test 데이터를 describe 함수로 통계내 봤을 때 총 구매액와 최대 구매액에 음수 값이 있어 해당 행은 삭제하려고 합니다. 이 이후로 어떻게 진행해야 할지 몰라서 도움을 구해봅니다 ㅠㅠㅠ
Domain -> Response 변환 코드를 Domain에 정의해두고 Controller에서 Domain 메서드를 호출해서 Response를 변환하는게 맞나는 건 이해했습니다. 근데 실제 API에 해당 내용을 적용하려고 보니 Domain 단 건 조회보다는 List<Domain>을 반환하는 경우가 훨씬 많았습니다. 따라서 List<Domain>을 List<Response>로 변환해야 하는데 해당 작업을 for문이나 Stream으로 Controller로 처리하려니 Controller 코드도 지저분해지고 Controller가 하는 역할에 부합하지 않게 되는 것 같습니다. List<>를 변환할 때는 어디서 하는게 올바른 것인지 질문드립니다!
안녕하세요, 선생님. 강의 15분 경에 다음과 같은 코드가 나옵니다만, 저는 분명 동일한 코드를 실행했는데 오류가 떠서 질문드립니다. house_df.fillna(house_df.mean(),inplace = True) TypeError: can only concatenate str (not "int") to str 이 코드가 Null있는 문자형 열까지 포함시켜 처리하기 때문에 오류가 나는 거 같은데, 혹시 원래 정상적으로 실행되는 코드인가요…? 책에 있는 코드도 동일한데 제가 실행시키면 에러가 나서 전 Null 있는 숫자혀여 열에 대해서만 각 열의 평균값으로 결측치를 채워서 실행했습니다. 만약 현재 버젼으로 정상적으로 실행이 되지 않는 코드라면 선생님께서 혹시 이 부분에 대해서만 새로 작성하신 코드를 여쭙고 싶습니다! 방금 확인해보니까 jupyter notebook으로는 잘 실행되는데, vscode에서는 위와 같은 오류가 뜹니다. 혹시 이 오류가 뜨는 이유를 알 수 있을까요?
작업형 1 문제 3에서요 조건으로 풀어주셨는데요. sum 대신 len 쓰는 건 말이 안될까요? 일단 답은 틀렸어요,,.. 한국말로 일대일 대응해서 코드를 적어보면, f3 컬럼에서 '실버'인 행의 갯수를 출력하려면 len을 쓸수 있지 않을까요? 그런데 값이 달라 질문드립니다 ㅠㅠ
안녕하세요 Thymeleaf vs HTML + RestController 주제를 듣던 중 의아한 부분이 생겨 글을 작성하게 되었습니다. 해당 강의에서 Thymeleaf 에 대한 설명을 진행하던 와중, 도중 강의가 갑자기 끝나는 듯한 느낌을 받았습니다. 강의 페이지를 보니, 이후 설명되야 할 내용처럼 보이는 것을 발견했습니다. 혹시 중간에 강의가 누락된 것인지 확인 부탁드립니다.
위 문제와 같이 scanf_s를 연속으로 사용할 때 궁금한 점이 있습니다. 먼저 첫번째 입력으로 1을 입력하면 버퍼에 [1][\n] 이렇게 입력되고 1이 빠져나가면 [\n]이 버퍼에 남게 되는 걸로 이해하고 있습니다. 그렇다면 두번째 입력 때 [\n] [2] [\n] 이렇게 입력이 되는건가요? 또한 만일 엔터가 맨 앞에 있다면 왜 scanf_s를 연속으로 쓸 때는 스킵이 안되는지와 get_s와 같이 쓰면 스킵이 되는지가 궁금합니다..!
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요. 강의를 듣기 전 풀어봤는데, 설명해주신 방법도 숙지하겠습니다. function solution(s) { let answer = ''; let stack = []; let contain = false for (let ele of s) { if (ele === '(') { contain = true stack.push(ele) } if (!contain) { answer += ele } if (ele === ')') { stack.pop() if (stack.length === 0) contain = false } } return answer }
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 코드는 마지막에 첨부되어 있습니다. 게시글 엔티티 Post가 게시글에 달린 댓글 엔티티 Comment의 컬렉션을 프로퍼티로 갖습니다. 댓글 엔티티 Comment는 COMMENT, REPLY 타입으로 구분되며, 프로퍼티로 parentComment와 replies를 갖습니다. COMMENT 타입은 parentComment == null이며, REPLY 타입은 replies == null입니다. Post.comments는 Comment의 타입을 고려하지 않고 모두 갖고 있습니다. 위 상황에서 게시물 상세 정보를 가져올 때, comments를 fetch join하여 Post 엔티티를 가져와 댓글들을 타입 계층에 따라 분리하는 작업을 합니다. 이때 REPLY 타입의 replies에 접근하지 않습니다. COMMENT 타입의 replies에는 접근하며 해당 replies는 모두 같은 게시물에 속해있습니다. 예상했던 쿼리의 개수는 1 혹은 (1 + COMMENT 타입 수) 였습니다. 애초에 둘 중 무엇인지 궁금해서 일을 진행했었습니다. 테스트를 실행해보면, post.comments의 요소에 처음 접근할 때 REPLY 타입을 가져오는 쿼리가 발생합니다. 그런데 이후에 다른 COMMENT 타입에 접근할 때는 REPLY를 가져오는 쿼리가 발생하지 않습니다. 만약 Post의 COMMENT 타입 Comment.replies에 접근할 때 쿼리가 발생하는 거라면 COMMENT 타입의 개수만큼 발생해야 하는게 아닌가요? 제가 무엇을 놓치고 있는지 궁금합니다. 논외로, Spring data JPA의 @Query를 통해 작성한 단순한 정적 쿼리가 계속 반복된다면 QeuryDSL로 옮겨 반복을 줄이는게 합리적일까요? 아니면 spring data jpa의 편리함을 유지하는게 합리적인가요? 감사합니다. public class Post extends BaseEntity { public static final int TITLE_MAX_LENGTH = 50; public static final int CONTENT_MAX_LENGTH = 10000; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "post_id", nullable = false, updatable = false) private Long id; @Column(name = "title", nullable = false, length = TITLE_MAX_LENGTH, updatable = false) private String title; @Column(name = "content", nullable = false, length = CONTENT_MAX_LENGTH) private String content; @Column(name = "hits", nullable = false) private Long hits; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "writer_id") private Member writer; @OneToMany(fetch = FetchType.LAZY, mappedBy = "post", orphanRemoval = true) @ToString.Exclude private List<Comment> comments = new ArrayList<>(); } public class Comment extends BaseDeleteEntity { public static final int CONTENT_LENGTH = 1000; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "comment_id", nullable = false) private Long id; @Column(name = "content", nullable = false, length = CONTENT_LENGTH) private String content; @Column(name = "type", nullable = false, updatable = false) private CommentType type; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "post_id", nullable = false, updatable = false) private Post post; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "writer") private Member writer; @OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", orphanRemoval = true) private List<Comment> replies = new ArrayList<>(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_comment_id", updatable = false) @ToString.Exclude private Comment parent; } @Query(value = """ SELECT p FROM Post p LEFT JOIN FETCH p.writer AS w LEFT JOIN FETCH w.profile LEFT JOIN FETCH p.comments WHERE p.id = :postId """ ) Optional<Post> findPostById(@Param("postId") final Long id); @Autowired EntityManager em; @Autowired PostRepository postRepository; @Test public void 정상작동테스트_추가적인_쿼리_발생_x() throws Exception { //given Post post = PostTest.create("username", "nickname"); Member member = post.getWriter(); em.persist(member); em.persist(post); Long postId = post.getId(); int commentCount = 10; int replyCount = 2; createComment(post, member, commentCount, replyCount); em.flush(); em.clear(); //when int totalCommentCount = commentCount * (replyCount + 1); Post findPost = postRepository.findPostById(postId).get(); System.out.println(); //then for (Comment comment : findPost.getComments().stream().filter(Comment::isCommentType).toList()) { // 이때 REPLY 타입을 조회하는 쿼리가 1회 발 System.out.println("comment = " + comment); System.out.println("comment.getReplies().get(0) = " + comment.getReplies().get(0)); } Assertions.assertThat(post.getComments().size()).isEqualTo(totalCommentCount); } [테스트 실행 시 쿼리] 2023-11-02T11:45:00.154+09:00 DEBUG 51844 --- [ main] org.hibernate.SQL : select p1_0.post_id, c1_0.post_id, c1_0.comment_id, c1_0.content, c1_0.created_by, c1_0.created_date, c1_0.deleted_date, c1_0.is_deleted, c1_0.last_modified_by, c1_0.last_modified_date, c1_0.parent_comment_id, c1_0.type, c1_0.writer, p1_0.content, p1_0.created_by, p1_0.created_date, p1_0.hits, p1_0.last_modified_by, p1_0.last_modified_date, p1_0.title, w1_0.member_id, w1_0.created_by, w1_0.created_date, w1_0.last_modified_by, w1_0.last_modified_date, w1_0.login_id, w1_0.login_type, w1_0.profile_id, p2_0.profile_id, p2_0.created_by, p2_0.created_date, p2_0.last_modified_by, p2_0.last_modified_date, p2_0.nickname, w1_0.user_role, w1_0.social_login_id, w1_0.username from post p1_0 left join member w1_0 on w1_0.member_id=p1_0.writer_id left join profile p2_0 on p2_0.profile_id=w1_0.profile_id left join comment c1_0 on p1_0.post_id=c1_0.post_id where p1_0.post_id=? 2023-11-02T11:45:00.162+09:00 INFO 51844 --- [ main] p6spy 2023-11-02T11:45:01.221+09:00 DEBUG 51844 --- [ main] org.hibernate.SQL : select r1_0.parent_comment_id, r1_0.comment_id, r1_0.content, r1_0.created_by, r1_0.created_date, r1_0.deleted_date, r1_0.is_deleted, r1_0.last_modified_by, r1_0.last_modified_date, r1_0.post_id, r1_0.type, r1_0.writer from comment r1_0 where array_contains(?,r1_0.parent_comment_id) [반복되는 spring data jpa 쿼리] public interface PostRepository extends JpaRepository<Post, Long>, PostQueryRepository { /** * Post 반환 시 Member, Profile을 fetch join한다. ~ToOne 매핑관계에 대한 fetch join은 별명을 사용할 수 있고, 연계하여 fetch * join할 수 있다. * * @param id must not be {@literal null}. * @return */ @Query(value = """ SELECT p FROM Post p LEFT JOIN FETCH p.writer AS w LEFT JOIN FETCH w.profile LEFT JOIN FETCH p.comments WHERE p.id = :postId """ ) Optional<Post> findPostById(@Param("postId") final Long id); /** * Post를 페이징 처리하여 Page<Post>로 반환한다. 이때 Member와 Profile을 fetch join한다. * * @param pageable the pageable to request a paged result, * can be {@link Pageable#unpaged()}, * must not be {@literal null}. */ @Query(value = """ SELECT p FROM Post p LEFT JOIN FETCH p.writer AS w LEFT JOIN FETCH w.profile """, countQuery = "SELECT count(p) FROM Post p" ) @Override Page<Post> findAll(final Pageable pageable); /** * WriterId가 memberId와 같은 Post를 페이징 처리하여 Page<Post>로 반환한다. 이때 Member와 Profile을 fetch join한다. * * @param writerId writerId가 일치하는 Post들을 반환한다. * @param pageable 페이징 정보 */ @Query(value = """ SELECT p FROM Post p LEFT JOIN FETCH p.writer AS w LEFT JOIN FETCH w.profile WHERE w.id = :writerId """, countQuery = "SELECT count(p) FROM Post p WHERE p.writer.id = :writerId" ) Page<Post> findAllByWriterId(@Param("writerId") final Long writerId, final Pageable pageable); }
spring security 3.1.5 버전 방식입니다. 기존에 implement 하지 않고 클래스를 @configuration 해서 구성 파일로 인식하게 만들고 해당 메서드를 @bean 을 주입시켜 사용하는 방식입니다. 처음 참조할 부분은 여기를 참조 하시면 됩니다. 처음 설정 방법 :: 3.1.5 방법 1 SecurityConfig::SecurityFilterChain 메서드를 수정하기 @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity .csrf(AbstractHttpConfigurer::disable) .exceptionHandling((handling) -> handling.authenticationEntryPoint(jwtAuthenticationEntryPoint) .accessDeniedHandler(jwtAccessDeniedHandler) ) .headers((header) -> header.frameOptions( HeadersConfigurer.FrameOptionsConfig::sameOrigin ) ) .authorizeHttpRequests((registry) -> registry.requestMatchers("/api/hello").permitAll() .requestMatchers("/api/authentication").permitAll() .requestMatchers("/api/signup").permitAll() .anyRequest().authenticated() ); return httpSecurity.build(); } 방법 2 JwtSecurityConfig에 메서드를 하나 추가 한다. public HttpSecurity configureAndReturn(HttpSecurity httpSecurity) { httpSecurity.addFilterBefore( new JwtFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class ); return httpSecurity; } SecurityConfig::SecurityFilterChain 메서드를 수정하기 @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { return new JwtSecurityConfig(tokenProvider).configureAndReturn( httpSecurity .csrf(AbstractHttpConfigurer::disable) .exceptionHandling((handling) -> handling.authenticationEntryPoint(jwtAuthenticationEntryPoint) .accessDeniedHandler(jwtAccessDeniedHandler) ) .headers((header) -> header.frameOptions( HeadersConfigurer.FrameOptionsConfig::sameOrigin ) ) .authorizeHttpRequests((registry) -> registry.requestMatchers("/api/hello").permitAll() .requestMatchers("/api/authentication").permitAll() .requestMatchers("/api/signup").permitAll() .anyRequest().authenticated() ) ).build(); } 개인적으로는 방법 1이 깔끔하다고 느낍니다.
강의자료를 보던중에 혼동이 와서 질문드립니다.. 강의자료를 보면 세션을 생성하고, 신규 세션을 반환하고, 세션에 데이터를 보관하고.. 등등 세션이라는 단어가 사용이 되는데요.. 하지만 이전에 세션 저장소라는 개념도 있어서 '세션'과 '세션저장소'의 구분이 잘 되지않습니다.. 다른 질문을 참고하니 HttpSession은 세션저장소이다 라고 답변주신것을 보긴했습니다. 그리고 session은 Map형태로 저장이 되서 세션저장소 내부에 있는 Map자체를 session이라고 생각했는데, 이 Map의 sessionId에 대응되는 값도 session이라고 부르는것인가요..? HttpSession = 세션저장소 세션저장소내에 세션이 있다. 세션 = 세션저장소 내에 있는 Map = 세션저장소 내에 있는 Map의 value 이렇게 이해해도 되는것일까요..?
store.js는 mutations 속성에 DB(or localStorage)에 접근해서 실제로 데이터를 CRUD하는 함수를 정의하고, 각각의 컴포넌트들의 methods 속성에는 $store.commit을 통해 store.js로 상태들을 모아주는 역할을 하는 것이라 이해를 했습니다. 여기서 궁금한 부분은, 데이터를 가공하는 로직이 필요할 경우 각 컴포넌트의 methods에서 가공 후 store로 넘기는 방법 일단 데이터를 다 받은 뒤 store의 mutations에서 가공&저장을 하는 방법 저는 각각의 컴포넌트에서 가공한 뒤 가공된 데이터를 store로 넘기는 게 맞다고 생각이 되는데, 뭐가 더 나은 방법일지 궁금해서 문의드립니다.
안녕하세요 강사님 강의듣고 이해안되는 부분이 있어서 질문 남깁니다. 최초로 상품등록을 하면 컨트롤러에서 Get메서드형식인 아래의 컨트롤러가 호출이되면서 빈깡통의 Item 객체가 모델에 담겨서 addForm.html로 값이 넘기는것으로 알고있는데요 그래서 최초 등록폼에서 소스보기를 하면 상품명 ,가격,수량부분이 value 가 공백이 들어간것으로 이해했습니다. @GetMapping("/add") public String addForm(Model model) { model.addAttribute("item", new Item()); return "form/addForm"; } 하지만 의문드 드는점이 등록지역의 value는 SEOUL이 들어갔습니다 답은 메서드단위의 resions의 값이 들어갔다는것을 알고있지만 이해가 되지 않는점이 addForm에 등록지역 부분에는 th:field부분에서 ModelAttribute의 값인 ${resions}이아니고 선택변수인 {resions}가 들어갔으니 최초에는 값이 없으니 위의 상품명처럼 value가공백이 들어가야하는데 SEOUL로 들어가는 것이 이해가 안갑니다. th:field= {resion}의 자동생성되는 value가 th:value의 ${resions}의 벨류로 덮어쓰기가 되는건가요? 긴글 읽어주셔서 감사합니다.
안녕하세요, 앨런, Qos 부분을 수강하면서 수업 자료에 있던 코드들을 이렇게 바꾸어서 실행해보았는데요... 첫줄은 sync 라서 시작/완료까지 실행하고 task2, task4(비동기라서 완료까지 안 찍고 넘어가고), 그리고 task3 시작/완료 라고 이해를 했습니다. 제가 예상한 결과였고, 그렇게 출력이 되었어요. 근데 동일한 코드를 반복적으로 실행하면 그때마다 다른 결과가 나오는데.. 왜 그런지 모르겠어서 질문 남깁니다.. ㅠㅠ 어쩔때는 4가 먼저 실행되고 어쩔때는 3이 먼저 실행되더라구요.. 왜 그렇게 순서가 바뀌는지가 가장 궁금하고.. qos를 통해서 우선순위를 설정한다는 의미가 언제 어떻게 우선순위대로 실행되도록 한다는 것인지 이해를 못 한 것 같습니다... 위 코드에서 userInteractiveQueue 가 defaultQueue.async(qos: .userInitiated)보다 우선순위가 높은 것이 실행을 먼저 하는 것은 아닌것 같은데.. 우선순위라는게 어떻게 반영이 되는것인지 감이 안 잡힙니다 ㅠㅠ 아니면 제가 쓸데없는 코드를 보면서 고민한건지.. 답변부탁드려요!!
안녕하세요. 선생님. 선생님 강의로 많이 배우고 있네요. UrlFilterInvocationSecurityMetadataSource 를 직접 구현하여 DB와 연동하는 것을 보여주셨는데. 이 클래스에 Resouce 인가 설정을 위한 클래스의 멤버 변수로 LinkedHashMap<RequestMatcher, List<ConfigAttribute>> requestMap 을 사용하네요. 만약 DB에 Resource, Role 인가 설정 변경 시 reload()가 불렸을 때 DB에서 모두 가져와 requestMap 에 put 하는데 이것이 multi thread 에 safe 한지요? 만약 thread에 safe 하지 않다면 좋은 방법이 있는지요? lock을 쓰기에는 read 요청이 많아 부담스러울 것 같다는 느낌이 있네요. 강의에서 Role 추가 시 실시간 설정 반영은 하지 않았지만 RoleHierarchy 또한 마찬가지 인 것 같아요. 운영 시 거의 변경이 안되기 때문에 그냥 놔두는게 가장 좋은 방법인지? 선생님의 의견을 알고 싶어요. 감사합니다.