Thursday, December 29, 2016

Eric Ries "The Lean Startup"

For me, this book is really mind-changing. What I like in "The Lean Startup" is that every assumption is there with robust proof. You understand why author tells you this thing, he tells the stories and gives you examples of why that thing is bad and why the different thing is good. I learned really a lot from it, and not only about the approach to the business but also about the approach to the life. I am the big fan of the term "Leap of faith", because I found so many leaps of faith in my life, that now I really understand why the things are going in this way and not in other. A quick summarize of the book below.

The concept of this book is built around "Validated learning" term. The validated learning means, basically, failing. After each fail, you get some experience about what was the mistakes, that led you to the fail. The problem is that, probably, you spent a lot of time and money to learn this. The solution here is to fail as early as possible, so you can avoid spending your money and time to the lousy things. So the flow is: you make some product and try to recognize that it is failing as early as possible then you make some changes, based on your experience, and start the process again.

There are three basic things that you need to know, before implementing this approach. The first one is how to recognize that your project is failing? You can see that it doesn't achieve its goals. E.g. the feature you decided the most important doesn't earn money, or nobody use it. Your customers are the only people who unintentionally show you the value of your product. Why unintentionally? Because when they use (or not use) your product they do it only because they need it and they use it only the way they can. You cannot understand if your product will be successful or not only by yourself or with your partners. The only way to understand it - release the product. And that means that you need to release your product as fast as possible.

