묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
9분 40초 최상위 태그질문있습니다(React.Fragment)
조건에따라 {content}를 보일지 <textarea>를 보일지 결정하는코드를 작성한고있는데 궁금한게 <textarea>랑 {content}두곳에 React.Fragment를 붙여야한다해서 <></>를 넣는다고알고있습니다 근데 최상위태그의경우 <div className='content'>가 될수있다고생각해서 <></>를 없애고 그냥 <textarea> , {content}만 넣었을때 에러가뜹니다… 왜 그런가요?
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
질문드립니다
아 혹시 선생님의 비전공자를 위한 진짜 입문 올인원 개발 클래스 수업을 듣고 있는데 혹시 해당 수업 내용을 가지고 블로그를 작성해도 괜찮을까요?
-
미해결오늘부터 개발자 - 개발자를 준비하기 전 꼭 알아야 할 것
포트폴리오는 어떤형식을 작성하셨는지 여쭤봐도 될까요
포트폴리오에 대한 구체적인 개념이 안잡히다 보니 어떻게 작성해야할지 감이 안잡혀서요... 유튜브에 봐도 거의 대부분 달라서 뭘 해야할지도 모르겠고 포트폴리오에 대한 구체적요소들을 잘 모르다 보니 막막하네요... 혹시 어떤 형식으로 작성하셨는지 구체적으로 알수 있을까요? ...ㅠㅜ
-
해결됨10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
3-O 질문 있습니다.
강의에서 나오는 풀이와 몇가지 차이가 있긴 하지만 - 인덱스를 100*H +N으로 구한다는 점 - 사다리를 12로 놓는다는 점 이 차이가 있는것 같다고 생각했습니다. 강사님 풀이 중 다음 부분에서 궁금한 점이 있습니다. H를 사다리라고 한다면 Hㅁㅁㅁㅁㅁ 를 탐색하고 난 이후에 for (int j = 1; j <= n; j++)부분으로 인해서 첫번째 공간에 사다리를 또 놓게되는 중복이 발생하지는 않는지 궁금합니다. 예를들어 처음에 Hㅁㅁ 인상태로 go를 하면 HㅁH를 탐색하고 첫번째 인덱스를 0으로 바꾼후 ㅁHㅁ 탐색 그 이후 ㅁㅁH 케이스에서 다시 HㅁH 가 발생하지 않는지 궁금합니다. 또한 저의 풀이는 계속 9%에서 시간초과가 발생하는데 그 이유가 궁금합니다. for (int i = here; i <= h; i++) { for (int j = 1; j <= n; j++) { if (visited[i][j] || visited[i][j - 1] || visited[i][j + 1]) continue; visited[i][j] = 1; go(i, cnt + 1); visited[i][j] = 0; } } #include <bits/stdc++.h> using namespace std; int N, M, H; int arr[34][12]; int res = 5; bool simul() { for (int i = 1; i <= N; i++) { int depth = 0; int idx = i; while (depth <= H) { int point = arr[depth][idx]; if (point == 1) idx++; else if (point == 2) idx--; depth++; } if (idx != i) return false; } return true; } void dfs(int hn, int level) { if (level >= res || level > 3) return; cout << hn << endl; int h = hn / 100; int n = hn % 100; if (hn == H * 100 + N) { if (simul()) { res = min(level, res); } return; } int nh = n < N ? h : h + 1; int nn = n < N ? n + 1 : 1; dfs(nh * 100 + nn, level); if (n < N && !arr[h][n] && !arr[h][n + 1]) { arr[h][n] = 1, arr[h][n + 1] = 2; dfs(nh * 100 + nn, level + 1); arr[h][n] = 0, arr[h][n + 1] = 0; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> N >> M >> H; for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; arr[x][y] = 1; arr[x][y + 1] = 2; } dfs(101, 0); if (res == 5) cout << -1; else cout << res; return 0; }
-
미해결배달앱 클론코딩 [with React Native]
useEffect , interceptor 질문입니다!
선생님 안녕하세요, AppInner.tsx 코드에서 interceptor 부분 중 질문있습니다. useEffect 에 의존값이 없으면 최초 렌더링시에만 호출되는 걸로 알고 있는데요. dispatch는 정적객체라 안적어도 상관없다고? 하셔서 없는것과 마찬가지로 생각했습니다. 그럼 interceptor가 포함된 useEffect 코드는 최초 렌더링만 된다고 이해가 되는데요. 그럼 여기서 궁금한건 요 두가지 경우예요. 인터셉터는 419 에러가 뜰때마다 호출되어야해서 최초렌더링만 되어선 안된다 (?) 최초 렌더링 때 인터셉터가 만들어져 대기하고 있고, 419 에러때 마다 인터셉터가 가로챈다. 1, 2번중 어떤걸로 이해해야 할까요? 아니면 둘다 틀린건지 궁금합니다. // 앱 실행 시 토큰 있으면 로그인하는 코드 useEffect(() => { const getTokenAndRefresh = async () => { try { const token = await EncryptedStorage.getItem('refreshToken'); if (!token) { return; } const response = await axios.post( `${Config.API_URL}/refreshToken`, {}, { headers: { authorization: `Bearer ${token}`, }, }, ); dispatch( userSlice.actions.setUser({ name: response.data.data.name, email: response.data.data.email, accessToken: response.data.data.accessToken, }), ); } catch (error) { console.error(error); if ((error as AxiosError).response?.data.code === 'expired') { Alert.alert('알림', '다시 로그인 해주세요.'); } } }; getTokenAndRefresh(); }, [dispatch]);
-
미해결장고 설계철학으로 시작하는 파이썬 장고 입문
장고에서의 비즈니스로직 관리에 대하여 (서비스)
안녕하세요 강사님. 스프링과 장고의 샘플코드 비교해주신 부분에서 질문이 있어서 남겨봅니다. 샘플코드를 보았을 때, 장고 코드에서는 뷰에서만 서비스의 일부 기능을 담당한다고 되어있는데요. 만약 비즈니스 로직이 커질 경우, 서비스와 컨트롤러가 나뉘어져있는 스프링쪽이 좀더 관리가 용이할 수 있을거 같다는 생각이 들었습니다. 비즈니스 로직이 비대해졌을 때 장고에서는 일반적으로 이 코드를 어디서 관리하는지 질문 드리고 싶습니다. 기존의 컨트롤러와 엔티티로서의 기능을 담당하고 있는 View와 Model로 분산해서 로직을 작성하게 될까요?? 아니면 별도로 service.py같은 파일을 생성해서 관리를 하는게 좋을까요? 강사님 의견이 궁금합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
3분 40초 이후 localhost:8080/hello의 Whitelabel Error Page
[질문 내용]안녕하세요, 3분 40초이후 localhost:8080/hello에 접속해도 제대로 작동하지 않는 현상때문에 질문 드립니다. 강의와 똑같이 진행 후, localhost:8080/hello로 접속하여도 Console 창에 아무 반응도 오지 않고, 웹페이지도 Whitelabel Error Page가 계속 뜹니다. super 메서드도 지웠고, 인텔리제이를 껏다가 다시 켜보고, 클래스를 재생성하여 진행해봐도 같습니다. ㅠㅠ 어디가 잘못됐는지 알려주시면 감사하겠습니다! 아래는 생성한 HelloServlet 클래스와 service 함수입니다. package hello.servlet.basic; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "helloServlet", urlPatterns = "/hello") public class HelloServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("HelloServlet.service"); } } 아래는 서버를 띄운 후, localhost:8080/hello 접속했을 때의 페이지입니다.
-
미해결[D.P.(DappProject)] 디앱 프로젝트(NFT 생성, NFT 구매 및 판매)
fromWei 질문
안녕하세요! dapp프로젝트 1,2를 수강했던 학생입니다. 약간 강의 외의 질문이 될 수도 있겠지만... 혼자 계속해서 dapp 관련 공부를 하다가 BigNumber라는 라이브러리를 알게되었는데 이 강의를 수강할때는 fromWei를 활용했던것같아서 이에대해 궁금한점이 생겨 질문을 작성하게 되었습니다. BigNumber를 사용했을 때와 fromWei toWei와 같은 메서드를 사용했을때 차이점과 둘중 하나를사용한다면 어떤 상황에 BigNumber를 쓰고 fromWei, toWei를 사용하는지 궁금합니다!
-
미해결홍정모의 따라하며 배우는 C++
6-4 선택정렬
6-4 선택정렬 10분 11초 부근에서 직접 해보라고 하셔서 강의를 보기전 직접 해보았습니다. 그리고 성공비슷하게 했으나 뭔가 이상해서 질의를 드려봅니다. 알고리즘은 사진의 윗부분 주석과 같이 순차적으로 정렬되어야함이 맞으나, 제가 짠 코드에서는 콘솔창과 같이 정렬이 되네요. 뭔가 중간 단계가 건너뛰고 최종결과가 나오는 것처럼요. 하지만 배열사이즈를 바꿔보고 숫자를 늘려봐도 최종결과는 오름차순으로 정확하게 정렬이 됩니다. 이러면 맞다고 봐야하는 걸까요?
-
미해결[초급편] 안드로이드 커뮤니티 앱 만들기(Android Kotlin)
회원가입 시 자꾸 '실패'만 뜹니다.
항상 강의 잘 듣고 있습니다. 회원가입 부분을 구현하는 중, 다 맞게 입력했는데 자꾸 '실패'라고 뜨는 현상을 맞이하여 질문드립니다. authentication에서 이메일/비밀번호까지 수정을 다 했는데, 어떻게 된 건지 궁금합니다. 혹시 강의 자료 중에 소스 코드가 어디에 위치해 있는지 알려주실 수 있으신가요? 다른 오류가 생기면 그걸 먼저 찾아보겠습니다. 아래는 코드입니다. package koreatraveltipsintroimport android.content.ContentValues.TAGimport android.content.Intentimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.util.Logimport android.widget.Toastimport androidx.databinding.DataBindingUtilimport com.example.koreatraveltips.MainActivityimport com.example.koreatraveltips.Rimport com.example.koreatraveltips.databinding.ActivityJoinactivityBindingimport com.google.firebase.auth.FirebaseAuthimport com.google.firebase.auth.ktx.authimport com.google.firebase.ktx.Firebaseclass joinactivity : AppCompatActivity() { private lateinit var auth : FirebaseAuth private lateinit var binding : ActivityJoinactivityBinding //이와 관해서 오류가 날 수도 있는데, 당황하지 말고 문제의 원인을 구글링해서 문제를 해결하자.//gradle에 id 'kotlin-android-extensions'을 추가해 주면 된다. override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_joinactivity) auth= Firebase.auth binding = DataBindingUtil.setContentView(this, R.layout.activity_joinactivity)//해당 레이아웃 파일의 부분의 데이터를 바인딩 하겠다는 코드이다. binding.joining.setOnClickListener {//윗줄의 코드는 '회원가입하기'라는 버튼을 누르면 어떻게 되는지에 대해 구현하는 코드라는 의미이다. //회원 가입 버튼을 클릭을 하면, 위의 정보들을 가져 오겠다는 의미이다. //변수를 하나 만들고, 디폴트 값을 true라고 정한다. //그리고, 아래의 조건들에 걸리면, 값을 false로 바꾸는 것이다. var isTrue = true val email = binding.email.text.toString() val password = binding.password.text.toString() val passwordcheck = binding.passwordcheck1.text.toString() //저기 값이 비어 있는지 확인한다. if(email.isEmpty()) //만약 이메일 값이 비어 있다면 {//아래와 같은 값을 띄운다. Toast.makeText(this,"이메일을 입력해주세요.",Toast.LENGTH_LONG).show() isTrue = false } if(password.isEmpty()) //password가 비어도 마찬가지. { Toast.makeText(this,"password1을 입력하시오.",Toast.LENGTH_LONG).show() isTrue = false } if(passwordcheck.isEmpty()) { Toast.makeText(this,"password2를 입력하시오.",Toast.LENGTH_LONG).show() isTrue = false } //비밀번호가 서로 다르다면 비밀번호를 같게 입력해달라고 메시지를 띄운다. if(!password.equals(passwordcheck)) { Toast.makeText(this,"비밀번호를 똑같이 입력하시오",Toast.LENGTH_LONG).show() isTrue = false } //비밀번호의 길이를 확인 if(password.length < 6) { Toast.makeText(this,"비밀번호를 6자리 이상으로 입력해주세요.",Toast.LENGTH_LONG).show() isTrue = false } //만약 위의 필터링을 모두 통과했다면, 아래의 것들을 실행시켜보자. if(isTrue==true) { auth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(this) { task -> if (task.isSuccessful) { // Sign in success, update UI with the signed-in user's information Toast.makeText(this,"성공",Toast.LENGTH_LONG).show() //회원가입이 성공적으로 끝이 난다면, mainactivity로 이동한다. val intent = Intent(this, MainActivity::class.java) startActivity(intent) //그런데, 이렇게만 코드를 짜면, 뒤로가기로 앱을 끌 경우 //회원가입 페이지가 나와버리는 결과가 발생한다. //그래서 코드를 더 짠다. } else { // If sign in fails, display a message to the user. Toast.makeText(this,"실패",Toast.LENGTH_LONG).show() Log.e(TAG, "createUserWithEmail:failure", task.exception) } } } }아래는 오류 화면 캡쳐입니다. 감사합니다.
-
미해결Redux vs MobX (둘 다 배우자!)
리덕스 툴킷 과 saga질문
안녕하세요. 제로초님 빠른 답변 항상 감사드립니다. 툴킷과 saga 활용에 대해 질문 드리려고 합니다. 1. 요즘에 거의 툴킷만 실무에서 사용한다고 들었는데,빠르게 리덕스부분 익히고 노드버드로 넘어가려해서 툴킷과 mobx까지만 듣고 saga는 건너뛰어도 실제 업무 및 노드버드 듣는데 문제 없나요? 2. 노드버드는 툴킷을 사용하지 않는데, 노드버드에서 saga 부분을 듣지 않아도 그 부분을 쉽게 툴킷으로 변환가능한가요?
-
미해결Vue.js 완벽 가이드 - 실습과 리팩토링으로 배우는 실전 개념
권한 요청드립니다.
인프런 아이디 : semomuri 인프런 이메일 : semomuri@gmail.com 깃헙 아이디 : semomuri@gmail.com 깃헙 Username : semomuri
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
프로젝트 열기
앞으로 프로젝트를 열 때마다 항상 build.gradle을 통해서 열면 되는 건가요? 그냥 프로젝트 폴더를 open 하는 것과는 어떤 차이가 있나요?
-
해결됨Flutter 앱 개발 기초
파이어베이스 Auth에러
import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'auth_service.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // main 함수에서 async 사용하기 위함 await Firebase.initializeApp(); // firebase 앱 시작 runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => AuthService()), ], child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: LoginPage(), ); } } /// 로그인 페이지 class LoginPage extends StatefulWidget { const LoginPage({Key? key}) : super(key: key); @override State<LoginPage> createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { TextEditingController emailController = TextEditingController(); TextEditingController passwordController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("로그인")), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ /// 현재 유저 로그인 상태 Center( child: Text( "로그인해 주세요 🙂", style: TextStyle( fontSize: 24, ), ), ), SizedBox(height: 32), /// 이메일 TextField( controller: emailController, decoration: InputDecoration(hintText: "이메일"), ), /// 비밀번호 TextField( controller: passwordController, obscureText: false, // 비밀번호 안보이게 decoration: InputDecoration(hintText: "비밀번호"), ), SizedBox(height: 32), /// 로그인 버튼 ElevatedButton( child: Text("로그인", style: TextStyle(fontSize: 21)), onPressed: () { // 로그인 성공시 HomePage로 이동 Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => HomePage()), ); }, ), /// 회원가입 버튼 ElevatedButton( child: Text("회원가입", style: TextStyle(fontSize: 21)), onPressed: () { // 회원가입 print("sign up"); }, ), ], ), ), ); } } /// 홈페이지 class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { TextEditingController jobController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("버킷 리스트"), actions: [ TextButton( child: Text( "로그아웃", style: TextStyle( color: Colors.white, ), ), onPressed: () { print("sign out"); // 로그인 페이지로 이동 Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => LoginPage()), ); }, ), ], ), body: Column( children: [ /// 입력창 Padding( padding: const EdgeInsets.all(8), child: Row( children: [ /// 텍스트 입력창 Expanded( child: TextField( controller: jobController, decoration: InputDecoration( hintText: "하고 싶은 일을 입력해주세요.", ), ), ), /// 추가 버튼 ElevatedButton( child: Icon(Icons.add), onPressed: () { // create bucket if (jobController.text.isNotEmpty) { print("create bucket"); } }, ), ], ), ), Divider(height: 1), /// 버킷 리스트 Expanded( child: ListView.builder( itemCount: 5, itemBuilder: (context, index) { String job = "$index"; bool isDone = false; return ListTile( title: Text( job, style: TextStyle( fontSize: 24, color: isDone ? Colors.grey : Colors.black, decoration: isDone ? TextDecoration.lineThrough : TextDecoration.none, ), ), // 삭제 아이콘 버튼 trailing: IconButton( icon: Icon(CupertinoIcons.delete), onPressed: () { // 삭제 버튼 클릭시 }, ), onTap: () { // 아이템 클릭하여 isDone 업데이트 }, ); }, ), ), ], ), ); } }
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
오류 발생 후 지속적 alert 발생 방지를 위해 error 상태 초기화 코드 작성 후 오류 질문 드립니다.
안녕하세요 아래 리렌더링 시 지속적으로 alert발생으로 인해 error 후 초기화 코드를 작성을 했습니다. 하지만, 제가 상태를 바꿔주지 않은 속성도 바뀌는 현상이 있습니다. 코드는 아래와 같습니다. 스위치 문 내에서는 상태의 변경이 없으나, 리덕스 데브툴에서는 아래처럼 제가 설정하지 않은 loginLoading 값이 변경되어 나옵니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
쓰레드 풀 관련 질문 드립니다.
쓰레드 풀 관련해서 질문드립니다.강의 예제에서 HTTP 요청이 들어온경우 연결 이후 쓰레드 풀에서 쓰레드를 할당해주는 것 이라고 이해했는데. 문득 이런 궁금점이 들었습니다.요청이 들어왔을 때 '연결'을하고, 이에 대한 '응답' 을 하는 것도 쓰레드가 해줘야 하는 일이 아닌가요? 프로세스의 가장 작은 단위 이기 때문에 이런 '연결' 과 '응답'도 쓰레드가 결국해줘야 한다고 생각했습니다 그렇다면 이런 연결과 응답을 책임지는 쓰레드도 톰캣 내부에 있는 (쓰레드 풀)에 있는 쓰레드를 쓰는건가요..?
-
미해결Vue.js 시작하기 - Age of Vue.js
vue 설치후에 vue --version 실행 시 아래와 같은 메시지가 뜹니다.
https://www.inflearn.com/questions/409418 질문자분이랑 같은 이슈가 발생해서 질문글 올립니다. 선생님께서 답변해주신, cmder 에뮬레이터(http://cmder.net/) 다운 받으려고 해당 사이트 방문하니 expired 되었다고 뜹니다 ㅜㅜ 송태양님과 동일한 이슈 입니다. vue 설치까지는 되는데, vue --version으로 확인하려고 하면 cmd에서는 'vue'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다. VS Code내에서는 아래처럼 메시지가 발생합니다. 혹시 또 다른 해결방법이 있을지 문의드립니다. 강의에서 쓰는 버전으로도 해보고, 최신 버전으로도 설치해봐도 동일하네요.ㅜㅜ 구글링 하면서 하루종일 이것저것 해봐도 해결이 되지 않아 여쭤봅니다. (시스템 변수(path)설정.. vue버전, node버전 확인 등등) 확인부탁드립니다.
-
미해결[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
Train시에 GT데이터들의 Annotation이 어떻게 각 피처맵을 거친 값들에 적용되는지 궁금합니다!
안녕하세요 무더위 건강 잘 챙기시길 바랍니다. 저는 직접 깃허브에 있는 코드로 구현 하고 있는 중입니다만 512*512를 인풋으로 넣어서 Neck까지 통과한 결과 P3, P4, P5, P6, P7이 각각 (1, 128, 128, 64) (1, 64, 64, 64) (1, 32, 32, 64) (1, 16, 16, 64) (1, 8, 8, 64)로 나왔고 각 셀에 9개 앵커박스를 할당해 boxnet을 통과시켜 concat하면 128*128*9 +64*64*9 +32*32*9 + 16*16*9 +8*8*9 = 196,416 (1, 196416, 4) 의 결과값을 얻었는데 서론이 너무 길었네요ㅜㅜ Train시에 원본 이미지와 그에 따른 Annotation 파일에 BBox의 x, y, w, h 좌표가 있을 때 이 데이터가 피처맵들에 맞는 데이터로 변환이 되어서(?) 위에서 구한 결과값과 어떻게 비교가 되어서 학습이 될지 궁금합니다. 직관적인 제 생각으로는 만약 원본 이미지에 (10,10) 좌표에 바운딩박스가 있다면 반으로 줄인 피처맵에는 대략적으로 (5,5) 좌표에 박스가 위치하지 않을까 하는데 맞는지 궁금합니다 혹시 https://github.com/xuannianz/EfficientDet/tree/030fb7e10ab69a297c7723120c2d1be856a852c0 여기 코드에 그런 내용이 있다면 언급해주시면 정말 감사하겠습니다! 바쁘실텐데 귀찮게 해드려서 죄송합니다만 답변 부탁드립니다
-
미해결지금 바로 React 시작하기
정답안에 압축파일안에 컴포넌트 이름이 잘못 된 것 같습니다.
정답 코드 압축풀고, 컴포넌트 열어서 StockCounter봤는데, 함수형 컴포넌트 명시가 GoodsCounter로 되어있고 export default 도 그렇게 되어있네용
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
하이버네이트에 관한 질문이있습니다!
하이버네이트가 JPA의 구현체라는 것은 알고있습니다. 그러면 강의 중에도 등장하는 영속성 컨텍스트, EntityManager 같은 개념들도 다 하이버네이트가 구현해놓은 것인지 궁금합니다! 감사합니다.