Як переглянути власний код? [зачинено]


177

Я працюю над сольним проектом і маю підтримувати власний код. Зазвичай перевірку коду проводить не автор коду, тому рецензент може дивитися на код свіжими очима - однак, у мене немає такої розкоші. Які практики я можу використовувати для більш ефективного перегляду власного коду?


34
Я не впевнений, що ви можете, принаймні, не ефективно - ви можете зібрати джерело оглядової команди на codereview.stackexchange.com, якщо ваш код не є власником
jk.

8
Ви не можете переглянути власний код. Якщо ви не можете знайти інших людей, я вважаю найкращим, що ви можете зробити, щоб використовувати стільки статичних аналізаторів, на які ви можете взяти ваші руки, і включити ВСІ попередження.

136
Переглянути власний код легко. Напишіть фрагмент коду. Відстаньте на 2 тижні / місяці / роки, продовжуючи вивчати та розробляти інше програмне забезпечення. Поверніться до цього фрагменту і спробуйте зрозуміти, що робить код. Ви знаєте, що дізналися щось, коли думаєте: "який ідіот написав це ?!".
Юрій Зубарев

6
@YuriyZubarev Але що робити, якщо ви не хочете чекати тижні / місяць / роки?
anatoliiG

12
Ви можете переглянути свій код у зміненому стані розуму. Або ви можете кодувати в зміненому стані розуму і делегувати огляд коду своєму звичайному нудному самому.
SK-логіка

Відповіді:


92

Перш за все, скористайтеся інструментами, щоб перевірити, наскільки це можливо. Тести (підкріплені певним розумним покриттям коду) дадуть вам певну впевненість у правильності коду. Засоби статистичного аналізу дозволяють отримати багато речей з найкращих практик. Завжди будуть проблеми, які потребують людських очей, щоб визначити, і ви ніколи не зробите так гарну роботу, переглядаючи свої речі, як хтось інший, є деякі речі, які ви можете зробити, щоб допомогти, однак

  • перевірочні тести існують і проходять (можливо, мають цільове покриття тесту, хоча вам може знадобитися порушити це в певних випадках, але ви повинні мати можливість обґрунтувати, чому)
  • перевірити Статичний аналіз проходить (тут також буде помилкових негативів, але це добре, якщо ви можете виправдати, чому тоді його штрафом придушити їх)
  • підтримуйте контрольний список подальших речей, які слід перевірити (в ідеалі додайте це як нові правила статичного аналізу, якщо це можливо), переконайтесь, що ви перевіряєте все, що SA не може перевірити, наприклад, чи залишаються коментарі все-таки дійсними, чи є речі названі належним чином (називання речей - це звичайно, одна з 2 важких проблем, відомих інформатиці)
  • якщо виявлена ​​несправність, перевірте, чи причина є системною, і подивіться, чому її не було знайдено в попередніх тестах чи оглядах

Це, звичайно, корисно і при перегляді інших кодів


3
Щодо контрольного списку, мати специфікацію дуже корисно.
Вейн Вернер

Я не люблю контрольні списки. Вони змушують рецензента зосередитися на контрольному списку, а не думати про проблему, рішення та багато іншого. Тому я пропоную зробити їх мінімальними.
Балог Пал

57

Загляньте на сайт Code Review Stack Exchange. Це для обміну кодом з проектів, над якими ви працюєте для експертної оцінки :

Exchange Review Stack Exchange - це сайт із запитаннями та відповідями для пошуку експертної оцінки вашого коду. Ми працюємо разом, щоб вдосконалити навички програмістів у всьому світі, приймаючи робочий код і вдосконалюючи його.

Якщо ви шукаєте відгуки щодо конкретного робочого коду вашого проекту в наступних областях ...

  • Кращі практики та використання моделей дизайну
  • Питання безпеки
  • Продуктивність
  • Коректність у непередбачених випадках

Ви також можете використовувати інструменти статичного аналізу коду для виявлення певних проблем, але вони в деяких випадках створюють помилкові сигнали тривоги, і не можуть підказати, як вдосконалити дизайн.


