دانش در مقابل مهارت
کالج به ما آموخت که تفاوت زیادی بین تئوری و عمل وجود ندارد. خوب، مطمئناً متوجه شدید که این یکسان نیست. اما شما تفاوت اصلی را نمی بینید. با این حال یکی وجود دارد. اکثر مردم علامت برابری را بین «من می دانم» و «من می توانم» قرار می دهند. آیا تو؟ چند نمونه چطور؟- می دانم که سیگار برای من مضر است، اما سیگار می کشم.
- من می دانم که فست فود برای من مضر است، اما آن را می خورم.
- من قوانین راهنمایی و رانندگی را می دانم اما نمی توانم رانندگی کنم.
- می دانم که دویدن برای من خوب است اما صبح ها دویدن ندارم.
شما به سطح جدیدی رسیده اید
سطح 9
1 ریشا، ردیابی پشته
- سلام! امروز به شما خواهم گفت که stack trace چیست. اما ابتدا اجازه دهید به شما توضیح دهم که پشته چیست. - یک پشته کاغذ را تصور کنید - تکالیف برای یک منشی خاص. یک تکلیف جدید را می توان در بالای پشته قرار داد و او یک تکلیف را از بالای یک پشته می گیرد. بنابراین، تکالیف نه با اول وقت انجام می شود. هر بار که منشی تکلیف آخر را می گیرد. چنین ساختاری از مجموعه، پشته نامیده می شود . - در جاوا، یک مجموعه ویژه وجود دارد - Stack. این مجموعه دارای متدهای «افزودن عنصر» و «برداشتن (برداشتن/برداشتن) یک عنصر» است. همانطور که می دانید، آخرین عنصر اضافه شده ابتدا گرفته می شود. - هوم سخت نیست، حدس می زنم. - خوب. سپس اجازه دهید توضیح دهم stack trace چیست. - تصور کنید که در جاوا تابع А تابع B را فراخوانی می کند و دومی تابع C را که به نوبه خود تابع D را فراخوانی می کند . بنابراین، برای خروج از تابع B ، ابتدا باید از تابع C خارج شوید و برای این کار باید از تابع D خارج شوید . این بسیار شبیه به پشته است. - و شباهت چیست؟ - در پشته، برای رسیدن به یک تکلیف خاص، باید تمام تکالیفی که در بالا قرار داده شده را نیز انجام دهید. - خب، این یک جور قیاس است، اما مطمئن نیستم که همه چیز را درست متوجه شده باشم یا نه. - اینجا را نگاه کن. در جاوا یک پشته مجموعه ای از عناصر است. مانند ورق های کاغذ در یک پشته است. برای برداشتن سومی از بالا باید ورق دوم را بردارید اما قبل از آن باید اولی را بردارید. شما همیشه می توانید ورق ها را بگذارید و بردارید، اما می توانید آنها را فقط در بالا قرار دهید و فقط از بالا بگیرید. همین امر در مورد فراخوانی تابع نیز صدق می کند. تابع А تابع B را فراخوانی می کند ، دومی تابع C را فرا می خواند . برای خروج از А ابتدا باید از B خارج شوید و برای این کار باید از C خارج شوید . - یک دقیقه صبر کن. اگر درست متوجه شده باشم، کل پشته به صورت «فقط آخرین برگه ای که روی پشته قرار داده شده می تواند گرفته شود» و «اول، آخرین تابع فراخوانده شده باید خارج شود» می شود. آیا اینطور است؟ - آره. بنابراین، دنباله فراخوانی توابع «پشته فراخوانی تابع» یا به سادگی «پشته تماس» است. تابع فراخوانی آخرین باید ابتدا خاتمه یابد. بیایید به مثال نگاه کنیم: - باشه. همه چیز با فراخوانی تابع روشن است، حدس میزنم. اما این StackTraceElement چیست ؟ - ماشین مجازی جاوا همه فراخوانی های تابع را ثبت می کند. برای این منظور یک مجموعه ویژه - پشته دارد. هنگامی که یک تابع دیگری را فراخوانی می کند، JVM یک عنصر جدید StackTraceElement را قرار می دهددر این پشته هنگامی که تابع به پایان می رسد، عنصر از پشته حذف می شود. بنابراین، این پشته همیشه اطلاعات به روز در مورد وضعیت فعلی «پشته فراخوانی تابع» را ذخیره می کند. - هر StackTraceElement حاوی اطلاعاتی در مورد متد فراخوانی شده است. بنابراین می توانید نام این روش را با استفاده از getMethodName بدست آورید . - مثال بالا آن را نشان می دهد:- «پشته تماس» را دریافت کنید:
- آرایه را با استفاده از حلقه برای هر تکرار کنید . امیدوارم فراموشش نکرده باشید
- نام روش ها را در System.out چاپ کنید .
2 دیگو، نمایش وظیفه روی پشته ردیابی
- هی، آمیگو! در اینجا یک کار کوچک برای نمایش ردیابی پشته به صفحه است.وظایف | |
---|---|
1 | هر متد باید StackTrace خود را برگرداند. پنج متد بنویسید که یکدیگر را فراخوانی کنند. هر متد باید StackTrace خود را برگرداند. |
2 | StackTrace دوباره پنج روش بنویسید که یکدیگر را فراخوانی کنند. هر متد باید نام متد تماس گیرنده خود را برگرداند. با استفاده از StackTrace می توانید روش تماس گیرنده را بدست آورید. |
3 | متد باید شماره خط کدی را برگرداند که این متد از پنج متد بنویسید که یکدیگر را فراخوانی میکنند. هر متد باید شماره خط کدی را که این متد از آن فراخوانی شده است برگرداند. از تابع element.getLineNumber() استفاده کنید . |
4 | ردیابی پشته از 10 تماس کد بنویسید تا ردیابی پشته 10 تماس دریافت کنید. |
5 | متد باید یک نتیجه برگرداند - عمق ردیابی پشته آن روشی بنویسید که عمق ردیابی پشته خود را نمایش داده و برمی گرداند. عمق ردیابی پشته تعداد روش های آن (تعداد عناصر موجود در لیست) است. |
3 الی، خطاها و استثناها
- هی، آمیگو! امروز یک درس بسیار جالب داریم. من در مورد استثناها به شما خواهم گفت. استثنا مکانیزم خاصی برای کنترل خطاهای برنامه است. در اینجا چند نمونه از خطاهایی که ممکن است در برنامه رخ دهد آورده شده است:- برنامه سعی می کند یک فایل را روی دیسک کامل بنویسد.
- برنامه سعی می کند متدی از یک متغیر را فراخوانی کند که مرجع تهی را ذخیره می کند.
- برنامه سعی می کند یک عدد را بر 0 تقسیم کند.
- هنگامی که یک خطا رخ می دهد، ماشین مجازی جاوا یک شی خاص - یک استثنا - حاوی تمام اطلاعات مربوط به خطا ایجاد می کند. برای خطاهای مختلف استثناهای متفاوتی وجود دارد.
- سپس این استثنا برنامه را مجبور می کند تا عملکرد فعلی را فوراً و تابع بعدی را تا خروج از روش اصلی قطع کند. پس از آن برنامه خاتمه می یابد. توسعه دهندگان جاوا این فرآیند را «بازگرداندن پشته تماس» می نامند.
- اگر یک استثنا در داخل بلوک try رخ دهد ، کد موجود در این بلوک دیگر اجرا نمی شود، اما اجرای بلوک catch شروع می شود.
- اگر هیچ استثنایی رخ نداد، بلوک try تا انتها اجرا می شود و catch هرگز اجرا نمی شود .
4 Elly، RuntimeException، پرتاب
- امروز تصمیم گرفتم موضوع دیگری را مطرح کنم. در جاوا، همه استثناها به دو نوع کنترل شده/بررسی شده و کنترل نشده/چک نشده تقسیم می شوند . استثناهای علامتدار باید دستگیر شوند، علامتنخورده را میتوان گرفت اما این مورد الزامی نیست . - آیا می توان از روی عمد استثناها را در یک کد قرار داد؟ - در کد خود می توانید استثنائات را خودتان بیاندازید. شما حتی می توانید استثناهای خود را بنویسید. اما بعداً در این حفره عمیق خواهیم شد. حالا بیایید یاد بگیریم که چگونه با استثناهایی که ماشین مجازی جاوا پرتاب می کند کار کنیم. - خوب. - اگر استثناهای ClassNotFoundException و FileNotFoundException در یک متد پرتاب شوند (ظاهر شوند)، برنامه نویس باید آنها را در امضای یک متد (سربرگ متد) مشخص کند. چنین استثناهایی بررسی می شوند. این چیزی است که معمولاً به نظر می رسد: - بنابراین، ما فقط پرتاب ها را می نویسیم و استثناها را با کاما از هم جدا می کنیم. درست؟ آیا اینطور است؟ - آره. اما یک چیز جالب دیگر وجود دارد. برای اینکه مثال زیر کامپایل شود، متدی که متد1() را فراخوانی می کند باید این استثناها را بگیرد یا به جلو پرتاب کند. اگر میخواهید استثنای علامتدار را به جلو پرتاب کنید، باید آن را در هدر متد مشخص کنید . - یک بار دیگر، اگر در متد اصلی ، می خواهید متدی را فراخوانی کنید که در عبارت سرصفحه آن، FileNotFoundException را پرتاب می کند ، ... باید یکی از این دو کار را انجام دهید:- برای گرفتن استثناها FileNotFoundException، …
باید کدی را که در آن یک متد خطرناک را فراخوانی میکنید با یک بلوک try-catch بپیچید. - برای نگرفتن استثنائات FileNotFoundException، …
5 Risha، رول پشته تماس، نحوه انجام آن در موارد استثنا
- من می خواهم کمی بیشتر در مورد نحوه عملکرد استثناها به شما بگویم. مثال زیر توضیح می دهد که: - متوجه نشدم. - خوب. توضیح می دهم چه خبر است. - در مثال سمت چپ چندین متد را به ترتیب زنجیره فراخوانی می کنیم. در متد2() ما به طور خاص یک استثنا ایجاد و پرتاب می کنیم (برای شروع یک خطا). - مثال سمت راست نشان می دهد که چه اتفاقی می افتد. به متد2() نگاه کنید . این همان چیزی است که ایجاد یک استثنا به آن تبدیل میشود: یک شی از نوع RuntimeException ایجاد میکنیم ، آن را در یک استثنا متغیر ویژه ذخیره میکنیم و بلافاصله از متد خارج میشویم – return . - در متد 1 ، پس از فراخوانی روش2 ، بررسی می شود که آیا استثنا وجود دارد یا خیر. اگر استثنا وجود داشته باشد، متد 1 بلافاصله خاتمه می یابد. این بررسی به طور ضمنی پس از فراخوانی هر متد (!) جاوا انجام می شود. - وای! - دقیقا. - در ستون سمت راست در متد main نوشتم که وقتی یک استثنا توسط بلوک try-catch گرفته می شود چه اتفاقی می افتد . اگر هیچ استثنایی وجود نداشت، کد همانطور که برنامه ریزی شده بود به اجرای خود ادامه می دهد. اگر استثنایی از نوع مشخص شده در catch وجود داشت ، ما آن را مدیریت می کنیم. - و پرتاب و instanceof به چه معناست؟ - به آخرین خط سمت چپ نگاه کنید ، RuntimeException (های) جدید را پرتاب کنید . به این ترتیب ما یک استثنا ایجاد و پرتاب می کنیم. این فقط یک مثال است. ما تا الان این کار را نمی کنیم. - با استفاده از دستور « а instanceof B » در بلوک سمت راست بررسی می کنیم که آیا شیء a دارای نوع B است یا خیر . یعنی آیا شی ذخیره شده در متغیر استثنا دارای نوع RuntimeException است . این یک بیان منطقی است. - خوب، کمی روشن تر می شود.6 دیگو، وظیفه گرفتن استثنا
- اینجا را نگاه کن! عمو دیگو کار کمی برای گرفتن برای شما آورده است. امیدوارم موفق باشید. من فکر می کنم شما به آن نیاز خواهید داشت. هه - هی، آمیگو! در اینجا چند کار جالب استثنایی وجود دارد.گرفتن وظایف | |
---|---|
1 | 1. استثنا هنگام کار با اعداد، استثنایی را که هنگام اجرای کد رخ می دهد، بگیرید: int a = 42 / 0; استثنا را روی صفحه نمایش دهید و نوع آن را مشخص کنید |
2 | 2. استثنا هنگام کار با رشته ها استثنایی را که هنگام اجرای کد رخ می دهد، بگیرید: رشته s = null; رشته m = s.toLowerCase(); استثنا را روی صفحه نمایش دهید و نوع آن را مشخص کنید. |
3 | 3. استثنا هنگام کار با آرایه ها استثنایی را که هنگام اجرای کد رخ می دهد، بگیرید: int[] m = new int[2]; m[8] = 5; استثنا را روی صفحه نمایش دهید و نوع آن را مشخص کنید. |
4 | 4. استثنا در هنگام کار با مجموعه های لیست، استثنایی را که هنگام اجرای کد رخ می دهد، بگیرید: ArrayList<String> list = new ArrayList<String>(); رشته s = list.get(18); استثنا را روی صفحه نمایش دهید و نوع آن را مشخص کنید. |
5 | 5. استثنا هنگام کار با مجموعههای نقشه، استثنایی را که هنگام اجرای کد رخ میدهد، بگیرید: HashMap<String, String> map = new HashMap<String, String>(null); map.put(null, null); map.remove(null); استثنا را روی صفحه نمایش دهید و نوع آن را مشخص کنید. |
7 ریشا، چگونه گرفتن چندگانه کار می کند
- حالا، چند سخنرانی جالب دیگر. من خیلی دوست دارم تدریس کنم - من می خواهم به شما بگویم که یک صید چندگانه چگونه کار می کند. در واقع بسیار ساده است: وقتی یک استثنا در block try رخ می دهد ، اجرای برنامه به اولین catch منتقل می شود . - اگر نوع مشخص شده در پرانتز block catch با نوع Exception-object یکسان باشد، اجرای کد در داخل {} شروع می شود. در غیر این صورت به صید بعدی می رویم . چک در آنجا تکرار می شود. - اگر دیگر بلوک های catch وجود نداشته باشد ، اما استثنا گرفته نشده باشد، به جلو پرتاب می شود و روش فعلی قطع می شود. - می بینم. آن catch اجرا خواهد شد که نوع آن با نوع استثنا مطابقت دارد. - بله درسته. در واقع، قضیه کمی پیچیدهتر است: نکته این است که کلاسها میتوانند از یکدیگر به ارث برده شوند. اگر کلاس «گاو» از کلاس «حیوان» به ارث رسیده باشد، شیء نوع «گاو» ممکن است نه تنها در متغیری از نوع «گاو»، بلکه در متغیری از نوع «حیوان» نیز ذخیره شود. . - پس چی؟ - از آنجایی که همه استثناها از کلاس های Exception یا RuntimeException (که از Exception نیز به ارث رسیده است )، همه آنها ممکن است با استفاده از دستورات catch (Exception e) یا catch (RuntimeException e) گرفته شوند . - پس چی؟ - این بدان معنی است که ابتدا می توانید هر استثنایی را با استفاده از دستور catch (Exception e) بگیرید . دوم، ترتیب بلوک های گیر مهم است. مثالها: - استثنا حسابی حاصل از تقسیم بر 0 در دومین گیر افتاده است. - در مثال زیر، ArithmeticException در اولین catch قرار می گیرد ، زیرا کلاس های همه استثناها از Exception به ارث برده می شوند. بنابراین، Exception هر استثنایی را می گیرد . - در مثال زیر، استثنا ArithmeticException گرفته نمی شود، بلکه به سمت روش فراخوانی پرتاب می شود. -خب الان داره روشن میشه. این استثناها به این راحتی نیست. - فقط به نظر می رسد. در واقع، این یکی از ساده ترین چیزها در جاوا است. - من شک دارم که از این موضوع راضی باشم یا ناراحت…8 دیگو، وظایف چندگانه گرفتن استثنا
- هی، آمیگو! دیروز مست شدم و کارهای شما را بیش از حد پیچیده کردم، اما امیدوارم هیچ احساس سختی از جانب شما وجود نداشته باشد و همه آنها را حل کنید؟ به نفع خودته اینجا:وظایف | |
---|---|
1 | 1. استثناها روشی وجود دارد که دو استثنا به ارث رسیده از Exception و دو مورد دیگر از RuntimeException به ارث برده شده است : NullPointerException ، ArithmeticException ، FileNotFoundException ، و URISyntaxException . شما باید NullPointerException و FileNotFoundException را بگیرید ، اما نباید ArithmeticException و URISyntaxException را بگیرید . چگونه انجامش بدهیم؟ |
2 | 2. گرفتن استثناها سه استثنا وجود دارد که به طور متوالی از Exception به ارث رسیده اند : کلاس Exception1 گسترش می دهد Exception کلاس Exception2 گسترش Exception1 کلاس Exception3 گسترش Exception2 متدی وجود دارد که به شرح زیر توضیح داده شده است: public static void method1() Exception1, Exception2, Exception3 را می اندازد . بلاک کنید تا هر سه Exception1 ، Exception2 و Exception3 را بگیرید |
3 | 3. گرفتن استثناهای انتخابی 1. دریابید که چه استثناهایی با روش BEAN.methodThrowExceptions ایجاد می شوند . 2. متد processExceptions() باید متد BEAN.methodThrowExceptions را فراخوانی کند و استثناها را کنترل کند: 2.1. اگر یک استثنا رخ داد FileSystemException ، با فراخوانی متد BEAN.log آن را ثبت کرده و 2.2 را به جلو پرتاب کنید. اگر یک استثنا CharConversionException یا هر IOException دیگری رخ داد، فقط آن را با فراخوانی روش BEAN.log 3 ثبت کنید. کلاس/نوع استثنایی را که در حال ارسال آن هستید در 2.1 اضافه کنید. به امضای متد processExceptions() . 4. استثنای باقی مانده در متد main() را مدیریت کرده و آن را ثبت کنید. از try..catch استفاده کنید نکته: اگر استثنا MyException را گرفتید ، که نمیخواستید آن را بگیرید، میتوانید با استفاده از کد زیر آن را به جلو پرتاب کنید: catch (MyException e) { throw e; } |
4 | 4. گرفتن استثناهای بررسی شده همه استثناهای علامت زده شده را در متد processExceptions() مدیریت کنید . شما باید هر استثنای علامت گذاری شده ای را که رخ داده است را روی صفحه نمایش دهید. می توانید فقط از یک بلوک امتحان کنید . |
5 | 5. گرفتن استثناهای بدون علامت همه استثناهای تیک نشده را در متد processExceptions() مدیریت کنید . شما باید با استفاده از متد printStack() یک رد پشته از هر استثنا رخ داده را روی صفحه نمایش دهید . می توانید فقط از یک بلوک امتحان کنید . |
9 استاد، سخنرانی در مورد استثناها
- امروز یک موضوع فوق العاده جالب داریم - استثناها. در آن زمان، زمانی که دانشمندان و برنامه نویسان جوان عمیقاً در مورد این موضوع هیجان زده بودند ... - متاسفم، من باید به آزمایشگاه بروم. در اینجا یادداشت های سخنرانی آمده است. فکر کنم خودت بفهمی اینجا: جاوا Exceptions (Oracle Documentation) Exception Handling in Java (Java T point) Java - Exceptions Handling (نقطه آموزش) Basic Exception Handling جاوا10 جولیو
- آمیگو، نظرت در مورد درس امروز چیست؟ آیا مغز پوزیترونی شما هنوز کار نکرده است؟ وظایف دیگو برای فرسودگی هر کسی کافی است. بیایید یک لحظه آبجو بنوشیم و استراحت کنیم. هنوز ایستاده ای؟11 کاپیتان سنجاب
- سلام سرباز! - صبح بخیر آقا! - یه خبر عالی برات دارم. در اینجا یک بررسی سریع برای تقویت مهارت های شما وجود دارد. این کار را هر روز انجام دهید، و به سرعت مهارت های خود را افزایش خواهید داد. وظایف به طور ویژه برای انجام در Intellij IDEA طراحی شده اند.کارهای اضافی برای انجام در Intellij Idea | |
---|---|
1 | 1. تقسیم بر صفر یک روش public static void divisionByZero() ایجاد کنید ، جایی که باید هر عددی را بر صفر تقسیم کنید و نتیجه تقسیم را روی صفحه نمایش دهید. فراخوانی متد divisionByZero() را در یک try..catch قرار دهید . با استفاده از متد ()exception.printStackTrace ردیابی پشته استثنا را روی صفحه نمایش دهید . |
2 | 2. شمارش معکوس از 10 تا 0 یک حلقه برای شمارش معکوس از 10 تا 0 بنویسید. از Thread.sleep(100) برای ایجاد تاخیر استفاده کنید. تماس خواب را در یک امتحان بپیچید .. catch . |
3 | 3. یک روش را در یک تلاش بپیچید . اعداد را از صفحه کلید بگیرید. یک کد برای خواندن اعداد از صفحه کلید در یک متد جداگانه readData() بنویسید . کل بدنه این متد (کل کد داخل متد readData() به جز اعلام لیستی که اعداد در آن ذخیره خواهند شد) را در یک try..catch بپیچید . اگر کاربر به جای وارد کردن عدد، متنی را وارد کند، روش باید استثنا را بگیرد و تمام اعداد وارد شده را روی صفحه نمایش دهد. نمایش اعداد روی صفحه نمایش هر عدد باید در یک خط جدید باشد. ترتیب اعداد باید درست مانند ورودی باشد. |
4 | 4. مبدل تاریخ ، تاریخ را با فرمت «08/18/2013» از صفحه کلید بخوانید . از اشیاء Date و SimpleDateFormat استفاده کنید . |
5 | 5. حروف صدادار و صامت برنامه ای بنویسید که خط را از صفحه کلید بخواند. برنامه باید دو رشته را روی صفحه نمایش دهد: 1) رشته اول باید دارای حروف صدادار باشد 2) رشته دوم باید دارای حروف صامت و علامت گذاری از متن وارد شده باشد. کاراکترها را بر اساس فاصله جدا کنید. ورودی مثال: Stop look listen خروجی مثال: oooie stplklstn |
6 | 6. داستان شنل قرمزی 1. پنج طبقه وجود دارد: کلاه قرمزی، مادربزرگ، پتی، هیزم شکن، گرگ. 2. هر کلاس دارای دو فیلد از نوع ArrayList است : kill و ate. 3. اشیاء لازم از قبل ایجاد شده اند (هود، مادربزرگ، ...). 4. رابطه درستی ایجاد کنید (چه کسی خورد و چه کسی را کشت) تا منطق «کلاه قرمزی» را به دست آورید. |
7 | 7. Move static Modifies Move static Modifies Modifiers static را حرکت دهید تا کد کامپایل شود. |
8 | 8. فهرست آرایه های اعداد فهرستی ایجاد کنید که عناصر آن آرایه های اعداد باشند. پنج آرایه شی با طول 5، 2، 4، 7، 0 را به لیست اضافه کنید. آرایه ها را با هر داده پر کنید و آنها را روی صفحه نمایش دهید. |
9 | 9. ده گربه یک کلاس Cat با یک فیلد نام رشته ایجاد کنید . یک نقشه فرهنگ لغت ایجاد کنید<String, Cat> ، 10 گربه را به مدل «Name» - «Cat» اضافه کنید. مجموعه ای از نام ها را از نقشه دریافت کنید و مجموعه را روی صفحه نمایش دهید. |
وظایف پاداش | |
---|---|
1 | 1. برنامه کامپایل و اجرا نمی شود. درستش کن وظیفه: برنامه باید دو نام فایل را از روی صفحه کلید بخواند و فایل اول را در محل مشخص شده توسط نام دوم کپی کند. |
2 | 2. قابلیت جدیدی به برنامه اضافه کنید. وظیفه قدیمی: برنامه باید دو نام فایل را از روی صفحه کلید بخواند و فایل اول را در محل مشخص شده توسط نام دوم کپی کند. وظیفه جدید: برنامه باید دو نام فایل را از صفحه کلید بخواند و فایل اول را در محل مشخص شده توسط نام دوم کپی کند. اگر فایلی (که قرار است کپی شود) با نام مشخص شده وجود نداشته باشد، برنامه باید پیغام «فایل وجود ندارد» را روی صفحه نمایش دهد و سعی کند قبل از خواندن فایل، یک بار دیگر نام فایل را از کنسول بخواند. نام فایل دوم (مقصد). |
3 | 3. الگوریتم یادگیری و تمرین. لیست کلمات و اعداد را از صفحه کلید بخوانید. کلمات را به ترتیب صعودی و اعداد را به ترتیب نزولی به صفحه نمایش دهید. ورودی نمونه: گیلاس 1 لوبیا 3 سیب 2 0 هندوانه خروجی نمونه: سیب 3 لوبیا 2 گیلاس 1 0 هندوانه |
GO TO FULL VERSION