How to release the product fast? Build less. You need to release only the most important things and they can work poorly, but anyway, you will see how your customers interact with that. How to choose which feature is the most important? Here is the term "Leap of faith". When you start your project you usually assume something. If you design a photo sharing app, you assume that people will be ready to switch to new photo sharing app. Usually, you accept these assumptions without any proof, and it becomes the main reason of your fail. What you need to do is find which assumption you accepted as the axiom and check it first. Just build the most simple implementation (in some cases you don't even need it, try to make the service by your own - contact customers, make the work with your own hands, without your application or web service).

That means, that you need to work in small batches. You need to release fast and with really small changes. You need to thoroughly check how the change affected your project. For this, you need to use cohort analysis instead of vanity metrics. Vanity metrics are simple, e.g. the number of users or the number of something else. Why is vanity metrics bad? Because they don't really show are you growing or not? Cohort analysis allows you to segment your customers and check the percentage of the segments. If the percentage of users in your target segment is growing it means that you are growing too, otherwise, you do something wrong.

To wrap it up:
 - Your goal is to fail earlier to avoid unnecessary expenses
 - You need to release often and in small batches
 - The first thing to test are your leaps of faith
 - Use cohort analysis instead of vanity metrics

Of course, there are much more useful things with different interesting stories about fails and successes of the different startups, about mistakes, problems, and solutions. I highlighted ones, that I think are the most important. I definitely advise to read this book to everyone, who involved in IT industry or want to build his own business.

Friday, November 25, 2016

Steven Skiena "The Algorithm Design Manual"

The modern typical programmer doesn't need to solve complicated algorithmic problems. Usually, you use fixed set of tools and methods that help you to manage the memory and the runtime of your program properly. Knowledge of the language matters, because you use data structures like the hash tables or linked lists almost every time, and, if you know how they work, you can achieve good runtime or memory economy, by using correct data structure. But very seldom you meet the problem, where you need to balance the tree in one way, instead of another, or solve complicated graph problem. The best way to apply the knowledge of algorithms for the average software developer is to go to a technical interview in a company like Google or Facebook. I wanted to read this book to update my skills of solving algorithmic problems and fill the whitespaces in my knowledge.

This book definitely requires a strong technical background. I knew a lot of data structures, represented in this book and some algorithms over this data structures, but even with this, it was very difficult to read it. The best way to use "The algorithm design manual" is to treat it like a course in your university. You need to take a pen and a paper and draw everything and try to reproduce the algorithms. Unfortunately, I read this book during my bus travels between office and home, so I didn't have such a possibility and didn't understand some things.

The best thing about this book is that it gives you the strong sense of how to develop the algorithms for a particular problem. It gives you the bunch of tools and says how to apply them. And the first thing that you need to do, when designing an algorithm is to model the problem in terms of existing problems. There are a bunch of existing already solved problems, and yours is definitely a special case. The second part of the book gives you a lot of problems that you can meet and, which is really important, gives you a set of questions that you need to ask yourself to understand in which direction to move further. It also gives you links to the implementations of the solutions, so you even don't need to reinvent the bicycle.

The proper way to optimize your algorithm is to use the correct data structure for some operations. The first part covers the majority of the data structures that you will need in solving algorithmic problems. It also gives simple implementation in C and set of tasks after every chapter. I guess, I need to reread this part more thoroughly because I still didn't understand some of the graph problems and I didn't solve the problems at the end of chapters.

In general, if you solve the algorithmic problems often, that book can be a bible for you. You can open it every time you need to solve something and read the correct approach. Otherwise, the best way for you is to read the first part and make sure that it is in your head, then make a fast screen of the second part. Then, open it again when you stuck and look for some help there.

If you want to start your journey in the algorithmic world, this will be a good book for you, but, it explains things very fast and sometimes skips the details, so you either need to prove things yourself or to find it in the other book. Better to read this book with some background, so you can recall some things and update your knowledge.

Friday, October 21, 2016

Ф.М. Достоевский "Преступление и Наказание"

Мне стыдно признаться, но я не читал "Преступление и наказание" в школе. Сейчас, когда я закрыл книгу, стало ясно, что начинать надо было в нынешнем возрасте. Может быть я отстаю в духовном развитии от сверстников, но я не могу представить, что десяти- или одиннадцатиклассник сможет полностью прочувствовать переживания и болезнь Раскольникова и сердцем понять выводы, доказанные в течение повествования и представленные в эпилоге. Если вы читали это произведение только в школе или вообще не читали и вам сейчас от 20 до 30, то я настоятельно советую взяться за "Преступление и наказание".

Это одна из тех книг, которой я зачитывался в запой. Я читал ее везде и не мог оторваться. Такое со мной, последнее время, бывает редко. Каждый раз,, отрываясь от книги я находил в себе волнение и лихорадку, мне было тяжело, я боялся. Я чувствовал Раскольникова так, как будто вспоминал свои переживания. Это то, что я больше всего ценю в книгах, и если писателю удается передать ощущения так ярко, без сомнения, его мастерство достойно уважения. В случае Достоевского, я теперь готов поставить его куда-то во главу пантеона моих любимых писателей.

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

Прежде всего, я согласен с теорией Раскольникова, лишь с одной оговоркой. Я действительно считаю, что люди могут быть материалом и могут быть великими. Я также согласен, что великим прощаются преступления. Так уж вышло, что великие поступки затмевают грязь. Так уж вышло, что моральные принципы и права существуют лишь в головах людей и нигде больше, поэтому и вся эта система с прощением или судом существует там же. Каждый хочет быть великим, но не каждый может. Поэтому, я бы сказал, что на преступление права не имеет никто, но кто-то может заслужить прощение.

Очень хочется быть великим. Никто не хочет быть материалом, предназначенным для размножения. Никто не хочет существовать. Я вижу две крайности существования - Раскольников, который не мог смириться со своим существованием и пытался доказать, прежде всего себе, что он принадлежит к категории великих, и Мармеладов, который смирился со своим существованием и провалился в самую глубокую пропасть. Ни одна из этих крайностей не может быть правильной.

Наказание описывается с самого начала книги. Страх, болезнь, депрессия, грязь, все это тревожит Раскольникова с первых страниц. Казалось бы, он еще не совершил убийства, но уже наказан. Когда в книге появляется Мармеладов, мы видим противоположность, которая тоже наказана. За что же наказание, если преступление еще не совершено? Я считаю, что преступление, которое упоминается в названии книги - это не убийство старухи процентщицы. Преступление - это мировоззрение. Преступлением является высокомерие Раскольникова, смирение Мармеладова, одержимость Свидригайлова. Преступлением являются крайности, и лишь одну крайность прославляет Достоевский - бесконечное самопожертвование. Самопожертвование Разумихина, Дуни, Сони находят награду. В любви видит Достоевский выход. В любви, а не в безразличии, эгоизме, высокомерии или одержимости. Достоевский говорит, что велик тот кто любит, прощаются преступления тому, кто полюбил. Когда Раскольников раскаивается (по-настоящему) 7 лет каторги мысленно сокращаются в семь дней, а значит преступление прощено, значит и Раскольников стал великим, раз способен полюбить.

Счастье - понятие сложное, для каждого оно свое. Но никто не счастлив в одиночестве. Мне нравится то, что Достоевский не говорит о том, что величие заключается только в любви - полюбил и этого достаточно. Я понял мысль так: чтобы стать великим, нужно полюбить. Нужно полюбить и выстроить мир вокруг себя и любимых, а потом уже приниматься за всех остальных. 

Некоторые вещи в жизни довольно неочевидны, потому что скрывают свой эффект за пеленой долгого времени. Наверно, любовь одна из таких штук. Я всегда говорю, что живу очень счастливой жизнью и никогда не испытывал никаких несчастий. И все это, потому что был любим и потому что сам всегда любил. Любил родителей, друзей, девушку, жену. И как-то никогда не задумывался, что причина всегда была именно в этом. Хочу сказать спасибо вам, за то, что делаете меня счастливым. А величие еще впереди (я надеюсь на это), теперь-то я к нему готов!

Friday, October 7, 2016

H.G. Wells The Invisible Man

Despite Wells's books are a fiction, they look like the thought flow. Wells make an experiment inside the book and observe how is the experiment going. As a scientist, he gives us full information about the main parameters of the experiment and leaves us with it to analyze and to make conclusions. Every scene and every character look like a scientific environment put in the book for one purpose: to see how it will affect the observable object.

The Invisible Man is the book about people, their fears and first of all, their hunger for superiority. This book is an experiment about what will happen if the man, who is not ready to bear an ultimate power, will get it. The environment is a small town with casual people. The observable object is the man, who found how to become invisible. But the power goes with limitations - he can be invisible only if he is naked. This makes the Invisible Man weak and vulnerable and Wells shows it in the little details, like sneezing, because of the cold, caught by Invisible Man in winter, or by dirt, sticked to his feet in autumn.

Wells shows the disadvantages of invisibility very brightly: nobody cares about the Invisible Man. Nobody sees him, and nobody believes he exists. Invisible Man cannot buy anything, he cannot rent the apartments, cannot act as a casual man, because for other people he doesn't exist. Furthermore, the fear of weird things, fear of something absolutely new which is a trait of almost everyone, makes it impossible for Invisible Man to communicate with people in a usual manner.

Different people will deal with this set of problems in a different manner. The main character decided to become invisible because he wanted to avoid the problems. This means, that he wanted superiority because he was weak and couldn't deal with his problems himself. When the man is weak and he achieves the power, he cannot wield it. The Invisible Man thought that the problem is not inside himself but inside others. He thought that he is a genius and Wells shows his arrogance very distinctly. We can say, that the Invisible Man suffers some kind of star fever and this drives him mad. He cannot accept, that people think that he is not higher than them, that no one not only accepts his superiority but doesn't even notice him. I won't unveil the end of the book, I will just make some conclusions.

If you cannot solve one problem, there is a big chance you won't be able to solve another.  The power is not such a thing that can be wielded by anyone. You need to be strong to wield it. This means, that if you feel that you cannot solve the problem don't avoid it. Try to make anything to beat it. This is the only way to become stronger and to find a way to the power. Otherwise, you will end like the Invisible Man.

It was an interesting experience to read H.G. Wells but I don't think that I really like these books. I will recommend this only for fans of sci-fi or for someone who likes to conduct mind experiments. I would give this book 5/10 - I was not very bored, but it wasn't fascinating and super interesting for me.

Friday, September 23, 2016

H. G. Wells "The time machine"

Honestly, I am very indifferent to the sci-fi genre. I am more a fantasy guy. It wasn't very interesting for me to read Jules Verne in my childhood, however, everyone talked about it as something fascinating and exciting. But I've never read Herbert Wells before and I heard a lot about the deepness of his sci-fi novels so I thought that it is worth to try and give the second chance to the sci-fi for me.

I cannot say that "The time machine" is a sci-fi story. It is more about a flight of thought and ideas of the author about our future. I guess almost everyone discussed possible variants of our future with his friends or just in his mind. When we talk about the future we always think about robots, space traveling, and aliens.  We always think that our species will be quite the same. Maybe because we don't mind to think in a very long term. However, once I and my friend had a very interesting discussion about the very far future where our progress will lead us to the world of laziness and satisfaction. We thought that there will be no bodies only brains with wires and pipes connected to it and providing the nutritious and the dopamine. Everything to support the life will be done by robots and machines and even fixing the broken machines and factoring new machines will be done by machines too.

It is interesting that I and my friend thought in one key with Herbert Wells. The difference between our views is caused by our current time. We thought about the degradation of the humans by scientific causes and Wells thought about the degradation of the humans by class-difference causes. He thought that the rich class will live so happy that become a stupid defenseless and small creatures, who love everything about it. However working class, exiled to the underground, will become the underground beasts who will need to hunt on the surface to survive. It is quite an interesting idea that all the progress leads the humanity to degradation because all the progress directed to make the people happier. However, our happiness strongly depends on our animal instincts, like be not hungry, don't waste an energy of the body and have enough dopamine in the brain. We are doing great things to fulfill our primitive needs.

Wells also raises the problem of class differentiation. He shows that by offending a working class, by exiling it underground and exploiting it as a free working power the rich people created the beasts who hunting them in the night. Wells raises an idea that creatures who need to survive will become more powerful than always-happy creatures, and will keep them in permanent awe. So we need to be more pleasant to each other and provide equal rights to everyone.

However, the robots in my future don't have their own mind, so it is quite safe to use them as a working power, while our brains will enjoy the fountains of dopamine.

Sunday, September 11, 2016

Dale Carnegie "How to stop worrying and start living"

I didn't plan to read this book this year, but there were circumstances forced me to read it. It was terrible because I had to choose between one good thing and another good thing and I couldn't and I worried so much, that I couldn't even eat. I decided that something is wrong with me and I need to fix my panic, so I removed one book from my reading list and added "How to stop worrying and start living" instead.

My only concern about this book is the stories. There are so many stories of different people, all are the same, and it bothers you since the first pages. The whole book is like one idea in one sentence and ten similar stories about this idea each on 2 or 3 pages. The author presents it as a proof of his thought, but there is a small thing about it. You will do all the stuff, all the exercises from the book only if you are highly motivated to stop worrying. It is enough to read one successful case to believe that technique works fine. If you don't want to stop worrying you will close the book and not even hundred stories about how good the techniques are would stop you. So the tons of stories are completely unnecessary, and all of them are completely similar with only different characters inside. It makes the book huge and boring, and it doesn't give you what you want from the book.

I was very surprised to realize that I already use 80% of techniques that are presented in the book. I don't have insomnia or a nervous breakdown. I can even work under the stress condition, but not as well as without. Honestly, my main problem is that I always know what is my problem, why am I worrying and why I need to stop it. But I can't stop. And I wanted to find an answer from this book on how can I close my eyes on all these problems and make a decision or work as good as I do without stress conditions. I didn't found the answer. But I've found some good advises.

The first technique that I always use and I think it is worth to mention even it is not new for me is "always think about today, not tomorrow or yesterday". Because if you have something tomorrow and you cannot affect it today, you don't need to keep it in mind, because it bothers you. If you can do something today to improve tomorrow, then do it. If you made a decision and you cannot undo it, then you don't need to worry about it, because it is useless. What you can do is to sit one time, analyze what was wrong and what could be better, and promise yourself to not do the same errors in future.

The second technique is new for me, but, I think, very powerful. When you have a problem, and you are procrastinating because all the solutions seem bad, you need to choose the worst and try to accept it. If the worst case is that you lose millions of dollars or your house or something like that, try to mentally accept it, because it can be your tomorrow reality. If you will accept it, like it has already happened, you can try to improve the situation and think about how to make this situation better. It will be easier for you if you already decided that you don't have these millions of dollars that you are going to lose. If you think you don't have something then you can't lose it, right? After that, you can think on how to earn these millions of dollars, by making the situation better. It will be much easier.

The third technique I call the brainstorm of the problem. I've used it a couple of times, but it is not in my everyday arsenal, don't know why. The idea is that you write down the problem, then write down the cause of the problem, then write down the list of possible solutions and choose one, that seems the most acceptable to you. If the problem is not very serious unlike you think about it, you will see that there is nothing difficult about this problem.

Dale Carnegie talks a lot about religion. He says that prayer is very helpful to calm down your nerves. I agree with him that if you believe in some magical being above the skies, it will help you, but I cannot accept this mentally and it wouldn't help me. Instead, after reading the book, I've started to relax, when I feel worried. I am trying to relax all my muscles, close my eyes, and then starting to speak with myself like "What's wrong, man?". If I have the answer, I think about it, then imagine a general plan of actions of how to solve the problem, then imagine the first step that I need to undertake, and count till 30. This helps me very much and when I am relaxed with closed eyes and nothing bothers me it is very easy to concentrate and beat the worry.

I think that this book is not for me because I don't have any big problems (or because I understand it) because I know the majority of the techniques and apply it in my everyday life, and because I don't need these freaking tons of similar stories which constitute around 80% of the book. As I heard this book helped a huge amount of people, so maybe it is very good and helpful for people with some problems. I didn't find the answer that I sought, so maybe my broken expectations affected my attitude to this book. Anyway, I guess it is worth to try if you find yourself suffering by worry in your everyday life.

Friday, August 19, 2016

Олег Тиньков "Я такой как все"

Предисловие

Перед постом хочу написать, что я очень недоволен качеством предоставления услуг Тиньковфф банка, потому что в течение недели они не могут поменять номер телефона привязанный к аккаунту, ссылаясь на технические неисправности и не давая даже примерных сроков исправления ошибки. Весь мой предыдущий опыт работы с этим банком также был довольно негативный и ни одного действия без звонков/писем в тех поддержку сделать не получалось. Это совершенно не тот процесс, который я представляю себе при работе с банком (хотя, конечно, сам программист и представляю как происходят дела по ту сторону экрана). Это также не имеет никакого отношения к книге, но раз уж это связано с ее автором и его делом, я должен был высказаться, тем более, что отношение к Олегу Тинькову, как к бизнесмену у меня крайне позитивное.

Пост

Книгу я прочитал с большим удовольствием. Это одна из немногих книг, которые я с удовольствием читал даже дома (обычно, я читаю в транспорте, по дороге на работу, а дома занимаюсь другими делами). Перед тем как взяться за "Я такой как все", я почитал немного отзывов и увидел тонну негатива. Проблема этих людей в том, что они искали пошаговую инструкцию "Как заработать миллионы долларов и не страдать", а внутри ее не оказалось. Точнее, я бы выразился так, - там есть инструкция, но она находится между строк и называется "Почему у меня все получилось", что, конечно же, совсем другое. 

"Я такой как все" это история, прежде всего, о человеке, который начинал с того же, что и все, а закончил тем, о чем все мечтают. Это история о его переживаниях, о главных вещах в его жизни, о характере и мировоззрении. Что меня очень сильно привлекло, так это человечность, которой пропитана книга. Ты читаешь про мультимиллионера, а во многих моментах узнаешь себя. Очень хорошо, что Олег Тиньков описал не только победы, но и поражения. Описал в каком напряжении находился, как расстраивался и как ему было плохо от неудач. Чего стоит только момент с облигациями Тинькофф банка, которые никто не хотел покупать. Мне кажется, ничто так не вдохновляет, как осознание того, что успешный человек такой же, как и ты. Не бесчувственный робот, побеждающий на каждом шагу, а сибирский парень из маленького Ленинска-Кузнецкого, работавший в шахте.

Как мне удалось понять из книги, и как я сам давно подозревал, самое важное в бизнесе это две вещи - твой характер и твои партнеры. В книге, между строк, приведены черты, которыми должен обладать успешный предприниматель: терпение, расчетливость, смелость, любознательность, эгоизм (в хорошем смысле), амбициозность, логика. Так же, как и у Сунь-цзы в "Искусстве войны", предприниматель, как и полководец, должен обладать сразу всеми этими качествами, чтобы добиться успеха. Это необходимое, но недостаточное условие. Достаточным условием являются партнеры и люди вокруг. Ни один успешный предприниматель не стал миллионером в одиночку. Тинькову всегда кто-то что-то показывал, подсказывал, помогал. Надо сказать, что все люди любят советовать, но очень важно находиться в окружении таких людей, чьи советы помогут вам достигать ваших целей. Такому подходу помогут ваши эгоизм и логика. Очень понравилась фраза из книги "Я не верю в бизнес на фоне дружбы, но верю в дружбу на фоне бизнеса". Как показывает практика, делать бизнес с друзьями, действительно, так себе затея. А вот подружившись с партнером, можно построить довольно крепкие взаимовыгодные отношения.

Давайте теперь попробуем ответить на вопрос с чего начать свою дорогу к успешному предпринимательству? Как мотивировать себя ступить на этот путь? Тиньков стал предпринимателем не потому что вынашивал какие-то идеи с самого детства. Ему посоветовали, в одной из поездок в Узбекистан, купить дефицитные вещи, которые там продавались очень дешево. Так он начал зарабатывать. Позже, после переезда в Питер, Тиньков продолжил заниматься тем же, потому что студенту в чужом городе нужны деньги. А дальше, амбициозность и любознательность сделали свое дело, и помогли развить частную торговлю в международный бизнес: Польша, Германия, Россия - в этих странах торговал Тиньков. Тиньков начал продавать, потому что это приносило ему больше денег, чем что-либо  другое. Также как и вы, с большой вероятностью, смени работу на более высокооплачиваемую. Заработанные деньги помогали Тинькову достигать целей и задач, которые он перед собой ставил, помогали воплощать мечты в реальность, и это двигало его зарабатывать больше. 

Все началось с совета друзей как заработать денег - просто и прозаично. Это та же причина, по которой вы пошли работать туда, где вы работаете - это был самый доступный вариант заработать больше, чем вы получали. Деньги вы тратите на то же, на что тратит Тиньков - на свои цели и желания. Отсюда ответ - нужно ли вам идти в бизнес? Если ваши цели и желания достигнутся и исполнятся - да. Но надо не забывать, что вам придется очень много трудиться, выбирать между плохим и плохим, терпеть, трудиться, терпеть, трудиться, терпеть и, может быть, вы достигнете успеха. Задача выглядит довольно сложной, но раз уж она поможет вам добиться ваших целей, то почему бы и не попробовать? Тиньков решил такую задачу, а он такой же как и вы. 

Вывод простой: хотите делать бизнес, воспитывайте в себе качества предпринимателя. Избавляйтесь от страхов, научитесь расчитывать и принимать решения (в том числе на основании расчетов), научитесь думать о себе, а не о других, смотрите за тем, что происходит в мире, любите мир, ищите в нем то, что поможет вам стать счастливее, поймите, чего вы хотите достичь, развивайте логику, общайтесь с людьми, ищите людей с общими интересами, которые уже добились чего-то большего, чем вы. И, главное, не забывайте, что даже став таким человеком, вы добьетесь успеха только прикладывая усилия и перенося сильнейшие нагрузки. А кто говорил, что будет легко?




Saturday, July 30, 2016

Сунь-цзы "Искусство войны"

Я давно хотел прочитать эту книгу, так как видел ее во всех блуждающих по интернету списках "ОБЯЗАТЕЛЬНО ПРОЧИТАТЬ!!!! ЭТИ КНИГИ РЕКОМЕНДУЮТ ВСЕ!!!". Более того, название "Искусство войны" всегда было на слуху, и, с учетом моих взглядов на мир, я решил, что эта книга является универсальным трактатом не только для военных и увлеченных тактикой, но и для любого живущего на земле человека. Отчасти я оказался прав.

Вообще, если бы меня попросили описать "Исскуство войны" одной фразой, я бы переделал свое любимое высказывание "Лучше быть здоровым и богатым, чем бедным и больным" в "Буешь здоровым и богатым, тогда будет хорошо. Будешь бедным и больным, обязательно погибнешь". Сунь-цзы безусловно мудр и описывает очень важные вещи, но эти вещи ты вроде как понимаешь какой-то далекой частью сознания, и они довольно очевидны, но о применении их никогда не задумываешься.

Издание, которое попало мне в руки состояло из самого трактата на 10% и на 90% из комментариев и примечаний. Комментарии были довольно содержательны, с глубоким анализом существующих трактовок и множеством интереснейших исторических примеров. Но все же главной ценностью книги является сам трактат, который открыл мне несколько очень значимых мыслей. Я приведу здесь самое важное, что узнал и дам этому несколько иную трактовку, касательно того, как тот или иной совет можно применить в реальной, современной жизни.

Все мы знаем, что война это страшная и античеловечная вещь, но почему-то она существует. Существует она как и все в этом мире, ради чьей-то выгоды. Сунь-цзы говорит, что лучше всего когда войны нет. Лучший правитель и полководец тот, кто добивается победы без войны и без боя, без лишних потерь как человеческих, так и экономических. Война - один из способов, помогающих достичь определенной цели, но Сунь-цзы рассматривает ее исключительно как крайнюю меру. Причина довольно проста: затраты на ведение боевых действий могут превысить полученную выгоду. На войну следует идти только тогда, когда выгода от нее превосходит пологаемые затраты. Если есть стотысячное войско, то его содержит семьсот тысяч крестьян плюс нужно учесть, что затраты на клей и лак для колесниц, приемы послов, починку оборудования, перевозку составляют 1000 золотых в день (все цифры основаны на определенных фактах китайской истории, но мысль здесь ясна). Более того, на войну следует идти только когда 100% уверен в победе. Что нужно сделать, чтобы на 100% быть уверенным в победе, Сунь-цзы и описывает в своем трактате.

В переводе на реальную жизнь я бы мог сформулировать мысль так: не ввязывайтесь в какое-то дело, не сопоставив предполагаемые затраты и выгоды от него. Причем затраты нужно учитывать не только прямые, но и косвенные. Например, при самой бытовой ситуации, - переезде в более дешевую квартиру, в районе подальше, можно посчитать затраты на транспорт (бензин) в течение месяца для поездки на работу, в ближайший гипермаркет, в кино, стоимость доставки пиццы, или что вы там еще делаете. Кроме этого, один из самых важных ресурсов человека - это время. Подумайте сколько времени в этом случае вы потеряете и сможете ли вы его как-то возместить. Таким образом выигрывая в арендной плате, вы можете проиграть в других вещах суммарно больше. Возможно, пример звучит так себе, но это первое, что пришло в голову. Мысль такая: имейте цель, ищите как этой цели добиться, взвесьте затраты и выгоду и так решайте - двигаться вам по выбранному пути или нет.

Война это путь обмана - мысль, прошитая золотыми нитями через весь текст. Китайские воины не играли в благородных рыцарей, не утверждали лицемерно о честности и правдивости, а сообщали сразу, что будут лгать, хитрить и пользоваться любой слабостью противника. Я всегда думал, что это какая-то негласная правда, но оказывается уже несколько тысяч лет это установленная прописная истина. Очень важно на войне разными хитростями заставлять противника действовать так, как тебе угодно и не действовать так, как угодно противнику. Можно забирать у противника то, что ему дорого, чтобы отвлечь его силы от того, что нужно тебе. Можно подбрасывать ему ложную выгоду, чтобы он шел туда, куда нужно тебе. Можно показывать что ты слабый, чтобы он атаковал, а ты зажал его в тиски, можно, наоборот, показывать, что ты сильный, чтобы он отсутупил от нужного тебе места. Но чтобы знать как влиять на противника, нужно знать все про него: его силы, командование, настроения в армии и так далее. Для этого Сунь-цзы советует обязательно использовать шпионов и посвящает этому целую главу. Очень важно не дать противнику узнать ничего о себе, чтобы он повелся на твои хитрости и притворства. Для этого Сунь-цзы советует держать все в тайне, даже от своей армии, или даже лгать своим солдатам, чтобы дезинформировать противника.

Несмотря на то, что наша жизнь не война, и обманывать нехорошо, и шпионов под рукой нет, эту мысль также можно обратить и в наше повседневное русло. Смысл тут таков, что инициатива и контроль над всем, что происходит должны быть у вас в руках. В каждой ситуации нельзя расчитывать на авось. Нужно грамотно все расчитать, правильно понять обстановку и действовать так, чтобы добиться максимальной выгоды. Я поясню: допустим вы устраиваетесь на работу. Если вы делаете это впервые, вы понятия не имеете чего вам ждать на собеседовании. Здесь вы можете, конечно, слепо довериться своей интуиции и приготовить то, что считаете нужным для позиции, а можете поступить по-другому. Если вы опытный работник, с большой вероятностью, вы понимаете, что будет на собеседовании, но быть на 100% уверенным вы не можете. В этом случае, вам нужно узнать каков процесс собеседования в конкретной компании, и самое надежное узнать это у сотрудников компании. Если там есть знакомые, то все проще, если нет, можно спросить у менеджера по персоналу, или вообще найти разговорчивого сотрудника и пообщаться с ним. На собеседование вы придете с ответами на то, что вас точно будут спрашивать и, с большой вероятностью, вы получите работу.

Кстати, одним из самых важных моментов трактата я считаю высказывание Сунь-цзы, насчет того, что, зайдя глубоко на территорию противника, нужно грабить. Подвоз продовольствия через территорию чужого государства затруднен, поэтому нужно питаться за счет противника. Это значит, что в любой ситуации вы не просто должны получить выгоду в конце, вы должны получать ее в процессе, чтобы не изнурить свои силы и снизить затраты. Сунь-цзы также сообщает, что нельзя вести затяжную войну - ресурсы страны слишком быстро истощаются, а значит выгода от войны уменьшается. Эта мысль говорит нам - делайте все быстро. Не истощайте себя томительными ожиданиями и откладываниями. Нужно решать проблемы максимально активно, добиваясь любой ценой того, что вам нужно.

Полководец, вообще, (полководец - это вы, война - это ваши проблемы, а страна - это ваша жизнь) в понимании Сунь-цзы сверхчеловек. Это он выигрывает войну, он должен знать все про противника, он должен держать в голове план победы. Поэтому Сунь-цзы требует от полководца иметь все положительные качества, такие как ум, храбрость, строгость, гуманизм и беспристрастие. Если какого-то из этих качеств нет, существует вероятность, что победы такой полководец не достигнет. Не считайте, что вы, в мирное время, сможете достигнуть 100%  успеха, обладая одним или парой положительных качеств. Вы должны развивать в себе все: и смелость, и волю, и ум, и любовь к людям, и критическое мышление. Не думайте, что без чего-то одного все получится.

В программировании есть такое понятие как транзакция. Смысл в том, что есть какая-то группа из операций, которые нужно провести (например вставить сколько-то элементов и удалить другие) и эти операции либо выполняются все успешно, либо не выполняются вообще (ни одно). Так вот Сунь-цзы говорит так обо всем на войне. Либо вы используете все по-максимуму, либо проигрываете. Очень много внимания Сунь-цзы уделяет выбору местности и действиям в ней. Однако он также говорит, что местность это инструмент победы, и если правильно им пользоваться, победы можно достичь. Но это не значит, что выбрав лишь местность правильно вы обязательно победите. Также как и с качествами - для успеха следует уделять внимание всем аспектам, на него влияющим. Оставите что-то без внимания, 100% вероятности победить уже не будет.

Воины дерутся свирепо, только если отступать некуда и они смотрят в лицо смерти. Сунь-цзы прямо советует отрезать пути к отступлению перед битвой и говорить солдатам, что они идут на смерть. Тогда они не будут смерти бояться, а будут драться так, чтобы получить шанс на жизнь. По этой же причине, Сунь-цзы советует никогда не зажимать противника в угол, иначе его солдаты будут драться так, что смогут нанести тебе поражение. Это, вроде, довольно знаменитая техника в реальной жизни - отрезать себе пути к отступлению. От блокирования самому себе социальных сетей на работе, чтобы не отвлекаться, до увольнения с работы, чтобы начать новую жизнь

Итак, последняя мысль, которой я хотел бы уделить внимание, показалась самой важной для меня. Победу можно подготовить у себя, но реализовать ее, может только противник, показав свою слабость. Вы можете набрать сильную армию, сделать все по-правилам, укрепиться на правильной территории. Вы достаточно сильны, чтобы победить, но и противник достаточно силен, чтобы защищаться. Победить вам удастся только если противник допустит ошибку, значит ваша победа зависит от противника в равной степени, как и от вас. Вы можете сделать в жизни все правильно, подготовиться, натренироваться, прорепетировать, но всегда нужно ждать подходящей ситуации и выбирать правильный момент для реализации своих сил.

Я искренне советую всем прочитать эту книгу, так как она, как минимум интересна множеством исторических примеров, наполнена умнейшими мыслями китайской философии, и помогает понять некоторые очень важные вещи. Меня же, после прочтения, очень заинтересовала китайская история и мировоззрение древних китайцев, поэтому я, конечно же, добавлю в свой бесконечный список несколько книжек на эту тему.

Читайте интересные книжки!

Thursday, July 14, 2016

Ian Millington "Artificial intelligence for games"

The basic insight, that this book gave me is that AI is not a rocket science. Actually, Ian Millington says that AI is a handful of algorithms, which when combined performs a smart and interesting behaviour. Algorithms are generally simple and often has an O(n^2) complexity. The general value of this book, however, is that it gives you a good understanding of how AI should work in your game and how to build flexible, optimised and convenient architecture of your AI engine. I guess, it is not necessary to learn all these algorithms, that are in the book (however you definitely need to know, which algorithm solves which problem). If you plan to work with AI it is worth to get acquainted with this book. Here I will write general things that I think it is worth to keep in mind, without a detailed description of algorithms (when needed it can be found on the Internet).

I guess this will be last technical post which is so long. For future technical readings, I will write a short resume for each chapter. There will be more posts, but they will be shorter and more informative.

There are three key moments in AI engine:
  1. Movement
  2. Decision making
  3. Strategy
Movement and Decision-making are a single character behaviour algorithms, while Strategy is a group behaviour algorithm.

There are plenty of movement algorithms. In the most general way, we can divide it to Kinematic and Steering algorithms. Kinematic algorithms take static data (like current position and orientation and target position and orientation) and perform a stationary movement, without acceleration. Steering algorithms perform more complex behaviour with changing of acceleration and with using prediction methods to obtain a smarter movement method. The common interface for this set of algorithms is Steering, that contains all the kinematic data (like position, orientation, velocity and angular velocity) and the accelerations for both linear and angular. Each frame the game calls method update(steering, maxSpeed, time) for class Kinematic for each object in the game and this method updates current position, velocity and orientation of the character. From the whole diversity of steering algorithms, I want to pay attention to collision and wall avoidance algorithms. The most simple solution here is to cast a cone for each character and check if something lays within this cone. But this approach can produce some mistakes, like two characters can actually avoid each other if they continue to go straight, but can be in each other cones as well. Or two characters can collide, but neither of them is inside the cone.  The better solution here is to check if the characters will collide if they continue to move with the same speed. For wall avoidance, the simplest solution is to cast a ray and check if it crosses the wall. However, the trickiest thing here is the angles. The better solution is to cast multiple rays, but you can get stuck in the acute corner, so you need to be accurate with this. However, more rays mean more processing time, so it is worth to find the optimal number of rays.

Every moving algorithm works only with one variable (like position/orientation, velocity/rotation or acceleration). Very often we need to combine different movement behaviours into one. There are plenty of ways to do it. The first approach is weighted blending. In this, you need to determine weights for each behaviour and then sum up it together. This method has a bad side like you will not actually get a collision avoidance if other behaviours affect the result. Another way to do this is to use some arbitration system, which will decide which behaviour to choose in given moment of time. You can blend this two solutions.

The next big topic in movement is coordinated movement. The simplest method here is fixed formation, where you assign each character to each slot in a formation and treat one slot as a leader. The more scalable way is to use emergent formations like to set for each character another character as a target. We can totally remove the leader of the formation, by assigning invisible leader in the centre of mass of the formation. For more complex behaviours we can use the whole formation as a character, so we can make formations from other formations. Another interesting feature here is slot roles. We can have each slot with appropriate role (like melee or ranged) and character with another role cannot take it. This approach has some problems like if you have some melee fighters left, but without any available melee slots. In this case, the solution is soft rules. Soft rules mean that each slot has a cost for each type of unit. The problem for AI is to place a unit in such a way to obtain a minimum cost.

There are some algorithms with tricky situations like 3d movement or motor control in the book, but I would not pay attention to it here.

Pathfinding is a huge topic in AI. There are some implementations of Dijkstra and A* in the book. In brief, these two algorithms are similar. They work with directed weighted graphs, and have two lists for nodes they have already visited and nodes they want to visit right now. The difference between these two algorithms is that Dijkstra uses the exact cost for estimation of overall path cost, however, A* uses heuristics for this purpose. There are some optimisations for A* in the book, to increase execution time or memory expenses, but these situations seem like very rare.

The main problem of pathfinding is the world representation because we need to turn the continuous world into the discrete graph. The simplest case here is to turn the world into tiles and use them as the nodes of the graph. The second way is to use Dirichlet domains. It requires the level designer to put some characteristic points into the level. The Dirichlet domain is the cone that cast from the character point down to the bottom of the level. The next way to divide the world is the point-of-view method. In this method, we choose inflexion points near the convex vertices and use it as nodes of the graph. To check if they have a connection we just check if one point is visible from another point by ray casting. The last method is polygonal meshes, where you use each floor polygon as a node.

For huge levels, with different available actions, you can use hierarchical pathfinding. It looks like formations of formations but for pathfinding. It looks like if you need to go from one city to another you have the cities graph on the top of your hierarchy. If you have found a path between cities, you go deeper and try to find the path from your home to the airport. After you found it you start to search for the path to your bus stop and so on. To check where to go in the lower level you need to specify the exit nodes from the level. On each step, you do not need to process all the graph, but only the part that you need to execute now.

It is not necessary to use distance as a cost for pathfinding graph and positions for nodes. There is a solution for continuous pathfinding in the book (where the graph is changing over time) which uses different objects for the nodes and the costs.

The next chapter of the book is about decision making. When AI needs to represent smart behaviour it should decide what it should do next. For this kind of situations, decision trees can be used. The decision tree is the tree with decisions in the leaves and conditions in the nodes. Every edge represents an answer for the node condition. Decision trees should be balanced, and there are couple  algorithms for balancing it in the book. Also, there is an algorithm for the dynamic generating of the decision tree, when AI gets in different situations. The next way to implement decision making is state machines. State machines can be hierarchical and include another state machine as a state. There are tricky moments in the handling of hierarchical state but they are very easy to solve in the exact situation. Decision trees and state machines could be combined to one structure.

States, however, can be not clear and so fuzzy logic comes out. Fuzzy logic supposes that you can be in plenty of states partially. Unlike solid logic, where you do use logic operators like AND and OR, in fuzzy logic, you replace them with min() and max() functions respectively.

In the Goal Oriented Behaviour, every character has its own set of goals and actions that lead to fulfilling some goal. Every action has a positive value for some action and may have a negative value for some another action. The character uses these values to chose the only right decision.

In a rule-based system, you have a database of knowledge and the set of rules. When you parse the database you check which rule should be triggered now.  The most popular algorithm for matching rules is Rete. It represents rules as an acyclic directed graph, where each node of the graph represents some patterns of the rule, that leads to concrete action.

For merging decisions of different decision-making systems, you can use Blackboard architectures. In this algorithm, every decision-making system watches the blackboard where different data is represented. If the decision-making system found something that it needs to change it asks for having a control of the blackboard. Then special arbiter choose which system will have a control in the next iteration gives the control and system make some changes on the blackboard. Then you start again.

The last part of the AI engine is Strategy and tactics. It responds for the group AI behaviour. One of the most common methods in tactical AI is waypoint tactics. The level designer adds the waypoints to the level, that represents, for example, safe location for the characters. We can have different types of waypoints for the same level and then combine it to the graph. We can add the actions that will look for an appropriate waypoint to the decision tree of the character and this will cause smart behaviour. The waypoints can be generating automatically. There are couple ways: you can watch a player's behaviour and detect some waypoints or we can pre-test every point in the game if it is a candidate to the waypoint.

For tactical representation to the level, we can use an influence maps. Briefly, the approach is about calculating military influence for each position in the map. Every military unit has it's own influence formula, that calculates an influence with some decreasing, depending on the distance. For more realistic distribution we can use some algorithms from graphics, like filters (e.g. blur) or cellular automata.

We can force our AI to learn from the situation. We can keep death counter and kill counter for each position in the game, that have some deaths or kills. AI can avoid positions with large death counter, and try to place itself with the position with large kill counter.

For the tactical pathfinding, each edge of the graph will have different weight, depending on the goal of the character. We can tweak heuristics for A* here, for example.

For the group behaviour. it is better to use hierarchical AI. The general AI will issue orders for the army, the commander AI will issue the orders for the group, etc. We can also use the tactical waypoints to represent specific group behaviour (like tactically effective positions for taking a room). Every member of the AI team needs to send a signal about what he going to do now, and others should coordinate their intentions with it.

The next chapter is about learning, about neuro-networks and other stuff. The basic thing that you need to remember here is that in most cases you do not need learning. If you are implementing it, it means that likely you are doing something wrong. Usually, learning is needed before production, to not involve a level designer or a tester for it. But basically it is hard to debug learning algorithms and it can cause some problems. But it can help you to build a decision tree, or make your AI learn from the player.

Next chapter is about board games. There are some set of games, where you can predict every case of play. You can create a graph of all the cases and estimate the best set of moves. For this purpose, you can use minimax algorithm (that will maximise your profit for your turn and minimise it for opponent's turn to predict the overall path of the game). You can also use a technique that called open books. It consists of pre-computed costs of a different set of moves in some database, so for chess, for example, you don't need to force your AI to think in the first few steps.

For the games where you cannot build a tree of the game (because it is very huge) you can generalise some information to the larger cases, and use minimax for not exact moves.

The next set of chapters is about useful techniques that you can apply in your AI engine. First of all is Level of detail technique, that is very common in graphics. The whole point is to use less detail when you don't need. Like, don't use pathfinding in the city that you don't see on the screen. Or you can use only general modelling of some features in the city, like economics or the crime level, but not how these things happened.

The next technique is about world representation and how to build an event system for you AI. There are couple approaches that you can use like broadcasting or register individual listeners, I guess it is quite clear for all. You can also have the event-based approach for sense management, and register listeners for each character. Then either event manager or the character can check all the limitations and decide can the character, for example, hear the sound or not.

You can also find the basic approach to building an AI for each game genre in the end of the book. I will not describe it here because I think it is quite clear what techniques you should use for your own game. There is a very good questionnaire in the book if you have some difficulties with it.

I definitely will use this book if I decide to implement AI in my game. It is a step by step guide for building an AI, so you can actually call it a handbook for every AI developer.




Friday, May 27, 2016

William Golding "Lord of the flies"

It is so astoundingly that for so many years of existing, humanity cannot decide which shape should morality take. "Lord of the flies" tells us about nature of morality and about its connection with a wild human nature. Evil exists within men from our first appearance in the world. It is a wild sense produced by fear and thirst of survival and it is the main enemy of mind and society. "Fancy thinking the Beast was something you could hunt and kill! You knew, didn't you? I'm part of you" - tells the pig's skull to the one of the main heroes. The scene of this "interview" shakes your mind when you read it.  The symbol of the demon who lives inside, who has been created by your fear of the unknown, the lord of the flies lives somewhere inside and tries to swallow you.

We need to understand, that we always have a choice. We can listen to Piggy (voice of the mind) and stay with Ralph as a chief (civilization and society) and keep the fire going (work to have a salvation) or join the tribe of colored savages, hunting, killing and degrading with our own selfishness. It is always hard to choose between a moment of selfish fun and working for the commonweal because the human nature turns you to the first option. Golding tries to say, that you cannot build the society only on rules that seem right to everyone from the reasonable point of view. You always need to count your nature and keep in mind that we are humans, otherwise, the inner evil will become too strong and you wouldn't be able to control it.

"We did everything adults would do. What went wrong?" - asks Ralph when everything he tried to build was breaking down. He hadn't realized yet that he is already an adult, and Ralph, unlike Simon understands it only in the end of the novel. It is a very significant moment, that tells us that the novel is not about the children on the dead island. The novel is about adults in the dead world. The navy officer who rescued children in the last sentences of the book is a great symbol. He saved children from horrid things that were going to happen, he stopped the men hunt, but as the navy officer, he did the same terrible things in his past. Adult rescued kids from the lord of the flies, but who will rescue him?

I want to mention the mastery of William Golding. I don't know how, but I've been there, on the island, with those children. I was Piggy and cried "I have the conch!", I was Jack and hunted the pig, I was Simon and talked with the lord of the flies, and of course, I was Ralph and as an animal ran away from savages in wild, uncontrolled fear. It is magic how while reading a book you can feel the heroes, feel like them, see like them, think like them. You need to be really genius to write like this, and William Golding is. This is one of the most saturated and meaningful novels I've ever read.  

Friday, May 13, 2016

Э. Таненбаум, Т. Остин "Архитектура компьютера", 6-ое издание

Я завершил очередную книгу Таненбаума, и здесь, как всегда, мой конспект. Конспект получился настолько неполным, насколько это возможно и настолько объемным, насколько можно написать в одном посте.

Многое осталось за пределами головы, так как книга очень сложная. Сложилось такое впечатление будто я упустил самое важное. С другой стороны, я узнал очень много нового и закрыл те вопросы, из-за которых начал читать эту книгу. Книга оказалась очень интересной, несмотря на сложность (а во многом и благодаря ей) и я ни разу не заставлял себя читать (наоборот, даже хотел вернуться).

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

Компьютер состоит из связанных между собой процессоров, модулей памяти и устройств ввода-вывода. 

Архитектуру компьютера (так же как и компьютерных сетей) можно разделить на уровни. Самый нижний уровень описывает основные элементы, из которых конструируются компьютеры. В основе всех частей компьютера стоят транзисторы, которые соединяются в вентили. Путем различного соединения транзисторов, можно получить схемы, реализующие логические операции НЕ (если на вход подается напряжение 1В, то на выходе 0В), НЕ И (вход: 1В и 1В, выход 0В, в других случаях 1В) и НЕ ИЛИ (вход 0В и 0В, выход 1В, в других случаях 0В). Соединяя эти основные вентили, можно также получить схемы для И и ИЛИ. Функции преобразования входного сигнала создаются путем различных комбинаций этих вентилей. Модули, полученные путем реализации этих функций, расположенные на куске кремния, называются интегральными схемами.

Следующий уровень называется уровнем микроархитектуры. На этом уровне работают команду в которые интерпретируются команды следующего уровня. Обычно эти команды называются микрокомандами и выполняются они за один цикл (на RISC машинах) или за несколько циклов (на CISC машинах). Уровень микроархитектуры целиком зависит от аппаратной реализации. В книге рассматривается гипотетическая машина IJVM.  Синхронизация операций достигается путем использования тактового генератора процессора. Генератор выдает короткие импульсы, на спаде которого данные загружаются, а на фронте устанавливаются выходные. В промежутке между импульсами операции выполняются. Микрокоманды состоят из набора бит в которых указываются настройки используемых регистров и адрес следующей микрокоманды. Для управления вызовом процедур используется стек. Для оптимизации работы используется прогнозирование переходов, так как команды переходов выполняются дольше обычных. При динамическом прогнозировании, рядом с командой ставится бит, который указывает результат ее выполнения в прошлый раз. В следующий раз используется тот же путь. Если прогноз неправильный - бит меняется. Кроме того, команды могут выполняться не в той последовательности, в которой они пришли (для того, чтобы распараллелить работу и избавиться от моментов простаивания процессора). Выполнение команды до того как станет известно нужна команда или нет называется спекулятивным исполнением.

Уровень архитектуры набора команд является промежуточным звеном между программным и аппаратным обесепечением. Команды на этом уровне состоят из кода операции и некоторой дополнительной информации. Процесс поиска операндов называется адресацией. Существует несколько режимов адресации. Непосредственная адресация означает что в адресной части команды хранится сам операнд (константа в программировании). Прямая адресация - операнд выбирается по адресу. При регистровой адресации вместо адреса указывается регистр. При косвенной регистровой адресации адрес хранится в регистре. Обращение по адресу со смещением называется индексной адресацией. Существует также стековая адресация. На этом уровне вводится понятия потока управления (контекста, в котором выполняется текущая программа, например текущая процедура) и переключателей потока управления: исключений (чаще в случаях ошибок) и прерываний (в случае если ответ медленного устройства нужно срочно обработать).

На уровне операционной системы происходит виртуализация ресурсов компьютера. Сделано это для возможной совместимости с подменой железа компьютера. Виртуальная память позволяет работать с программами, которые "не влезают" в основную память. Виртуальное адресное пространство делится на страницы равного объема, которые отображаются на основную память. В памяти в каждый момент времени находится одна (или несколько) страница, остальное - на диске. Если в памяти хранится больше одной страницы, то участки памяти содержащие страницу называются страничными фрагментами. В таблице страниц находится соответствие между виртуальными и физическими адресами. Сегменты памяти - это подобие страниц, только они могут иметь разный размер. Каждый сегмент обладает своим адресным пространством. Файл - это виртуальная абстракция ввода-вывода. Файл описывается неким дескриптором, метаданными и, собственно, содержимым.

Уровень ассемблера позволяет перевести программу написаную на более-менее понятном языке для человека в машинный код, состоящий из чисел. Языком ассемблера называется язык команды в котором являются точной копией машинных команд, только в читаемом виде. Ассемблер транслирует эти команды в машинный код. Здесь я писать много не буду, так как тема более-менее мне знакома. Напишу только, что ассемблер транслирует программу в два прохода. В первом он собирает все объявленные программистом символические названия и считает их адреса, во втором он транслирует программу в выходной файл. На этой же ступени работает компоновщик, который из нескольких модулей генерирует выходной бинарный файл.

Процессоры предназначены для выполнения команд находящихся в основной памяти. Мозгом компьютера является центральный процессор. Ключевым понятием для работы процессора является тракт данных. Тракт данных состоит из входных регистров, арифметико логического устройство (АЛУ) и шин. Шины используются для передачи данных. Процессор принимает данные в регистры, проводит нужную работу в АЛУ, а затем отдает результат в выходной регистр. Процессор, ориентированный на поддержку как можно большего числа различных команд, называется СISC процессором, а процессор ориентированный на параллельный запуск как можно большего числа различных команд (при это набор команд исполняемых процессором гораздо меньше CISC системы) называется RISC процессором. Для выполнения команд в параллельном режиме используются конвейеры. Суть конвейеров заключается в том, что пока выполняется одна ступень исполнения команды, занимающая одну часть процессора, одновременно может выполняться другая часть команды, занимающая другую часть процессора. Например во время выборки следующей команды, параллельно на АЛУ может выполняться предыдущая. Существуют суперскалярные архитектуры. Суперскалярные архитектуры поддерживают либо несколько конвейеров одновременно, либо один конвейер с несколькими функциональными блоками на одной ступени (например, вместо АЛУ на ступени исполнения команды могут быть несколько АЛУ и блок отвечающий за операции над числами с плавающей точкой). Таким образом обеспечивается еще большая параллельность. RISC процессоры работают гораздо быстрее CISC процессоров. несмотря на то, что в RISC процессоров одна команда выполняется дольше, засчет параллелизма выигрыш во времени гораздо выше. Существуют также SIMD процессоры, которые состоят из большого числа схожих процессоров и выполняют одинаковые инструкции для разных наборов данных. Для ускорения обращения к памяти процессоры используют кэши. Кэш может отображаться на память прямо, таким образом память поделена на строки, определенного размера, имеющие адреса. Кэш хранит прямое отображение строк с мета-информацией, позволяющей понять какая именно строка лежит в кэше. Кэш может быть устроен как таблица, тогда для каждого адреса будет храниться n-строк. Это n-входовая ассоциативная память. Кэш может разделяться на кэш данных и кэш команд.

Для выполнения сложных вычилсительных задач используются мультипроцессоры и мультикомпьютеры. Мультипроцессоры - это несколько процессоров делящих одну память. В мультикомпьютерах каждый процессор обладает своей собственной памятью. Проблемы при организации мультипроцессорах встречаются в согласованности кэшей.  Мультипроцессоры делятся на типы в зависимости от доступа к памяти. UMA мультипроцессоры имеют одинаковый доступ к основной и локальной памяти, NUMA мультипроцессоры к локальной памяти обращаются быстрее, CC-NUMA работают с кэшами. Мультикомпьютеры, чаще всего, объединяются по локальной сети.

В памяти компьютера хранятся программы и данные. Память состоит из ячеек, которые, в свою очередь, представляют собой набор бит. Все ячейки в памяти имеют одинаковый размер, а также свой адрес. Современные компьютеры, в основном, работают с 8-разрядными ячейками (байтами). Ячейки объединяются в слова (чаще всего по 32 бита и по 64 бита). Большинство команд работают со словами. В памяти также хранится избыточная информация, для контроля правильности данных (контрольные суммы). Процессоры обладают своей небольшой памятью, которая называется кэш-памятью. Доступ к ней гораздо быстрее, чем к основной памяти компьютера, поэтому часть основной памяти копируется туда, для увеличения быстродействия. Так как место на плате процессора ограничено, кэш-память не может быть большого объема. В качестве памяти также могут выступать магнитные диски (жесткие диски), SSD, CD/DVD/Blu-Ray и т. д. Доступ к ним осуществляется дольше всего. Запись на магнитные диски осуществлется с помощью вращения диска под магнитной головкой. Дорожкой называется последовательность битов, записанных за полный оборот. Дорожка разбита на секторы. В одном жестком диске может быть несколько магнитных дисков. Набор дорожек, находящихся на одном расстоянии от центра, называется цилиндром. Диски можно организовывать в RAID массивы. Это наборы дисков, которые воспринимаются как один большой диск. SSD работают с помощью зарядки или разрядки транзисторов, оставляющих их всегда во включенном/выключенном состоянии.

Память состоит из защелок и триггеров. Защелки и триггеры это вентильные схемы, сохраняющие свою конфигурацию в течение определенного промежутка времени. Триггеры и защелки, как правило, одноразрядные. Из восьми таких элементов можно построить восьмиразрядный регистр. Для основной памяти используются немного более сложные схемы. На вход им подается адресный сигнал, состоящий из количества бит, необходимого для адресации всего адресного пространства и необходимые флаги, показывающие был ли дан сигнал для чтения или для записи. На выходе, соответственно, появляется необходимое значение. Существует два вида памяти - ОЗУ и ПЗУ. ОЗУ работает все время, пока к нему подается питание. ОЗУ может быть статическим (работает быстро) и динамическим (большой объем). Для ПЗУ питрания не нужно. Существует несколько типов ПЗУ, но я не считаю важным описывать это здесь.

Соединение компонентов компьютера осуществляется с помощью шин. Шина - это несколько проводников, соединяющих несколько устройств. Шина содержит адресные линии - чем больше линий, тем больший объем памяти можно через нее адресовать. Также существуют информационные и управляющие линии. Так как сигналы на разных линиях передаются с разной скорость возникает расфазировка шины. Чем больше скорость шины, тем больше расфазировка. Шины бывают синхронными и асинхронными. Синхронная шины содержит линию, которая запускается тактовым генератором. Любое действие шины занимает целое число циклов. Синхронная шина работает на скорости самого медленного устройства в паре. Асинхронная шина не содержит тактового генератора. Она работает засчет подачи определенных сигналов, символизирующих о завершении какой-либо операции (например после установки адресных линий, или после окончания считывания данных из памяти). Устройство которое посылает запрос по шине называется задающим, а принимающее подчиненным. Если существует несколько задающих устройств в один момент времени используется арбитраж шины. Арбитраж может быть централизованным или децентрализованным. При централизованном специальное устройство, с помощью определенной стратегии (на выбор разработчика шины) решает какое устройство воспользуется шиной в данный момент времени. При децентрализованном арбитраже, сами устройства решают кто будет передавать запрос (либо прослушивая линии запроса, либо работая с выделенной линией занятости шины). За раз шина может передать одно слово. Так как выгоднее передавать слова блоками, шина передает одно слово в цикл, до тех пор, пока не передаст целый блок данных.

Числа с плавающей точкой представляются в виде f * a^e, где f называется матиссой, е - экспонентой, а в качестве основания берется 2, 8 или 16. В зависимости от стандарта число записывается в виде 32 разрядного числа, первые несколько из которых представляют экспоненты, а оставшиеся матиссу. Точка находится перед матиссой. Нормализованный вид матиссы достигается путем сдвига влево до тех пор, пока первый бит не станет равным 1, а от экспоненты отнимается количество сдвинутых бит. 


Saturday, March 26, 2016

Виктор Пелевин "Generation П"

Я сначала хотел написать рецензию на книгу, поговорить об идее, о том, как автор изложил ее, о персонажах и прочей литературной мишуре, какой обрастает каждая рецензия. Но потом подумал - зачем? Я пишу эти посты, для того, чтобы через много времени смог вспомнить о том, что из книги узнал. Так уж получилось, что "Поколение П" не представляет абсолютно никакого литературного интереса, о чем уже высказывались многие критики. Текст, действительно, набит штампами, стилистическими ошибками, лишними словами и персонажами, поэтому подчерпнуть в ней что-то новое для себя, как для писателя, наверно, нельзя (разве что расценивать ее как негативный пример). Несмотря на все это, я с упоением прочитал книгу довольно быстро, практически не отрываясь, улыбаясь в некоторых местах, и, даже, удивляясь в других. Поэтому здесь будет скорее вихрь мыслей, что закрутился у меня в голове, после и во время чтения.

Наверно, основная моя проблема с "Generation П" - это то, что я не из этого поколения. В 90-ые я был еще совсем маленьким, в 98-ом только пошел в школу, а размышлять о взрослых проблемах начал только к середине двухтысячных. Мое поколение не претерпело такого ужасного потрясения как разрушение идеалов, у нас не было переломного момента, когда мы услышали, что все, что было плохо теперь хорошо (пусть подсознательно и подозревали об этом). У нас не было пустых полок в магазинах, которые потом заполнились запретными (ранее) плодами. Мы уже росли на запретных плодах, слыша повсюду слово секс, жуя сникерсы и турбо, нося кросовки и джинсы и, передавая друг другу порно, на жетских дисках и по локальной сети, измеряя его в гигабайтах.

Конспирологическая мысль о заговоре, которую Пелевин так рьяно старается разрушить в своем произведении, касалась наших ушей только эхом от "совковых" взрослых. У некоторых она отпечаталась сильно, у других (как у меня например) она не отпечаталась вообще. Следующее поколение должно уже не понимать пелевинского Татарского и поиск короля Симурга воспринимать как что-то необъяснимое. Но, безусловно, для людей, переживших потрясение разрушения иделов, моральных и философских принципов, незыблемых до определенного момента, это книга будет являться открытием.

Я выделил для себя три проблемы. Первая, пусть никогда в таком виде и не употребляется в книге, но звучит как "у меня должно быть как у людей или лучше". Идеалы заменились материализмом, черную пустоту, образовавшуюся после того как коммунизм выдрали с корнем из советских душ, стали заполнять вещи и деньги, явившись новым тотемным богом. Пусть неосознанно, но люди сами проглотили нить потребления, и, в ужасной гонке за несуществующим богом, забыли о том, что кроме потребления, нужно что-то еще и производить. Это формулирует вторую проблему, которая в книге обрастает бесконечным поиском национальной идеи. "Ничего не производим, только потребляем", что собственно и является прямым следствием попытки заполнить внутреннюю пустоту.

Легенда о короле Симурге красной нитью прошивает историю о Вавилене Татарском. Бесконечный поиск "Кто во всем виноват?" и "Кто за всем стоит?" перемежается с легендарным поиском стаей птиц своего короля Симурга. Оканчивается все довольно просто, Симург, в переводе, означает "стая птиц" (ну или тридцать птиц, как в книге), этим автор доносит до нас, что и во всех проблемах людей виноваты сами люди. Татарский становится живым обличием бога и, как собирательный образ типичного представителя поколения П, говорит нам, что все представители поколения П мужья Иштар, все они творят судьбу своими руками, следуя за невидимым золотым идеалом, который придумали сами. Такой удав, кусающий себя за хвост.

Да, я абсолютно согласен с мыслью Пелевина. Мне понравилось ощущение погружения в 90-ые глазами взрослого, а не глазами ребенка. Но мысль не из моей головы и не про меня. Будто радиоэфир дошедший из другой планеты - интересно, но ни о чем. Хочу сказать спасибо автору за несколько действительно развлекательных часов подаренные мне книгой. Прочитайте "Generation П", может, найдете что-то для себя.


Saturday, March 19, 2016

Scott Rogers "Level Up! The Guide to Great Video Game Design"

Well, I've got a lot of pleasure from reading this book. It's short and funny, full of cute illustrations, that sometimes put a little smile on your face. If you are a gamer with a huge experience (like me) you definitely already know the majority of things, that "Level up!" explains to a reader like what genres of games are exist, how enemies should behave, what camera type should you use, etc. However "Level up!" is not an overview of game types and game parts, it is like a manual, full of useful adviсes, and helpful ideas if you get stuck while developing your own game. There are some lists of features that you can add (like possible environments for your level), examples of documents and presentation that you need to show to a publisher or to make development easier for your team. So, if you are keen on game development, want to know how people create the games or even want to get new ideas for your own game, this book is definitely for you. Here are some ideas, that I learned from "Level up!", you can read it as well and decide if this book is worth reading for you.

The first thought from the book, that I considered very useful is that if you want to generate new interesting ideas, you should do things, that you are not doing in your casual life. You should read books about things that you never thought before (like gardening for me, or history of Bhutan, or even tutorial for plumbers) to expand your purview and get ideas from different fields. You should be curious and always learn something new to get interesting ideas.

If you stuck and cannot get any idea from your head, you should take a break. It is a very simple point, but not very obvious. Even my experience shows that breaks work well for your mind. Sports even better. When you sit all day blood doesn't circulate in your veins actively and your brain doesn't get a proper amount of oxygen. Let's jog!!

One more idea is about children. When you make a game for children, be sure that children want to look older, than they are. You should sell a game for 13 years old children to 10 years old children, for 15 years old to 13 years old etc. The worst thing that you can hear from a child about your game is "This game is for my little brother!"

Next thought is about story in a game. Gameplay is meat and story is salt. You need an exact amount of story to make a game feel tasty. Plot twist should occur every 15 minutes, you also need to have a start, middle and the ending of the story. There are a lot of scripting twists, to make your story  feel more exciting but I guess it is a theme for another book. There is the triangle of weirdness (which consists of characters, activities, and the world) and you should have only one weird thing from three. If you have more than one, player would be confused and frustrated and will turn your game off.

Game design is about creating an experience for players. I was really amazed when I've read about Left for Dead AI. It measures the stress level of the player (it depends on various parameters, like a current health of the player, his skill, his behavior etc.) and controls the enemies spawn speed, ammo spawn speed, difficulty and even music to make your experience more exciting!

Paperwork is what you need in any job. As a game designer, you need to provide the full vision of your game to all other people, like a publisher or other members of your team. It is hard because no-one interested in it and you have to inspire all people around. For this purposes, you need to be inspired yourself and understand how your game will work. Game Design Document here can help you. First, you need to create a one-pager document with all basic concepts, like title, genre, ESRB, and unique selling points (it is what you see on a back of the box with your game). Then you need to create a ten-pager, that  contains more detailed information about your game, about a story, about game mechanics, and other stuff. Then Game Design Document comes in with full information of enemies, of their attack patterns, with examples of animations and weapons art, etc. There are examples of all these documents at the end of the book, so when you decide to create it, you have a place to search.

Few words about the characters in computer games. They should look stereotypically (because a player needs to adjust his play style to the character and you shouldn't confuse the player) but act with personal features. If your character is a barbarian he definitely must  open doors with a powerful kick, not silently as a mouse. You can also add some traits, like fear of water, or something, but do not forget to add proper animation, when a character meets water.

In the chapter about level design author often mentions Disneyland and attractions in it. Designers of Disneyland worked hard to make attraction excited to visitors and we have something to learn from them. First of all - walking is not a gameplay. If you describe part of your level like "And now the character walks from point A to point B", then you need to remove this part from your game. Second, a level should tell the story, and teach a player. A player can learn how to use this particular mechanic in your game, or how to use weapon, or how to defeat exact enemy, and you need to be sure, that you teach player something. If not - just remove the level from your game. You shouldn't place two levels with a similar environment or/and gameplay next to each other. To see would it be boring or not you can create a beat chart (there are some examples in the book) on a piece of paper and remake your level concepts without wasting a time of developers.

Last useful thing, that I've learned from the book is that you need to make your players hate their enemies. Your bosses should bother them maybe at the start of the level, make their life difficult, so your player would get much more satisfaction from killing the boss, than if he just thing about a boss like about an obstacle.

I will reread this book, I guess multiple times, because I am developing a game now, and will do it (for the rest of my life, I guess), to get some advice and recall some important stuff. If you like games as I like it, you would definitely like this book.

Saturday, February 27, 2016

Douglas Adams "The Hitchhiker's Guide To The Galaxy"

Hi all, today we will talk about ultimate comedy science fiction series "The Hitchhiker's Guide To The Galaxy". This post is in English because the book that I've read was in English. The "Guide" is the series of five books (sometimes called "trilogy in five books") and for February, I planned to read only one (the first) book from the series. But it was too short, and I finished it on 15-th of February (plus minus one day) so I decided to read the second book "The Restaurant at the End of the Universe". Honestly, I wanted to read three books (I thought to complete the story) but didn't have time for the third book till the end of the month.

So the series tells us about space adventures of four main heroes - Arthur Dent from the Earth, his friend Ford Prefect, from a nearby vicinity of Betelgeuse, the president of the galaxy Zaphod Beeblebrox, and Trillian from Earth. The book imbued with waspish sarcasm and satire, and even I laughed in some places (there are very few books that I really laughed at, so this book is really fun).

The main idea that comes through all the plot is that our Universe is ultimately huge and we ourselves are ultimately small, as our problems and our thoughts. We live in our closed world, and even inside we close our mind to everything else, except our way from work to home and some minor difficulties on it. People started to think, that this bounded world is exactly the whole Universe, and it spins around them. The boundness of people precisely reflected in Ford Prefect's question about humans: "Why do they continue to say obvious things like "The weather is good today"?" He tried to compare humanity with highly developed race, that had telepathic abilities and every representative had to say obvious things aloud to not think about something important, not to give this information to others. But this theory didn't fit well to humanity and answer to this question was a puzzle for Ford. So people are blind in their isolated Earth, and in small worlds that everyone built for themselves, but if we open our eyes, we will see an infinite world of opportunities, the whole universe, full of different business, lifeforms, ways of think, points of view, and something, that we couldn't imagine. 

Arthur Dent is the man, who occasionally opened his eyes, because of his friend Ford Prefect. He travels the galaxy and surprises every new thing, that can be deadly dangerous or remarkably pleasant. His companions, Zaphod Beeblebrox and Ford Prefect have an understanding of how the Universe work, and act like conductors for Arthur to this huge new world. Despite the main plot tells us about ultimate questions about the meaning of life, I think, the author wants to tell us that it is useless and completely unworthy to search the dim answer, or dim question itself. I didn't finish the main plot because read only two books out of five, but it seems like the main idea is that true meaning of life is to learn and to be happy, to be curious and get a pleasure from your curiosity, to act and not to think or wait and always expand your bounds. Zaphod and Ford live exactly according to these rules and doing only stuff that they like. They understand, that they are too small and the universe is too large and that all in the universe are bounded, and they are completely okay with that, because they just doing things, that they want to do.

I will definitely read all five books in future, I've already added it to my reading queue for next years. I strongly recommend the series to all young people from 14 to 30 (and all other ages too, but for these ages it will be very exemplarily) and I also recommend to read these books in English, because English there is very easy and lightweight, you will understand the language without any troubles and you will learn a lot of useful new words, that, I guarantee, you didn't know before, so please read it to improve your English, if you are beginner in it. Read more books and learn more stuff, see you in my next posts!

Monday, February 22, 2016

Задачи

Я вот задумался о смысле математики и учебы в целом. Когда в школе/университете решаешь задачи, приходится напрягать мозги. Задачи не решаются так просто: тебе нужно взять все знания конкретной области в кулак, подойти к задаче с разных сторон, несколько раз зайти в тупик, а потом триумфально выйти из лабиринта с головой минотавра в руках. Задачи имеют один ответ, и, часто, одно или несколько решений, которые либо одинаковы, либо одно явно лучше другого. Когда твоя жизнь состоит целиком из решения математических задач, как например в студенческие годы, головы решенных минотавров уже некуда девать, блуждание по лабиринтам кажется скучной рутиной, победы перестают быть радостью и вчерашний герой начинает рефлексировать в поисках смысла жизни. Для чего я решаю задачи? Где мне это понадобится? Пошло оно все к черту, скучное, бесполезное занятие, бросаю институт и иду работать!
Тут-то и начинается самое сложное. Работа (в подавляющем большинстве случаев) как раз и есть ежедневная скучная рутина. Отличие в том, что задачи, возникающие в повседневной работе, например, программиста, отличаются от тех, что решались сотнями в универе. Здесь задачи неоднозначны, решений множество, ответов множество, а плюсов и минусов, часто по-ровну, как сторонников и противников этого решения. Выбор того или иного решения превращается в жаркий спор, выбор между временем разработки и его качеством превращает твое любимое дитя-проект в гадкого уродца, которому ты яростно клянешься в том, что все исправишь.

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

Saturday, January 30, 2016

Э. Таненбаум, Д. Уэзеролл "Компьютерные сети", 5-ое издание

Я наконец-то дочитал эту действительно сложную для меня книгу. 930 страниц А4 следовало прочитать за месяц, причем прочитать вдумчиво, чтобы в голове что-то осталось. Кроме того, в конце каждой главы был список задач. Для лучшего усвоения материала я решал эти задачи. Сначала я пытался решить все, но потом понял, что это занимает много времени, а пользы от этого немного, поэтому я решал 10% задач после каждой главы (это обычно 4-5 задач). Минусы задач были в том, что ответов на них не было (в интернете тоже особо не найдешь), некоторые ответы были в главе, но до других надо было дойти самому, или посчитать самому, а свериться было не с чем. Я читал по 30 страниц в день (иногда получалось больше) в три подхода - 10 по дороге на работу, 10 на обеде, 10 по дороге домой. Книга шла довольно тяжело, некоторые абзацы (я бы сказал 90%) приходилось перечитывать по нескольку раз, так что я смело могу утверждать, что я прочитал ее, как минимум, три раза. Некоторые вещи я, конечно же упустил, но это не страшно, ведь я не собираюсь проектировать сети или работать с ними каждый день. Моя цель была закрыть пробелы в знаниях и размять мозг и эти цели, я думаю, были на 100% выполнены. Ниже находится мое краткое изложение книги, чтобы структурировать полученные знания и вспомнить, когда понадобится (скорее всего через год перечитаю этот пост). Для проходящего читателя тут, скорее всего, полезной информации не будет, но если вы бегло хотите понять стоит ли это книга того, чтобы читать, возможно мое изложение вам поможет. От себя хочу добавить, что без знаний математики и хотя бы азов программирования браться за нее не стоит. Книга написана с долей юмора и интересными историческими справками (порой, тоже с долей юмора). Книга не научит вас проектировать сети, здесь можно найти общие знания, так сказать, фундамент, который вам пригодится если вы будете работать с ними напрямую или косвенно. Если вам нужны более подробные темы, советую заглянуть на последние страницы, там приведена масса литературы с довольно интересными пояснениями для чего и кому это нужно читать. Лично я добавил несколько книжек в свою бесконечную очередь для прочтения. А теперь приступим к изложению.

Книга представляет из себя довольно объемный и подробный обзор структуры и принципов работы компьютерных сетей.  Конечно, очень много материалов осталось за рамками этой книги, просто потому что сама область довольно большая и по каждой мелкой детали, упомянутой у Таненбаума одним предложением, найдется отдельная книга на 900 страниц, но и этого достаточно, чтобы понять основны и понимать, что же происходит вокруг тебя каждую наносекунду в вечно бурлящем эфире и судорожно напряженных проводах.

Книга разделена на главы, каждая из которых (за исклюением двух) посвящена отедльному уровню сетевой модели. Краткий обзор существующих, наиболее популярных сетевых моделей (TCP/IP и OSI) дается во введении. Вкратце, сетевые модели делятся на уровни, для того чтобы разделить ответственность в сложной структуре, сделать сеть масштабируемой (то есть легко расширяемой на более сложные варианты) и гибкой (то есть, чтобы сеть не ломалась, если вдруг перевести ее с коаксиального кабеля на передачу с помощью радиоволн). Каждый уровень можно описать как протокол + интерфейс. Протокол предосталяет способ общаться одинаковым уровням получателя и отправителя, в нем определяется в каком виде будет происходить обмен данными и как будут выглядеть данные. Интерфейс предоставляется нижним уровнем верхнему в обе стороны, чтобы нижний уровень одного устройства, смог забрать данные у верхнего уровня того же устройства, обработать их и передать более нижнему уровню. В книге рассматривалась обобщенная, довольно обоснованная сетевая модель, учитывающая недостатки и TCP/IP и OSI. Модель поделена на 5 уровней (от нижнего к верхнему): физический, канальный, сетевой, транспортный, прикладной. Есть еще два, рассмотренных отдельно подуровня: подуровень управления доступом к среде (подуровень канального уровня) и не всегда существующий подуровень безопасности (SSL работает между прикладным и транспортным уровнем).

Физический уровень отвечает за то, как будут переданы данные в физической среде. Он оперирует битами данных, которым соответствуют некоторые уровни напряжения (например 3В это 1, 0В это 0). На физическом уровне решается что будет использоваться в качестве переносчика информации: коаксиальный кабель, оптоволокно, UTP (существует несколько версий этого кабеля),  или же беспроводные переносчики, такие как радиоволны на разных частотах. У каждого из этих способов есть свои проблемы, влияющие на стоимость реализации, способы передачи, количество ошибок. Например оптоволокно очень дорогое и хрупкое, а для UTP нужны повторители через каждые сколько-то метров (зависит от версии), поскольку сигнал в них затухает. Частот радиоволн ограниченное количество, их нужно распределять между разными сетями, кроме того, бытовые приборы, такие как микроволновая печь, могут вносить существенные помехи, а некоторые длины волн не проникают сквозь стены. Физическому уровню также требуется избавляться от шума в каналах. Для того чтобы устанавливать надежный двухсторонний канал связи, физический уровень использует различные методы уплотнения данных. Например, в структуре, где провайдер посылает данные на распределитель, а затем от распределителя данные приходят к каждому клиенту, нужен метод который будет соединять данные для всех клиентов в один поток. Для этого используется временное уплотнение, частотное уплотнение и амплитудно-фазовое уплотнение. Мне, в частности, было особо интересно как работает мобильная телефонная сеть, описанная в этой главе. 5-ое издание довольно старое, и об LTE там говорили как о приходящей технологии, тогда как сегодня на каждом шагу можно подключиться к сети четвертого поколения. 1-ое поколение мобильных сетей было аналоговым, все последующие поколения были цифровыми. Системы второго поколения уже использовали CDMA (метод уплотнения, в котором символы кодируются так, чтобы при ошибках в нескольких битах символ все-равно был бы распознаваем), но GSM, самая распространенная система, использовала TDM, предоставляя каждому каналу временной интервал для работы. Третье поколение уже полностью работала на CDMA. В мобильные сети большую роль играют телекоммуникационные вышки, которые делят зону покрытия на соты. Каждая вышка отвечает за всех абонентов в своей соте, когда абонент переходит из одной соты в другую происходит процедура передачи. В старых системах, предыдущая вышка переставала обслуживать абонента, а новая принимала его, в новых сетях порядок обратный.

В обязанности канального уровня входит обработка ошибок передачи данных и управление потоками данных, исключающее затопление медленного приемника более быстрым передатчиком. Канальный уровень оперирует кадрами. Кадр формируется когда канальный уровень получает данные от более высокого сетевого уровня. Данные сетевого уровня оборачиваются в заголовок, содеражащий информацию в зависимости от используемого стандарта (который в свою очередь зависит от используемого физического уровня) и концевик (мне не нравится это слово, но я не знаю как перевести лучше), который часто содержит контрольную сумму, для проверки или устранения ошибок на приемнике. Существует несколько способ разграничения кадров, самый надежный, это использование флагового байта, символизирующего окончание кадра, однако если такой же байт попадется в тексте сообщения, нужно поставить перед ним ESC-символ (перед каждым ESC-символом, случайно встретившимся в тексте, кстати, тоже). После того как данные были приняты все ESC-символы удаляются, остаются только чистые данные. Контроль ошибок обеспечивается с помощью контрольной суммы. Выбор способа расчета контрольной суммы зависит от надежности канала. Если канал надежный, дешевле будет переслать кадр в случае ошибки, чем добавлять к кадру лишние данные для исправление ошибок. Если канал ненадежный, то лучше переслать больше данных, чтобы исправить ошибку на получателе, чем забивать пропускную способность сети постоянными пересылками ошибочных кадров.

Подуровень управления доступом к среде занимается проблемой распределения доступа к физическому каналу между конкурирующими машинами. Существует много способов, зависящих от физической среды передачи данных, количества конкурирующих машин, топологии сети и т. д. Один из самых простых, например, когда все пытаются отправить данные, и если возникла коллизия (то есть данные от нескольких машин столкнулись и не дошли до получателя, о чем свидетельствует, чаще всего, ответ от получателя), машины ждут случайный промежуток времени и отправляют данные еще раз. Такой метод крайне не эффективен в плане использования сети, поэтому были разработаны методы с прослушиванием линии. Если машина определяет, что кто-то уже передает, она не начинает передачу. В беспроводных сетях это порождает новые проблемы: проблема засвеченной станции, когда станция передает, но не той машине, которой хочет передать текущая станция (тогда текущая думает что линия занята и передавать нельзя) и проблема скрытой станции (когда одна станция, не может слышать как передает другая из-за слишком большого расстояния и начинает передавать, из-за чего случается коллизия). В таких случаях применяется более сложный протокол, который пытается не определить коллизии, а избежать их. В этом случае передающая станция посылает запрос на передачу, а получающая посылает ответ, в итоге все всё слышат и понимают, что передавать не надо. В таких случаях тоже случаются коллизии, но гораздо реже. В этой же главе рассматривались протоколы ethernet (много его разновидностей), 802.11, 802.16, Bluetooth, RFID, но о них я уже писать не буду, в большинстве своем там слишком подробное описание кадров с помощью которых они общаются и название тех решений, из вышеописанных, которые применяются в данных сетях. Очень жаль, что я это не запомнил, возможно это и было самым важным в данной главе. Когда буду перечитывать этот пост, запланирую себе перечитать эту часть.

Сетевой уровень решает как ему доставить пакет данных от получателя к отправителю, через кучу промежуточных машин, чтобы не перегрузить сеть и не потерять данные. Сетевой уровень может работать с установлением соединения или без. В случае установления соединения маршрут по которому будут идти все пакеты данных выбирается заранее. Если по пути выйдет из строя какой-нибудь маршрутизатор, канал будет недоступен и придется его восстанавливать, выбирая другой маршрут. В случае отстутствия соединения маршрут выбирается для каждого пакета отдельно, что делает этот метод устойчивым к выходу из строя какой-нибудь промежуточной машины. IP - это протокол сетевого уровня и он работает без установления соединения. Существует несколько алгоритмов нахождения кратчайшего пути. Один из них - это алгоритм Дейкстры (когда у каждого пути есть вес, зависящий от заполненности канала, или от скорости передачи данных на нем) использующийся в сетях. Один из вариантов обмена информации о путях между машинами сети это метод заливки. Все маршрутизаторы в сети посылают всем соседям известную информацию о сети с заданным интервалом времени. Одна из проблем возникающих при использовании этого метода это зацикленные пакеты и огромное количество дубликатов. Для решения этих проблем используются разные стратегии, например помещение счетчика жизни в заголовок пакета. Большая проблема в работе с сетевым уровнем это контроль перегрузки. Самым эффективным методом является ограничение более быстрого передатчика по минимальной скорости канала, но это решение должно приниматься на более верхнем уровне. На сетевом же используется метод маршрутизации по наименее загруженным каналам, часто используются такие стратегии как маркерное ведро или ведро с дыркой. Ведра помогают ограничивать скорость более быстрого источника. Суть в том, что маршрутизатор принимает на скорости отправителя, а выпускает со скоростью получателя. В случае переполнения ведра, он сообщает отправителю, чтобы тот перестал передавать. 

Каждый маршрутизатор обладает очередью пакетов, как только очередь переполняется, маршрутизатор начинает отвергать пакеты. Отверженные пакеты являются основным сигналом о перегрузке. Для того чтобы определить перегрузку на ранних стадиях, маршрутизатор начинает отвергать случайные пакеты, когда его очередь забита не полностью, а до какого-то уровня (например на 2/3). Тогда есть возможность определить и устранить перегрузку до того как она стала слишком сильной. Бывает трафик настолько важный (как например голосовая связь), что нельзя отклонять пакеты от него. В таком случае используются специальные указатели качества обслуживания. Например на маршрутизаторе добавляется приоритетная очередь и она обслуживается первой при освободившейся пропускной способности. Провайдеры могу взымать за эту услугу дополнительную плату. 

Основным протоколом, работающими в интернете на сетевом уровне является IP. Сейчас большинство сетей используют IPv4, но его проблема в том, что адресного пространства для индивидуальных компьютеров слишком мало (используется 32 бита на адрес) и не хватает адресов для всех. Для этого были созданы разные методы, которые позволяют переиспользовать IP-адреса, такие как NAT, но это противоречит основной идеологии многоуровневой сетевой модели (хотя и обеспечивает надежный и работающий сервис). Для решения этих проблем был разработан новый стандарт IPv6, он уже включает 128-битный адрес, но полностью несовместим с протоколом IPv4, поэтому перейти на него довольно сложно.

Интернет состоит из очень многих связанных сетей, разных типов и размеров, для маршрутизации в нем используются свои протоколы, такие как OSPF и BGP, для маршрутизации пакета внутри подсети и вне соответственно. Для передачи пакета из одного типа сети в другую, часто используется туннелирование. В этом случае пакет одной сети заварачивается полностью в пакет другой сети (можно провести аналогию с поездом, который везет в вагоне автомобиль) и на выходе извлекается и передается как раньше.

В мобильных сетях (опять же более интересующий меня вопрос) способ маршрутизации несколько отличается. Каждый мобильный клиент обладает домашним хостом. Если мобильный клиент меняет местоположение, он сообщает своем хосту о том, где находится. Вызывающий клиент запрашивает вызов у домашнего хоста вызываемого, тот транслирует вызов на текущий хост мобильного клиента, а тот мобильному клиенту. Мобильный клиент, затем, устанавливает прямой канал связи с вызывающим клиентом.

Транспортный уровень обеспечивает пересылку данных от машине к машине так, как будто связь между ними установлена напрямую и никакой сети между ними нет. Транспортный уровень может также работать с установлением соединения (TCP) и без (UDP). Транспортный уровень общается с помощью сегментов (я так понимаю, потому что лучшего названия придумать не смогли). TCP обеспечивает надежную пересылку данных с контролем ошибок и контролем перегрузки сети, UDP кладет на это хуй (сомневаюсь, что кто-то дочитал до этого момента, поэтому могу себе позволить).  Транспортный уровень работает с помощью сокетов. По сути, сокет для пользователя ничем не отличается от файла: программа открывает его, получает файловый дескриптор, пишет туда данные и получает положительный ответ или уведомление об ошибки записи. Чтение из сокета происходит точно также. Отчличие только в том, что записанные данные отправляются по сети через маршрутизаторы к другому хосту, который может находиться на другом конце света. Поверх TCP и UDP еще используются протоколы для передачи медиа данных (например видео или видео в реальном времени). Адресация у TCP используется с помощью портов. Сущесвтует множество зарезервированных портов (так 80-ый порт используется для работы web-сайтов через HTTP), вроде их 1024, остальные (65536 - 1024 = 64512 ) можно использовать для своих приложений. Когда сетевой пакет приходит к конкретному хосту, из TCP сегмента изымается номер порта и программе, которая прослушивает данный порт передаются необходимые данные.

Прикладной уровень это то, с чем имеют дело обычные люди чаще всего. Он включает в себя протоколы для работы с электронной почтой (например SMTP), протокол передачи гипертекста (HTTP) и доменную службу имен (DNS). Поподробнее расскажу про DNS, потому что про остальное мне и так известно, так как имею дело с этим каждый день. DNS существует для того, чтобы люди могли вбивать в адресную строку браузера не непонятные цифры IP-адреса, которые невозможно запомнить и кроме того постоянно меняются, а знакомые всем буквы. DNS хранит у себя таблицу записей о том какому IP-адресу какое имя соответствует и еще кучу разной информации. Все домены поделены на уровни. Верхние уровни, это доменные зоны стран, такие как .ru .uk .sg и прочие, а также всем известные .com .org .net .edu. Домены второго уровня это любое незанятое слово, которое вы хотите использовать для вашего сайта. Каждый домен управляет доменами уровнем ниже. Процесс поиска адреса по имени происходит следующим образом: хост, пытаясь найти имя получателя, опрашивает свой региональный доменный сервер, знает ли тот, какому IP-адресу принадлежит данное имя. Если в кэше этого сервера нет данного имени он опрашивает верхние домены и так пока цепочка не дойдет до корневого сервера. В следующей главе была описана атака на DNS кэш, когда злоумышленник в ответе на запрос его домена, отвечает, в дополнительной информации, что этот же IP-адрес используется и для любого другого доменного имени (например vk.com).  DNS сервер жертвы кеширует это у себя и, как только жертва захочет посетить vk.com, она посетит страницу злоумышленника.

Последняя глава рассказывала о безопасности в сети. Для обеспечения безопасноти используются различные методы шифрования. Все методы шифрования можно разделить на два типа: замена и перестановка. Шифрование с заменой заключается в том, что каждый символ исходного текста заменяется каким-нибудь другим символом. Шифрование с перестановкой заключается в перестановке исходных символов местами. Все алгоритмы шифрования так или иначе используют один или комбинацию этих способов. Одним из самых эффективных методов шифрования считается одноразовый блокнот. Суть заключается в том, что ключ это битовая строка, равная по длине битовой строке текста. Шифрование получается в результате операции XOR между двумя этими строками. Проблема в использовании этого шифра заключается в способе передачи ключа от отправитея к получателю. В качестве одного из способов передачи можно использовать квантовую криптографию (довольно сложно реализуемую для простых смертных). Суть заключается в том, что отправителем выбираются значения поляризации света, соответствующие битовому ключу, например за 1 будет отвечать диагонально направленый фотон слева направо и вертикальный, а за 0 диагональный справа налево и горизонтальный. Получатель выбирает случайную комбинацию поляризаторов перепендикулярных друг другу (вертикальный-горизонтальный и такой же, но повернутый на 45 градусов), а отправитель отправляет фотоны. Затем получатель отправляет отправителю комбинацию поляризаторов, что он использовал, а отправитель отвечает какие были правильными. Угаданный получателем ключ используют для шифрования. В данный момент существуют алгоритмы шифрования симметричные и асимметричные. Симметричные алгоритмы шифрования и шифруются и расшифровываются одним и тем же ключом, асимметричные используют для каждого метода разные ключи. Из симметричных довольно популярны были DES и AES (блочные шифры, то есть разбивали текст на блоки, а потом шифровали). Для обеспечения большей безопасности,  (так как символы зашифрованного блока соответствовали символам текст и переставив их можно было переставить текст) используют режим сцепления блоков, когда между следующим блоком перед шифровкой и предыдущим зашифрованным выполняют операцию XOR. Теперь если переставить строчки при расшифровке исходного текста не получится. 

Асимметричные алгоритмы используют два ключа такие, что невозможно из открытого ключа вывести закрытый. В основном ключами являются простые числа, достаточно большие, чтобы можно было их угадать, но есть алгоритмы завязанные на вычисления логарифмов. Самый распространенный алгоритм с открытым ключом это RSA. При передаче сообщения отправитель шифрует сообщение открытым ключом получателя, а получатель расшифровывает своим закрытым ключом. RSA работает медленно и его используют чаще всего для того чтобы передать общий ключ шифрования для отправителя и получателя, либо для электронной подписи. Электронная подпись нужна для документов, чтобы никто не мог ее подделать и легко было понять, что человек поставил ее сам. Электронную подпись ставят не на документ, а на хэш-функцию от содержания документа, чтобы в случае чего, можно было проверить что текст не менялся. Для этого считают хэш-функцию для документа еще раз, расшифровывают присланую хэш функцию открытым ключом того, кто ставил подпись, и сравнивают хэш функции. Если они не совпадают, значит текст кто-то поменял и ему доверять нельзя. Для лицензирования открытых ключей используют сертификаты. Сертификаты выдаются доверительным органом, который ставит на сертификат хэш и подписывает его своим закрытым RSA ключом. Даже если кто-то расшифрует его с помощью открытого ключа лицензирующего органа, подменить хэш будет нельзя, так как закрытый ключ шифрования не известен никому.