2
Це відмінна відповідь на запитання "Як переглянути свій код" та хороша порада взагалі (я обов'язково це зроблю) - але все ж трохи офтопік.
Макс Янков

5
Я, як правило, не люблю відповідь на 5 слів, але ця така правда .
maple_shaft

20
У кращому випадку це лише обмежене рішення. Постійно виставляти весь свій щоденний вихід на CR.SE не представляється можливим, оскільки великі штрихи це буде досить повним кодом котла. CR.SE також не допоможе у вирішенні проблем, які потребують нетривіального розуміння всієї архітектури додатків або домену, для якого написано додаток. З неофіційного погляду на код колег, коли він перевіряється в стилі, огляди, де я працюю подібні помилки, ймовірно, є більш поширеними, ніж ті, які були б придатні для лову через CR.SE.
Ден Нелі

3
Справжня цінність при перегляді - отримання фрагментів коду, які ви ніколи не представляли б будь-яку проблему, помічену та виділену як не очевидну, не пояснюючу себе або навіть нелогічно правильну . Ви не можете опублікувати фрагмент, code reviewякщо ви ще не знаєте, що це проблематично.
ZJR

3
@ ZJR Що ж, на 100% переглядається код у ваших проектах? Якщо так, ваші інженери мають занадто багато вільного часу. Щодо вашого другого коментаря, я не бачу проблем із запитом перегляду коду в коді, який ви вважаєте ідеальним.
BЈоviћ

29

Я розвинув у голові кілька абсолютно різних людей. Один із них навіть не програміст! Ми спілкуємося в чаті, обговорюємо останні новини та переглядаємо код один одного.

Я настійно рекомендую свій підхід.

ps Він не жартує.


27
Мене звуть Білл, Джефф, Боб і Еліс, і ми схвалюємо це повідомлення.
Майкл К

22

Я погоджуюся з думкою jk-s, що огляд на одну особу не настільки ефективний, як огляд на 2 особи. проте ви можете спробувати зробити все найкраще:

короткотерміновий огляд (незабаром після створення коду)

Я використовую git як локальне сховище. Щоразу, коли я закінчую функцію або виправляю помилку, я передаю зміни до сховища.

Перш ніж зареєструватися, я порівнюю, що я змінив у своєму коді, і переосмислив:

  • чи змінює назву змінної / методу / класів, для чого вони використовуються?

довгостроковий огляд (6 місяців після створення коду)

Я запитую себе:

  • чи можу я в одному сенсі описати, що робить клас / метод / змінна?
  • наскільки легко використовувати клас ізольовано (без інших класів) або написати єдиний тест?

4
+1 для короткострокової пропозиції щодо перегляду. Використання git для перегляду всіх змін між різними моментами дійсно може допомогти очистити код.
Лев

Мені спокійно подобається ідея довготермінового перегляду, я думаю, що, мабуть, я б поєднав її в загальний огляд проектного миття, хоча і, можливо, не переглядав увесь код (тоді, знову ж таки, я не прагну багато займатися сольною розробкою)
jk.

Я намагаюся зробити щось середнє: переглянути свій код приблизно через місяць. Мені також подобається 6-місячний огляд.
Девід Г

18

По-перше, відкладіть свій код настільки довго, наскільки це практично. Робота над чимось іншим, якимось іншим фрагментом коду. Навіть через день ви будете вражені тим, що знайдете.

По-друге, документуйте свій код. Багато програмістів ненавидять документувати свій код, але змушують сідати і виписувати документацію, як використовувати код і як він працює. Дивлячись на ваш код по-іншому, ви виявите помилки.

Кажуть, що справжнє оволодіння предметом - це здатність навчити його комусь іншому. За допомогою документації ви намагаєтесь навчити когось іншого своєму коду.


15

Перетворіть цю техніку налагодження в техніку перегляду коду: http://en.wikipedia.org/wiki/Rubber_duck_debugging

Концепція творить чудеса для того, щоб ввести вас у правильний спосіб мислення для роботи з кодом, як ніби він новий.


3
Я вважаю, що техніка качок була самостійно винайдена на кількох ділянках; ось чудова історія про це: hwrnmnbsol.livejournal.com/148664.html
Рассел Борогов

10
У наші дні моя гумова качка - це форма запиту на запитання Stack Exchange. Бажання написати гарне запитання робить трюк.
Кевін Рейд

Відмінна порада. Це ще краще, оскільки у мене на столі вже є гумова качка (вона була тут як модель для одного з моїх ігрових персонажів, але, мабуть, це не буде проти додаткової роботи ІТ-консультанта).
Макс Янков

5
@KevinReid, я люблю , щоб побачити деякі статистичні дані про покинутих повідомленнях SE - особливо ті , які люди друкували довше , ніж 60 - ї року на. Я знаю, що я робив те саме, щонайменше 5 разів.
Вейн Вернер

Ва! Я не знав, що це "річ". Я просто прокоментував вище, що мій професор-професор рекомендував це під час нашої першої в історії лекції десятиліття тому. Він порекомендував кота, але я вважаю, що каучукова качка зробить це.
Однозначно

13

На додаток до корисних інструментів, згаданих в інших відповідях, я думаю, що змінити ваш розум на користь під час перегляду коду. Дурне, але я кажу собі: "Я надягаю шапку для перегляду коду". Я роблю те саме з QA.

Тоді важливо обмежитися цим мисленням. Ви або рецензент, або рецензент, ви не можете бути обома одночасно. Тож як рецензент я беру об’єктивні записки, щоб поділитися з рецензентом. Я не змінюю код під час перегляду, це не те, що повинен робити рецензент.

Формальність часом здається трохи абсурдною, але під час роботи соло я виявляю, що мене часто тягнуть у багатьох напрямках. Тому я не обов'язково закриваю цикл огляду, перш ніж з'явиться щось інше - ця формальність (і справді я кажу грубі нотатки у вікі-інструменті) корисна для того, щоб переконатися, що огляд буде виконаний. Так само, як у моєму капелюсі QA, я додаю квитки на помилки, перш ніж їх виправити.


Я не думаю, що можна переглянути власний код
BЈович

4
@VJovic - Я не думаю, що я виконую найкращий перегляд коду свого коду, але я зазвичай знаходжу речі, які можна вдосконалити. Я також читав багато чужих кодів. Моя точка зору на те, як виглядає "хороший" код, постійно змінюється. Мене бентежить код, який я писав років тому. Це не відрізняється від доказування власної статті - це вимагає практики та набагато більше зусиль, але це можливо. Ключове, що я не можу переглянути, - це те, якщо абстракція має сенс для когось іншого. Але я можу запитати себе, як зробити щось простіше, чи це потрібно і т. Д.
Стів Джексон

@VJovic - Як згадував ThomasOwens, ви також можете створити контрольний список з попередніх помилок і пройти через це досить об'єктивно. Це інша приємна річ у тому, що це офіційно, ви можете побачити, що ви пропустили під час огляду, і відповідно налаштувати процес. Я вважаю, що я вивчаю багато уроків, відстежуючи себе і докладаючи зусиль, щоб змінити свій підхід, коли це вказано.
Стів Джексон

3
Налаштування правильного мислення - це дуже важливо. Я вважаю, що це допомагає, якщо я дійсно роздрукую код і переходжу його на папері маркером. Тоді я не можу нічого змінити під час перегляду (що заважає мені перейти в режим кодування) і можу легко писати коментарі та стрілки руху на папері.
Лев

Це означає перегляд старого коду, а не нового коду. Для цього вам потрібно набути досвіду, який може зайняти багато часу.
BЈовић

9

Здається, загальним є те, що самоперевірка не є ефективною. Я не згоден, і я думаю, що самоаналіз може вирішити багато питань, якщо зробити їх ретельно.

Ось поради з мого кількарічного досвіду:

  • Попросіть грубний контрольний список. Це речі, які ви хочете позначити, читаючи код.
  • Пройдіть огляд свого коду в автономному режимі. Це може здатися марним, але візьміть роздруківки, які можна коментувати та перевертати назад, або цифровий еквівалент добре виділених файлів pdfs, синхронізованих на iPad, який потім знімається в автономному режимі. Відійдіть від свого робочого столу, щоб все, що ви робите, переглядати код, який не відволікається.
  • Робіть це рано вранці, а не наприкінці робочого дня. Свіжа пара очей краще. Насправді це може допомогти відійти від коду за добу, перш ніж переглянути його знову.

Просто FYI - ці вказівки були частиною рекомендацій в Oracle кілька років тому, коли я працював там, де метою було зловити помилок "вище за течією", перш ніж код вийшов на тестування. Це дуже допомогло, хоча багато розробників вважалося нудною роботою.


3
Я також додав "зачекайте 24 години", щоб ви не дивилися на написаний вами код. Переконайтесь, що він принаймні 1 день, щоб ви бачили його після сну протягом ночі, а не торкалися до нього протягом 24 повних годин.
Джефф Етвуд

Я часто використовую роздруківки, коли мені потрібно переглянути або особливо перефактурувати якийсь код. Це творить чудеса для мене.
yitznewton

Як і в якомусь фільмі, ми дізналися з ГБ, що фальшивий оргазм краще, ніж оргазм - самоперегляд краще, ніж нічого. Так, ви можете навчитися багато займатися гумовою обробкою. Але це все ще досить неефективно в порівнянні з фактичною експертною оцінкою. особливо не піддаючись деяким реальним рецензентам протягом певного часу, щоб підбирати методи.
Балог Пал

8

Техніка персонального програмного забезпечення для оглядів може бути корисною, хоча вона покладається на наявність історичних даних про вашу роботу та якість продукції.

Ви починаєте з історичних даних про робочі вироби, зокрема про кількість та типи дефектів. Існують різні методи класифікації дефектів, такі як цей з курсу PSP . Ви можете розробити власну, але ідея полягає в тому, що вам потрібно вміти розповідати, які помилки ви робите на цьому шляху.

Коли ви дізнаєтесь, які помилки ви робите, ви можете розробити контрольний список, який ви можете використовувати під час огляду. Цей контрольний список охоплює основні помилки, які ви робите, і, на вашу думку, найкраще потрапити в огляд (на відміну від використання іншого інструменту). Кожен раз, коли ви переглядаєте робочий продукт, використовуйте контрольний список і шукайте ці помилки або помилки, документуйте їх і виправляйте. Періодично переглядайте цей контрольний список час від часу, щоб переконатися, що ви зосереджуєтесь на справжніх відповідних проблемах у вашому коді.

Я також рекомендую використовувати підтримку інструментів, коли це має сенс. Засоби статистичного аналізу можуть допомогти знайти деякі дефекти, а деякі навіть перевірити стиль перевірки, щоб забезпечити послідовність та хороший стиль коду. Використання IDE із заповненням коду та підсвічуванням синтаксису також може допомогти вам запобігти або виявити деякі проблеми, перш ніж натиснути кнопку "побудувати". Одиничні тести можуть охопити логічні проблеми. І якщо ваш проект достатньо великий або складний, безперервна інтеграція може об'єднати все це в регулярно запущений процес і створити приємні звіти для вас.


7

Робота соло означає, що якщо ви не довіряєте стороннім людям переглядати код від свого імені, вам потрібно буде подивитися на те, як ви пишете програмне забезпечення, щоб підтримувати якість коду.

По-перше, ви повинні мати засоби для того, щоб ваш код відповідав вимогам, по-друге, ваш код буде відносно легко змінити, якщо згодом ви вирішите, що у вас щось не так. Моя пропозиція полягає у застосуванні підходу до розвитку поведінки з наступних причин:

  1. BDD означає спочатку написати тест на код. Це гарантує тест на весь ваш код.
  2. BDD по суті є TDD, але з дещо іншим фокусом і "мовою". Це означає, що ви постійно переробляєте код під час роботи над ним і використовуєте свої тести, щоб забезпечити продовження зусиль рефакторингу для того, щоб ваш код відповідав вашим характеристикам продукту.
  3. Мова BDD закликає тести писати у вигляді висловлювань, які по суті кодують вимоги як одиничні тести.

Отже, ідея тут полягає в тому, що ваш постійний рефакторинг коду навіть після того, як ви пройдете тести, означає, що ви ефективно переглядаєте свій власний код і використовуєте свої одиничні тести як "зайву пару очей", яка переконує, що ваш код не відповідає " t не відхилятися від вимог, які кодуються в тестах. Також високе покриття тесту, що базується на вимогах, гарантує, що ви зможете змінити код у майбутньому, не виконуючи вимоги.

Справжньою проблемою для вас буде те, чи зможете ви помітити в коді потенційні проблеми, які вказуватимуть на необхідність рефактора. На ринку є кілька інструментів профілювання, які можуть допомогти вам у цьому, а також кілька інших інструментів, які стосуються показників якості коду. Вони часто можуть розповісти вам багато речей, які огляди коду можуть пропустити, і вони є обов'язковими при розробці проектів самостійно. Насправді, досвід є ключовим, і коли ви звикли бути нещадними у своєму рефакторингу, ви, швидше за все, станете набагато критичнішими до власного коду. Якщо ви ще цього не зробили, я б запропонував прочитати книгу Рефакторинга Мартіна Фаулера як вихідну точку та шукати хороший API BDD, який, на вашу думку, буде працювати для вас на тій мові, якою ви вирішили працювати.


5

Щоразу, коли я опинився в тій же ситуації, що і ви, я намагався вирішити проблему "бути занадто близьким до коду, щоб об'єктивно його вивчити", використовуючи інструменти огляду коду / метрики. Само собою зрозуміло, що інструмент не може надати те саме значення, що і досвідчений рецензент, але ви все одно можете використовувати їх для точного визначення поганого дизайну.

Одним із інструментів, який я вважав досить корисним у цьому плані, був SourceMonitor . Це трохи спрощено, але воно дає хорошу думку середнього рівня щодо вашого коду, наприклад, кількості методів у класі та складності кожного методу. Я завжди вважав, що цей тип інформації має настільки ж важливе значення (якщо не важливіше) застосування стилів кодування за допомогою інструментів типу StyleCop тощо (які важливі, але часто не є джерелом найбільших проблем). Використовуйте ці інструменти зі звичайними відмовами: знайте, коли потрібно порушити правило, і те, що в інструменті метрики коду все зелене, не є автоматично доброї якості.


5

Я не можу сказати вам, скільки разів я щось пояснював рецензенту коду, і лампочка в голові включається і каже: "Ей, почекай хвилинку". Тому я часто виявляю власні помилки в огляді коду, яких не бачила інша людина. Тож ви можете спробувати це, просто почніть пояснювати код так, ніби поруч з вами сидить людина, яка намагається зрозуміти, що ви зробили і чому.

Інша річ, яку я часто зустрічаю в оглядах коду, - це те, що розробник насправді не дотримувався вимоги. Тому порівняння вашого коду і того, що він робить, фактична вимога - це хороша перевірка.

Ми часто робимо такі речі, як пакети SSIS, які мають подібні структурні потреби - для огляду коду я розробив контрольний список речей, які потрібно перевірити (правильна конфігурація, налаштовано журнал, чи використовується база даних метаданих, чи є файли у стандартному місці, тощо). Можливо, у вас є деякі речі, які було б зручно перевіряти кожен раз в огляді коду. Сядьте і подумайте, що б ви помістили у контрольний список речей, які ви хочете обов’язково перевірити у своєму огляді коду (Перший пункт, переконайтеся, що вимога виконано, наступний пункт може мати щось спільне з помилками захоплення та реєстрації). Коли ви робите помилки та виправляєте їх, ви можете додати до списку інші елементи (скажіть щось на зразок, чи я переходжу до наступного запису в циклі чи збираюся нескінченно повторювати той самий перший пункт - на це знадобиться лише один нескінченний цикл навчити шукати це!).


1
Як пропонує Патрік Х'юз у своїй відповіді, використання проксі-сервера, як гумовий каченя, щоб стати учасником рецензента, допомагає мисленню.
Рассел Борогов

5

Дайте 3 місяці, потім поверніться і подивіться на свій код. Обіцяю вам, якщо ви не зможете знайти щось не так з цим (або питанням, хто написав цей мотлох!), Ви краща людина, ніж я!


Це теж моя техніка. 3 місяці достатньо довгі, що все, що я не можу відразу зрозуміти, потрібно спростити або задокументувати краще, але досить коротке, що я все ще пам’ятаю, що відбувається досить, щоб легко виправити це.
Ерік Поль

5

Зазвичай я роздруковую весь свій код і сідаю в тихому середовищі і читаю його, я знаходжу багато помилок, проблем, рефакторних речей, очищення, роблячи це. Думаю, що це гарна самоперевірка.


Гарне доповнення до наведених вище порад, дякую - хоча я думаю, що планшет чи щось подібне (з редактором, але без середовища розробки) теж працювало. Мені цікаво, хто спростував це і чому.
Макс Янков

4

Ще в коледжі я був викладачем з письма. Це, безумовно, дало мені певну перспективу щодо кодування, яку, на мою думку, багато розробників ніколи б не подумали. Одне з найважливіших - читати свій код вголос. Це звучить не так вже й багато, але я наведу прекрасний приклад, на який я думаю, що кожен може ставитися до цього.

Ви коли-небудь писали електронний лист чи папір, перечитували кілька разів, щоб переконатися в правильності його, а потім надсилали його, лише щоб виявити, що у вас є чітка орфографічна помилка, помилка друку чи граматична помилка? Я щойно зробив це вчора, коли попросив клієнта натиснути клавішу лайна замість клавіші shift. Коли ти читаєш у голові - бачиш те, що хочеш бачити.

Це ярлик для пропозицій "просто зачекай день або тиждень чи місяць", які висловили інші. Якщо ви читаєте це вголос, ви ловите ті самі речі. Я не знаю, чому це так ефективно, але після того, як сидіти з сотнями студентів і читати їх вголос, все, що я можу сказати, - це працює.


+1 Це походило б разом із підходом "поясніть це своїй коті". Використання різних частин вашого мозку може бути корисним, коли ви не можете використовувати колегу.
BMitch

плюс один за ключ від лайна
Mawg

3

Більшість людей схильні вважати свій код власними дітьми і годують їх егою, а не реальністю. Як і будь-які інші огляди коду, перегляньте його, як ви бачите чужий код. Повністю забудьте, що ви щось написали. Перегляньте кожен рядок коду. Контрольний список може бути корисним для естетики щодо перегляду власного коду. Автоматизовані інструменти для перегляду коду можуть допомогти певною мірою. Я використовував деякі інструменти, такі як klocwork (комерційне програмне забезпечення). Це дуже корисно, коли ви працюєте у великих проектах, і кілька розробників працюють над цим. Завжди орієнтуйтеся на виявлення дефектів, а не на виправлення.

Але найкращою практикою було б - перегляньте себе та пізніше залучіть до рецензії щонайменше двох інших людей із визначними ролями.


3

Подумайте про те, щоб зробити інспекцію Фагана самостійно - вам доведеться адаптувати процес, тому що ви самі, але ви повинні мати змогу отримати з нього досить велику цінність. Хитрість полягає в тому, щоб знайти правильний "набір правил", щоб оцінити ваш код як сольний розробник, а потім мати дисципліну, щоб задавати ці питання в критичній, аналітичній, нещадній ситуації кожен раз. Я підозрюю, що ви, можливо, захочете замислити свої 4-5 найважливіших питань для початку, а потім розвивати їх у часі. Деякі люди проти офіційних перевірок, тому що вони здаються такими трудомісткими ... перш ніж вирішити, що вони занадто дорогі, пам’ятайте про всі статистичні дані, що проведення перевірок належним чином фактично скорочує час проекту. Ось посилання на Вікіпедію, з якого можна розпочати подальші дослідження:

http://en.wikipedia.org/wiki/Software_inspection

Було також кілька книг, наприклад, Google для "Процесу перевірки програмного забезпечення" Стросса та Ебенау.

Інший варіант - заплатити комусь за огляд важливого проекту - або, можливо, платити їм час від часу, щоб зробити перевірку всього вашого коду. Цей хлопець дуже гарний, ми кілька разів вилітали з нього, щоб тренувати наших новіших розробників:

http://www.javaspecialists.eu/


0

Крім усіх рекомендацій щодо перегляду коду, ви можете використовувати такі інструменти, як PMD і findBug, щоб зробити перший рівень розумності свого коду.


0

Насправді це ще не було розміщено у відповіді (але додано як коментар до існуючої відповіді)

Перегляньте свій код після хорошого сну, наприклад, розпочніть день, переглянувши код, який ви написали попереднього дня.

Це, звичайно, не дасть вам колективного досвіду команди, але це дозволить переглянути код з нової точки зору.

Наприклад, якщо ви залишили фрагмент коду з неприємним злом, ви, можливо, не будете занадто схильні виправити це, якщо перегляньте свій код відразу після. Зрештою, коли ви починаєте переглянути свій код, ви вже знаєте і прийняли наявність цього зламу. Але якщо у вас був добрий сон, ви, ймовірно, більше вмотивовані для пошуку кращого рішення.

Коли ми спимо, мозок насправді не припиняє працювати над проблемами, які ми маємо, тому ви, можливо, дійсно можете знайти там рішення, хоча ці рішення іноді можуть представляти себе дивними способами .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.