학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 새로운 switch 문을 작성 했는데 오류가 나네요 switch 문 전체가 빨간줄로 에러가 뜨는데 이유좀 알려주세요 package reEx1; import java.util.Scanner; public class Switch_01 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("등급을 입력하세요:"); int grade = scanner.nextInt(); int coupon = switch (grade) { case 1 -> 1000; case 2 -> 2000; case 3 -> 3000; default -> 500; }; } }
안녕하세요. 강의 잘 듣고 있습니다. 첫번째 질문. 다름이 아니라, 처음에 회원가입 기능을 구현할 때, ViewModel 을 @Observable 을 통해 관찰 가능한 상태로 두고, ViewModel 을 다루는 가장 상위 View인 ContentView 에서 @State 로 선언하는 것까지는 이해가 됩니다. ContentView의 하위 뷰들 중에서, 로그인과 관련한 뷰는 Login - EnterEmail - EnterPassword - EnterName - EnterUserName - Complete인데, 강사님께서 코드로 작성해주신 간접적으로 접근하는 방법 말고, @Environment(SignupViewModel.self) var signupViewModel var body: some View { @Bindable var signupViewModel = signupViewModel 처음 설명해주신 직접적인 접근 방식을 활용했습니다. @Bindable var signupViewModel: SignupViewModel var body: some View{ 와 같이, ViewModel 에 read-write가 가능하기 위해 @Bindable 을 사용한다는 사실은 알고 있습니다. 하지만 문제는 아래와 같이 입력한 결과에 대해서 출력도 잘 하는데, @Bindable 을 적용하였을 때, 마지막 CompleteView 에서 아래의 완료 버튼을 눌렀을 때 MainTabView 으로 넘어가지 않은 문제가 생겼습니다. 기존 Auth.auth().currentUser 을 사용했을 때, swiftUI에서 변화를 감지 못하기 때문에, 알려주신대로 ViewModel 내부에서 var currentUserSession: FirebaseAuth.User? 프로퍼티를 만들어 했는데.. 왜 이러한 문제점이 생기는걸까요? if signupViewModel.currentUserSession != nil{ MainTabView() } else { LoginView() .environment(signupViewModel) } 물론, 강사님이 알려주신 방법대로 하면 잘 넘어갑니다 ^^. 두 번째 질문 간접적인 방법 .environment 를 사용했을 때, 오류가 떠서 CANVAS를 끄고 작업을 하셨는데 오류를 없앨수 있는 방법이 있을까요? 1) 최상단 InstagramCloneApp에 ViewModel을 적용? 2) environment로 설정되는 모든 뷰의 #Preview에 .enivronment() 적용? 긴 글 읽어주셔서 감사합니다 😃 답변 기다리겠습니다.
동영상은 17분 30초쯤 해당됩니다. 여기서 class X에 method2()를 하면 본인 classX가 아니라 classY의 method2()로 간다고 하셨는데 그럼 만약 classX에 metho2()가 this.method2()로 바뀌면 classX의 method2()로 가는 건가요? 감사합니다
코드 시작할때 부모의 car을 먼저 부르고 그다음 자식것을 호출하는것은 잘 알겠습니다. 만약에 스타트 엔진이라는 메서드가 자식에게도 있었다면 오버라이딩이 우선, 재정의된 자식것이 출력 -> 다음코드진행 위의 car처럼 부모것을 부르고, 자식것을 출력 -> 출력 (이게 성립되려면 스테틱이 붙어서 하이딩이 되어야 하는지..?) 답변 요청드립니다!
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] @PostMappping("/members/new") public String create() 여기에 Memberform form 을 파라미터로 넣었는데, Memberform 클래스를 사용하지 않고 이런식으로 그냥 Member 만 사용해서 바로 join이 가능한가요? 가능하지만 MemberForm 클래스를 활용하는 데 장점이 존재하기 때문에 MemeberForm 클래스를 사용하는건가요? 아니면 아예 아래 코드처럼은 불가능한건가요? @PostMapping("/members/new") public String create(Member member) { memberService.join(member); return "redirect:/"; }
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 프록시 객체에 대한 개념을 들어도 실제로 어떤 상황일때 쓰이는지 잘 이해가 안가는데 설명부탁드립니다. 2.준영속,삭제 상태의 프록시 객체를 조회하려고 하면 영속성 컨텍스트의 도움을 받을 수 없기 때문에 예외가 발생한다고 하셨습니다. 그렇다면 프록시 객체가 아닌 일반 객체에서는 예외가 발생하지 않나요? 만약 그렇다면, 왜 그렇게 되는지도 궁금합니다. 위와 같이 코드를 작성했습니다. find를 하고 출력할 때 프록시 객체가 출력되는건 이해가 가는데. find를 할 때 왜 sql 쿼리가 나가는지 이해가 가지 않습니다. find가 실제 DB에서 조회하는건 맞지만, 동일성을 보장하기 때문에 조회를 하면 안되는게 아닌지..
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] equals 메서드 오버라이딩 할 때 안에서 String 비교를 equals로 하셨는데 이러면 재귀호출되어 무한 반복되는 문제가 발생하지 않는 이유는 무엇인가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] public static void main(String[] args) { // 초기 은행 계좌 int balance = 0; try{ while (true) { Scanner sc = new Scanner(System.in); System.out.println("---------------------------------"); System.out.println("1.입금 | 2.출금 | 3.잔액 확인 | 4.종료"); System.out.println("---------------------------------"); System.out.print("선택: "); int option = sc.nextInt(); switch (option) { case 1: balance = deposit(balance, sc); continue; case 2: balance = withdraw(balance, sc); continue; case 3: System.out.println("현재 잔액: "+balance+"원"); continue; case 4: System.out.println("시스템을 종료합니다."); break; default: System.out.println("메뉴에서 값을 선택해주세요."); } } } catch (InputMismatchException e) { System.out.println("숫자를 입력해주세요."); } } public static int deposit(int balance, Scanner sc) { System.out.print("입금액을 입력하세요: "); int amount = sc.nextInt(); balance += amount; System.out.println(amount + "원을 입금하였습니다. 현재 잔액: "+balance); return balance; } public static int withdraw(int balance, Scanner sc) { System.out.print("출금액을 입력하세요: "); int amount = sc.nextInt(); if (balance >= amount) { balance -= amount; System.out.println(amount + "원을 출금하였습니다. 현재 잔액: " +balance); } else { System.out.println(amount + "원을 출금하려 했으나 잔액이 부족합니다."); } return balance; } 일반적으로 Scanner sc 를 메서드로 넘겨주는 행위를 하지 않는 걸로 아는데, 강의에서 설명해주신 부분 처럼 swich-case 문을 쓸 때처럼 따로 method를 뺄때 sc를 넘기지 않고, 실제 계산하고 출력하는 부분만 method로 만드는게 맞을까요?
강의 내용과 무관한 질문인데요. C언어 문제들을 여러 개 풀다보니까 직관적으로 눈에 보이는 게 많아지긴 했습니다. 예를들어 반복문 안에서 배수를 구한다던지, null을 만나면 빠져나간다던지.. 배열 공부 중에 래그드 배열이라는 걸 알게됐는데 계단식으로 쪼개지는(?) 규칙성이 있더라고요. 그래서 말인데 혹시 래그드배열 관련 강의나 자료 올려주실 계획이 따로 있으실까요..? ㅎㅎ
위 오류가 발생하고 스택오버플로우 중국 플랫폼 사이트 갓대희님 블로그 등 모든 사이트를 찾아보았으며, 하이퍼 바이저 실행여부, svm 실행 여부, wsl 재설치, 도커 데스크탑 버전이슈도 있었으므로 버전 변경 등 할수있는 모든 방법을 전부 실행하였으나 해결되지 않았습니다. 도커 데스크탑을 사용하지 않고 진행하는 방법이 있는지 궁금합니다. 현재 제 윈도우 11 21h2 환경에서는 도커데스크탑의 설치가 불가하다고 판단이 되는데 수업에 대해서 진행이 가능한지 궁금합니다.
if 문에 i%2 !=0 (i를 2로 나눴을때 0이 아니면 참) i가 0 일때 i++ 하면 1%2 !=0(참 이므로 continue) 그다음 21:05 i가 1일때 i++돼서 i가 2가 된 후 if문을 실행하잖아요 그러면 나머지가 0이므로 거짓이니까 printf문에서 2가 출력돼야 하는거 아닌가요?
안녕하세요. 연습문제 2번을 다음과 같이 풀어보았습니다. Q: 리텐션 연습문제: Retain User를 New, Current, Resurrected, Dormant User로 나누는 쿼리를 작성하여라. 주어진 데이터에서 어떤 사람들이 리텐션이 그나마 높은지, 찾아보아라. 주차별, 전체 유저에 대한 코호트 분석 그래프를 보면, 다음과 같습니다. 문제 정의 2022년 12월 19일 이후로 리텐션이 떨어지고 있는 문제점이 발생했다. 해당 원인이 무엇일까? 가설 설정 1) 고객의 유입량이 감소하고 있다. -> 2022년 12월 19일 이전과 이후의 주차별 신규 가입자 수를 비교한다. 2) 리텐션의 변화가 특정 유저 그룹에 의해 영향을 받는가? -> 신규유저는 어떤 시점을 기준으로 분류할 것인가? 주차별 신규 가입자 수 시각화 2022년 12월 19일을 월요일로 하는 주차부터 신규 가입자 수가 감소하는 추세이다. 전반적으로 신규가입자 수는 증가하는 추세였으나, 12월 19일을 기점으로 꺾이는 현상을 보인다. 따라서, 신규 가입자 수가 리텐션에 영향을 준다는 것을 확인할 수 있다. 기존의 추세와 반하게, 떨어지는 추세를 보이기 때문에 다음과 같이 기존 유저와 신규 유저를 정의하겠다. 1) 기존 유저 => 2022년 10월 03일 ~ 2022년 12월 19일 이전 2) 신규 유저 => 2022년 12월 19일 이후 복귀유저와 이탈 유저를 판단하는 기준이 필요하다. 이를 위해, 첫 로그인 이후, 두번째로 로그인을 하기까지의 걸리는 시간을 4분위 수로 검증해서, 중위값을 기준으로 기존유저와 복귀유저를 구분해보기로 했다. 로그인 판단 기준 = click_login 이라는 이벤트가 발생했을 경우 1. 자동 로그인 여부 판단 SELECT COUNT(*) FROM advanced.app_logs CROSS JOIN UNNEST(event_params) AS ep WHERE ep.key = "firebase_screen" AND ep.value.string_value = 'welcome' AND user_id IS NOT NULL 자동 로그인이 된다면, click_login 이벤트가 발생하지 않을 것이다. 하지만, COUNT(*)가 0이기 때문에, 해당 앱은 자동 로그인이 되지 않음을 알 수 있다. 즉, 사용자가 앱에 접속하면, 가입을 했더라도, 무조건 로그인을 해야한다. 따라서, 사용자가 앱에 접속 시, 로그인 이벤트가 무조건 발생한다. 2.첫번째 로그인 후, 다음 로그인하기까지 걸린 시간을 4분위 수로 계산 WITH base AS (SELECT event_date, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_timestamp, user_pseudo_id, event_name, ROW_NUMBER() OVER (PARTITION BY user_pseudo_id ORDER BY event_date) AS login_rn FROM advanced.app_logs WHERE event_name = 'click_login' AND event_date >= '2022-10-03' QUALIFY login_rn < 3) , second_event_data AS (SELECT event_date, event_timestamp, user_pseudo_id, event_name, login_rn, IF(second_event_date IS NULL, '2023-01-20', second_event_date) AS second_event_date FROM (SELECT *, LEAD(event_date) OVER (PARTITION BY user_pseudo_id ORDER BY event_date) AS second_event_date FROM base)) SELECT APPROX_QUANTILES(date_diff_day, 100)[OFFSET(25)] AS percentile_25, APPROX_QUANTILES(date_diff_day, 100)[OFFSET(50)] AS percentile_50, APPROX_QUANTILES(date_diff_day, 100)[OFFSET(75)] AS percentile_75, MAX(date_diff_day) AS percentile_100, AVG(date_diff_day) AS average FROM (SELECT DATE_DIFF(second_event_date, event_date, DAY) AS date_diff_day FROM second_event_data) 유저별로 로그인을 한 시점을 ROW_NUMBER()로 카운트했다. 또한, second_event_date(다음 로그인 시점)이 NULL인 경우는 이탈 유저이다. 그런데, 4분위 수를 계산하려면, 해당 값을 채워야했다. 2099-12-31로 하려고 했으나, 너무 큰 값을 채워버리면, 4분위 수 검증이 정확하지 않게 되기 때문에 (mid와 avg값이 오른쪽으로 치우쳐버리는 현상이 발생할 수 있다.) second_event_date의 max값을 구해서, 2023-01-20을 채워주었다. Approx_quantiles 함수는 백분위로 나눌 경우, 각 근사치의 최대값을 나타내는 함수이다. 중위값에 해당하는 값들 중 가장 큰 값은 39일이다. 이번에는, 해당 범위에 속하는 값들이 몇개가 있는지 확인해보겠다. SELECT COUNTIF(date_diff_day <= 19) AS count_up_to_25, COUNTIF(date_diff_day > 19 AND date_diff_day <= 39) AS count_25_to_50, COUNTIF(date_diff_day > 39 AND date_diff_day <= 66) AS count_50_to_75, COUNTIF(date_diff_day > 66 AND date_diff_day <= 109) AS count_75_to_100 FROM temp 데이터가 1분위, 2분위에 몰려있다. 따라서, 40일 을 기준점으로 삼아야겠다. 2022년 12월 19일 이후 ~ (신규유저) 2022년 10월 3일 이후 ~ 2022년 12월 19일 이전, 10월 3일 이후부터 다음 접속 시간이 40일 이전인 경우 (기존유저) 2022년 10월 3일 이후로부터 40일 이후로 접속한 유저(복귀유저) 2022년 10월 3일 이후로부터 40일 이후로도 접속 이력이 없는 경우 (이탈 유저) 3. 다음 접속일까지의 걸린 일 수 기반, 유저 분류 -- 유저별, 첫번째 로그인 후, 다음 로그인하기 걸린 시간을 4분위 수로 계산 -- 25% | 50% | 75% | 100% -- 로그인_이벤트: click_login -- event_date, event_timestamp, event_name, -- 중간테이블 -- 유저별 로그인을 한 시점을 ROW_NUMBER()로 카운트하기 -- 유저별 첫번째 로그인을 한 시점 구하기 MIN(event_date) OVER() -- second_event_date가 NULL인 경우는 이탈 유저임. -- 그런데, 4분위 수를 계산하려면, MAX(second_event_date) 값을 구하고, NULL을 잠시 해당 값으로 채워놔야함. -- 그 이유는 너무 큰 값으로 채워버리면, 4분위 수 검증이 정확하지 않기 때문임 (mid값과 avg값이 오른쪽으로 치워쳐버리는 현상이 발생할 수 있음) max_event_date: 2023-01-20 WITH base AS (SELECT event_date, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_timestamp, user_pseudo_id, event_name, ROW_NUMBER() OVER (PARTITION BY user_pseudo_id ORDER BY event_date) AS login_rn FROM advanced.app_logs WHERE event_name = 'click_login' AND event_date > '2022-10-03' QUALIFY login_rn < 3) , second_event_data AS (SELECT DISTINCT event_date, event_timestamp, user_pseudo_id, event_name, login_rn, IF(second_event_date IS NULL, '2099-01-20', second_event_date) AS second_event_date FROM (SELECT *, LEAD(event_date) OVER (PARTITION BY user_pseudo_id ORDER BY event_date) AS second_event_date FROM base)) -- 접속 데이터 기반, 신규, 기존, 복귀, 이탈 구분 , user_type_data AS (SELECT event_date, second_event_date, user_pseudo_id, DATE_DIFF(second_event_date, event_date, DAY) AS comeback_day, CASE WHEN event_date >= DATE('2022-12-19') THEN '신규 유저' WHEN event_date >= DATE('2022-10-03') AND second_event_date <= DATE_ADD(event_date, INTERVAL 40 DAY) THEN '기존 유저' WHEN event_date >= DATE('2022-10-03') AND second_event_date > DATE_ADD(event_date, INTERVAL 40 DAY) AND second_event_date != DATE('2099-01-20') THEN '복귀 유저' WHEN event_date >= DATE('2022-10-03') AND second_event_date = DATE('2099-01-20') THEN '이탈 유저' ELSE NULL -- 예외 처리 END AS user_type FROM second_event_data) 4. 각 유저 타입별 리텐션 계산 기존 유저 -- 일자별 리텐션 계산 (기존 유저) , analysis_current AS (SELECT diff_of_day, COUNT(DISTINCT user_pseudo_id) AS user_cnt FROM (SELECT user_pseudo_id, MIN(event_date) OVER (PARTITION BY user_pseudo_id) AS first_day, event_date, comeback_day as diff_of_day FROM user_type_data WHERE user_type = '기존 유저' ORDER BY event_date, second_event_date) GROUP BY 1) SELECT diff_of_day, user_cnt, first_user_cnt, ROUND(SAFE_DIVIDE(user_cnt, first_user_cnt), 3) AS retention_day_rate FROM (SELECT diff_of_day, user_cnt, FIRST_VALUE(user_cnt) OVER (ORDER BY diff_of_day) AS first_user_cnt FROM analysis_current) 복귀 유저 신규 유저 이탈 유저 리텐션이 평평하게 안나오네요... 뭔가 단단히 잘못된것 같습니다..
안녕하세요! 좋은강의 해주셔서 감사합니다! 저는 모니터라는 개념에 대해 잘 이해를 못하다가 이번 강의를 통해 좀 알것 같기도 한데 애매한 부분이 있어서 질문드리고자 합니다~ 강의 내용을 보면 synchronized = 모니터라고 볼 수 있을 것 같은데, 41분쯤에 장표에서 나온 모니터는 lock.wait()과 lock.notify()로 구현되어있잖아요! 그런데 저는 지금까지 동기화 코드를 작성할때 Object클래스의 wait()이나 notify()함수를 사용안하고, synchronized만 사용해도 동기화가 잘 됬던것 같거든요! synchronized만 사용할때랑 자바 모니터로 구현할때랑 무엇이 다른건지 아직 좀 잘 모르겠습니다..