Showing posts with label what i learn from. Show all posts
Showing posts with label what i learn from. Show all posts

28 October 2018

What I learnt from 000: Introduction

In the world of perfect people as seen on LinkedIn or Instagram and expert in everything as seen on Twitter, Facebook or other social media I don't need to write another review. There are many reviews by experts, 'experts' and bloggers, so adding another 'review' will create more noise in the internet universe. Instead, I will do  'What I learnt from': is a series of short notes about what I learnt from a book or webinar. I will add some loose opinion about the topic! 

3 August 2017

What I learn from .019 : Growing Object-Oriented Software, Guided by Tests” By Steve Freeman, Nat Pryce.

Growing Object-Oriented Software, Guided by Tests” By Steve Freeman, Nat Pryce.

I am in the middle of mastering TDD. It helps me to gain confidence in code and helps me to change code without being surprised by unexpected shit hit the fan. It makes your writing code slower and you need be kept balance with a number of tests and ensure there are no duplicate tests as it makes changes time-consuming. There is some aspect of TDD that I am confused about it. I needed a book that will show TDD from project start to keep improving stage where you just keep add new features and improve existing ones.
Guess what? There is a book for that. It is called “Growing Object-Oriented Software, Guided by Tests” By Steve Freeman, Nat Pryce.
This book is great if you know basics of TDD and you want to understand how to use TDD methodology from project starts to maintenance phase based on the real world for example.
It helps you shape TDD skill set. I learnt a lot, but below you can find my favourite takeaways from this book.:


GENERAL
  1. Test data builder. This produces a more focused test with less code. We can name the builder after the features that are common, and the domain objects after their differences. We could add a factory method that returns a copy of the builder with its current state:
    1. Order orderWithDiscount = hatAndCape.but().withDiscount(0.10).build();
Order orderWithGiftVoucher = hatAndCape.but().withGiftVoucher("abc").build();
For complex setups, the safest option is to make the “with” methods functional
and have each one return a new copy of the builder instead of itself.
I really like this pattern in larger projects because it helps me create context  I needed for test without noise (like set things that are not used in test)
  1. Logging.
    1. Support logging (errors and warn) is part of the user interface of the application. These messages are intended to be tracked by support staff that handle support.It should be used to diagnose a failure or monitor the progress of the running system.
    2. Diagnostic logging (info, debug and trace) is infrastructure for programmers. These messages should not be turned on in production because they’re intended to help the programmers understand what’s going on inside the system they’re developing
It is an interesting approach which I would like to try it in one of my future projects. Proper logging is critical in diagnosing and fixing problems.
  1. Interface and Protocol. An interface describes whether two components will fit together, while a protocol describes whether they will work together.
  2. public static void main(String... args) throws Exception {
Main main = new Main();
XMPPAuctionHouse auctionHouse =
XMPPAuctionHouse.connect(
args[ARG_HOSTNAME], args[ARG_USERNAME], args[ARG_PASSWORD]);
I like concept of using content to describe elements of args[]


CODE:
  1. Keep the code as simple as possible, so it’s easier to understand and modify. Developers spend far more time reading code than writing it, so that’s what we should optimise for readability.Write the Test That You’d Want to Read.
Easier said than done, but I am getting better and better at this, but it is the mantra which all developers should repeat over and over again.
  1. Train wreck” code is bad because it lower readability. For example: master.getModelisable().getDockablePanel().getCustomizer()).getSaveItem().setEnabled(Boolean.FALSE.booleanValue());  It should be master.allowSavingOfCustomisations();
  2. Values and Objects. It’s important to distinguish between values that model unchanging quantities or measurements, and objects that have an identity. Values and Objects. values are immutable, so they’re simpler and have no meaningful identity; objects have state, so they have identity and relationships with each other.
    1. Values are immutable instances that model fixed quantities. They have no individual identity, so two value instances are effectively the same if they have the same state. This means that it makes no sense to compare the identity of two values; doing so can cause some subtle bugs—think of the different ways of comparing two copies of new Integer(999). That’s why we’re taught to use string1.equals(string2) in Java rather than string1 == string2. string1.equals(string2) in Java rather than string1 == string2.
    2. Objects, on the other hand, use the mutable state to model their behaviour over time.
  3. As the code scales up, the only way we can continue to understand and maintain it is by structuring the functionality into objects, objects into packages, packages into programs, and programs into systems. We use two principal heuristics to guide this structuring:
    1. Separation of concerns. When we have to change the behaviour of a system, we want to change as little code as possible. If all the relevant changes are in one area of code, we don’t have to hunt around the system to get the job done. Because we cannot predict when we will have to change any particular part of the system, we gather together code that will change for the same reason.
    2. Higher levels of abstraction. The only way for humans to deal with complexity is to avoid it, by working at higher levels of abstraction. We can get more done if we program by combining components of useful functionality rather than manipulating variables and control flow; that’s why most people order food from a menu In terms of dishes, rather than detail the recipes used to create them.
  4. UNUSED_CHAT is a meaningful name for a constant that is defined as null.
  5. Keep the Code Compiling. Try to minimise the time when we have code that does not compile by keeping changes incremental. When we have compilation failures, we can’t be quite sure where the boundaries of our changes are, since the compiler can’t tell us. This, in turn, means that we can’t check into our source repository, which we like to do often.The more code we have open, the more we have to keep in our heads which, ironically, usually means we move more slowly. TDD shows how fine-grained our development steps can be.
  6. Where do we start when we have to write a new class or feature? the simplest thing that could possibly work” but simply should not be interpreted as simplistic. We prefer to start by testing the simplest success case. Once that’s working, we’ll have a better idea of the real structure of the solution and can prioritise between handling any possible failures we noticed along the way and further success cases.
  7. From author’s experience, when the code is difficult to test, the most likely cause is that design needs improving. Author value code that is easy to maintain over code that is easy to write.
  8. Encapsulation vs Information hiding.
  9. Encapsulation ensures that the behaviour of an object can only be affected through its API. Information hiding Conceals how an object implements its functionality behind the abstraction of its API.
  10. Many object-oriented languages support encapsulation by providing control over the visibility of an object’s features to other objects, but that’s not enough. Objects can break encapsulation by sharing references to mutable objects, an effect is known as aliasing. Aliasing is essential for conventional object- oriented systems (otherwise no two objects would be able to communicate), but accidental aliasing can couple unrelated parts of a system so it behaves mysteriously and is inflexible to change. We follow standard practices to maintain encapsulation when coding: define immutable value types, avoid global variables and singletons, copy collections and mutable values when passing them between objects, and so on.
  11. No And’s, Or’s, or But’s. Every object should have a single, clearly defined responsibility; this is the “single responsibility” principle. When we’re adding behaviour to a system, this principle helps us decide whether to extend an existing object or create a new service for an object to call.
  12. Impl Classes Are Meaningless. Sometimes we see code with classes named by adding “Impl” to the single interface they implement. This is better than leaving the class name unchanged and prefixing an “I” to the interface, but not by much. A name like BookingImpl is duplication; it says exactly the same as implements Booking, which is a “code smell.” We would not be happy with such obvious duplication elsewhere in our code, so we ought to refactor it away. It might just be a naming problem.
  13. I agreed with that but I found quirky too because my answer to that used default implementation, but it is context based
  14. It comes handy to have RuntimeException like SomethingWentHorribleWrongException or Defect when the code reaches a condition that could only be caused by a programming error, rather than a failure in the runtime environment.
  15. We like to start by writing a test as if its implementation already exists, and then filling in whatever is needed to make it work—what Abelson and Sussman call “programming by wishful thinking”.


PROJECT


  1. How to start a new project using TDD approach? We want to start from building a “walking skeleton” that we can deploy it into a production-like environment, and then run the tests through the deployed system. Including the deployment step in the testing process. It is critical for two reasons. First, this is the sort of error-prone activity that should not be done by hand, so we want our scripts to have been thoroughly exercised by the time we have to deploy for real. Second, The development team bumps into the rest of the organisation and has to learn how it operates currently. If it’s going to take six weeks and four signatures to set up a database, we want to know now, not two weeks before delivery. To design initial structure, we have to have some understanding of the purpose of the system and we need a high-level view of the client’s requirements, both functional and non-functional, to guide our choices. The tools we build to implement the “walking skeleton” are there to support this learning process. Deploying and testing right from the start of a project forces the team to understand how their system fits into the world. It flushes out the “unknown unknown” technical and organisational risks so they can be addressed while there’s still time. Understand problem → Automate Build, Deployment, End to End Tests → TDD cycle.
  2. The “walking skeleton” is an implementation of the thinnest possible slice of real functionality that we can automatically build, deploy, and test end-to-end. For example, for a database-backed web application, a skeleton would show a flat web page with fields from the database.
  3. Iteration Zero. In most Agile projects, there’s a first stage where the team is doing initial analysis, setting up its physical and technical environments, and otherwise getting started. The team isn’t adding much visible functionality since almost all the work is infrastructure so it might not make sense to count this as a conventional iteration for scheduling purposes. A common practice is to call this step iteration zero: “iteration” because the team still needs to time-box its activities and “zero” because it’s before functional development starts in iteration one. One important task for iteration zero is to use the walking skeleton to test-drive the initial architecture.
  4. Iteration Zero. In most Agile projects, there’s a first stage where the team is doing initial analysis, setting up its physical and technical environments, and otherwise getting started. The team isn’t adding much visible functionality since almost all the work is infrastructure so it might not make sense to count this as a conventional iteration for scheduling purposes. A common practice is to call this step iteration zero: “iteration” because the team still needs to time-box its activities and “zero” because it’s before functional development starts in iteration one. One important task for iteration zero is to use the walking skeleton to test-drive the initial architecture.


TDD
  1. As we develop the system, we use TDD to give us feedback on the quality of both its implementation (“Does it work?”) and design (“Is it well structured?”).
  2. Writing tests:
    1. makes us clarify the acceptance criteria for the next piece of work—we have to ask ourselves how we can tell when we’re done (design);
    2. encourages us to write loosely coupled components, so they can easily be tested in isolation and, at higher levels, combined together (design);
    3. adds an executable description of what the code does (design);
    4. detects errors while the context is fresh in our mind (implementation);
  3. The Golden Rule of Test-Driven Development: Never write new functionality without a failing test.


TESTING
  1. Levels of Testing. We build a hierarchy of tests to gain confidence on various levels:
    1. Acceptance: Does the whole system work?
    2. Integration: Does our code work against code we can't change?
    3. Unit: Do our objects do the right thing, are they convenient to work with?
  2. Watch the Test Fail. We always watch the test fail before writing the code to make it pass, and check the diagnostic message. If the test fails in a way we didn’t expect, we know we’ve misunderstood something or the code is incomplete, so we fix that. As we write the production code, we keep running the test to see our progress and to check the error diagnostics as the system is built up behind the test. Where necessary, we extend or modify the support code to ensure the error messages are always clear and relevant.
  3. One common mistake is thinking about testing methods. A test called testBidAccepted() tells us what it does, but not what it’s for.
  4. The end-to-end test shows us the end points of that process so we can explore our way through space in the middle.
  5. Common causes of test brittleness include:
    1. The tests are too tightly coupled to unrelated parts of the system or unrelated behaviour of the object(s) they’re testing;
  6. The tests overspecify the expected behaviour of the target code, constraining it more than necessary.
  7. There is duplication when multiple tests exercise the same production code behaviour.
  8. Test brittleness is not just an attribute of how the tests are written; it’s also related to the design of the system. If an object is difficult to decouple from its environment because it has many dependencies or its dependencies are hidden,  its tests will fail when distant parts of the system change.
  9. We mock object to manages expectations and stubbing for the test. The essential structure of a test is:
    1. Create any required mock objects.
    2. Create any real objects, including the target object.
    3. Specify how you expect the mock objects to be called by the target object.
    4. Call the triggering method(s) on the target object.
    5. Assert that any resulting values are valid and that all the expected calls have been made.
  10. We start work on a new feature by writing failing acceptance tests that demonstrate that the system does not yet have the feature we’re about to write and track our progress towards completion of the feature.We write the acceptance test using the only terminology from the application’s domain.It helps to understand what the system should do, without tying us to any of our initial assumptions about the implementation or underlying technologies.
  11. Small, Focused, Well-Named Tests The easiest way to improve diagnostics is to keep each test small and focused and give tests readable names. If a test is small, its name should tell us most of what we need to know about what has gone wrong.
  12. The point of a test is not to pass but to fail. We want the production code to pass its tests, but we also want the tests to detect and report any errors that do exist. A “failing” test has actually succeeded at the job it was designed to do.
  13. Even unexpected test failures, in an area unrelated to where we are working, can be valuable because they reveal implicit relationships in the code that we hadn’t noticed.



I highly recommended this book.

20 July 2017

What I learn from .018 : Coursera course : Usable Security


Ages ago. I enrolled myself into course Usable Security on Coursera. 


    It was about usability and Human-Computer Interaction related to security. If you are interested in UX.  I highly recommended this course.
Sadly, I lost some of my notes, but this is what I still remember from  I learned from this course:

  1. Human-Computer Interaction (HCI) is a study how people interact with technology.
  2. Tasks are goals that users set out to accomplish when they are using the system. 
  3. To evaluate the usability of the system, you need to create a representative list of tasks and evaluate the usability of those tasks according to following factors:
    1. Speed (how quickly task can be accomplished)
    2. Efficiency (how many mistakes are made in accomplishing the task)
    3. Learnability (how easy is to learn to use the system)
    4. Memorability (once learned, how easy is to remember how to use the system)
    5. User Preference (what do users like?)
  4. Tasks.. 
    1. should NOT  be leading or descriptive (shouldn't have instructions what to do step by step)
    2.  should NOT be too specific (shouldn't say like third link )
    3. should NOT be a focus on least important  or rare elements than users will do (like checks list of authors of the website)
  5. Mental models
    1.  let understand how users perceive systems.
    2. are used our experience and/or knowledge from all other parts of our life to  interact with new things. 
    3. are important to understand as If we take these mental models into account when we're design software, we can build things that will be easier learn, remember and easier to use faster and more efficient.
  6. A mental model is a combination of:
    1. Affordances  (Affordances are things within a system that show a user how they're supposed to be used. 
    2. Mapping
    3. Visibility
    4. Feedback
    5. Constraints (how a system can prevent us from doing things that we shouldn't and how the design of it can encourage us to do things the right way.
  7. There are much more to learn from this course but I forgot it already.
Conclusion
    It is a great course for people who are interested in UX. It is worth spend some time on readaing about basics of cognitive psychology and learn how memory works as It will help you learn much more from this course.

6 July 2017

What I learn from 017 : Kotlin Dojo by Kotlin London User Group

Recently, I spoke with some colleagues about Kotlin and I decided to do some research about this language. Kotlin is a statically typed programming language that runs on the JVM and it can be translated into ECMAScript apparently. My first impression about Kotlin was it is like Java without a legacy mess and with many synthetic sugar features but at the time of writing this, I didn’t explore language enough to make any statement with some evidence. 

Accidentally, I discover Kotlin London Meetup that was organizing the Kotlin-Dojo. I always want to see how dojo sessions look like, so it decided to attend.  Before I went, I managed to grasp basic syntax and that turns out to be a bare minimum to be able to enjoy this dojo. 

 It was very well organized. Quick introduction, tasks were usually well explained and they have some learning value (not only code practice) and they provide links to various references. Some exercises were about learning Kotlin. Some of them show when IntelliiJ was helpful and where was misleading. Presenters after some time show solution and give an opportunity to others to show their solutions too. 
 I paired with a guy who seems to know many things so I could learn a lot and as I saw some syntax I was able to contribute some stuff too. What I learn from Kotlin Dojo:
  1. Kotlin has decent IDE support but still, there are many misleading glitches.
  2. Kotlin is an interesting language to learn, but I feel it is more a mod to Java language than independent language.
  3. It is mature enough to be used in production. There are already a few companies who are using Kotlin.
  4. I really like some synthetic sugar in Kotlin like var (mutable variable) and val (immutable value) and much more.
  5. I have noticed that when other languages that compare themselves to Java, they highlighting fact that they compressed syntax to improve readability. Yes, there is less noise on screen and it makes developing is faster but later on, understand and debugging code us more difficult. These syntax optimizations reduce readability and memorability (ability to re-learn what code does and why). So far I have noticed this problem in Groovy, Scala and ... Kotlin where somebody struggles to understand what compiler was moaning about


 Overall, it was a great meetup. I will try to attend in future. In 2018 where I am planning learning this language as 2017 is a year I am learning Python.

 If you are interested in learning Kotlin, check this meetup:
https://www.meetup.com/kotlin-london/

 If you want to see exercise check this github: https://github.com/springernature/kotlin-dojo

1 July 2017

What I learn from.016 : What I learn from "The JVM as a platform for building smart contracts" by Ben Evans



"The JVM as a platform for building smart contracts" by Ben Evans

https://www.meetup.com/Londonjavacommunity/events/240079438/


I attended to meetup organized by London Java Community. It turns out to be interesting and bit confusing presentation but overall I found very useful.


Most interesting quote: "User is always the weakest part of the system".


What I learn from:

  1. Java was created for the job, not as academic research. Java is very pragmatic and conservative in change and that's one of the reasons why is so popular choice.
    • It is something that Brian Goetz (Java architect) mentioned too. I still believe that some stuff should be removed, but I can live with it. 
  2. I learn what strictfp is for and so now  Most CPU can do better precision. strictfp prevent from this happen.
  3. I heard basic about Cryptocurrency. 
      • I learn that a digital currency in which encryption techniques are used to regulate the generation of units of currency and verify the transfer of funds. (Source: Wikipedia)

    Why it was a bit confusing? This due fact that talk suddenly switched from cryptocurrency into how to implement it in Java. However, to be fair, Ben asked people how familiar are they with this concept and majority were very familiar and actually I learn quite a bit about it, so I am very happy.

    FOLLOW AUTHOR:


    TWITTER: https://twitter.com/kittylyst/


    FOLLOW LONDON JAVA COMMUNITY


    MEETUP: https://www.meetup.com/Londonjavacommunity/

    21 June 2017

    What I learn from 015 : article by Richard White titled "How We Use Trello & Google Docs to Make UserVoice Better Every Day"




    "How We Use Trello & Google Docs to Make UserVoice Better Every Day" by Richard White

        Jira and Confluence tools from Atlassian are one of the well-known standard tools used for product management and team collaboration. In the article "How We Use Trello & Google Docs to Make UserVoice Better Every Day" by Richard White, we can see and alternative way to do product management using Trello a great "get things done" task tool and google docs.
    It is worth reading it.

    What I learned from this article:


    • A person is not required to take the top card from the list but rather the top card that it feels most comfortable to handle. 
      • It is a great idea. For example for pair programming when you can switch pairs between tasks as different people like different things and want learn different things, so they can switch pair on the ticket basis.
    •  Etiquette is that you should never have your face on more than 2 cards at a time: 1 major project and 1 minor.
    • Something that I should work on in the future. Currently, I do not follow this rule as for when I finish the task but I need to wait for our CI to finish successfully, I have a habit to pick-up something new.
    • If a bug is considered as “Critical” by the customer team then it can be pick up by “developer on call”.
    • They set limits to pick 7 bugs per week. It prevents development to be disturbed because there are always bugs and the customer team always wants them all fixed. They learned that set a constant throttle of how much time they spend on bug fixing helps them to have more stable development.
    • If you don't have a dedicated support team, then having a limit for a number of bug fixes to do is crucial. I experienced a chaos when our team suddenly need to take care of support and it turns our development into a mess. We fixed it by having dedicated person who handles these issues.
    • We keep a list of areas that we think might need refactoring. Engineers take small cards when they feel like it and add them to in progress; larger cards need to be planned in the Next Up list.
    • It is a great idea to have 'spare time' to spend on improving code without hassle.
    • One of they board is called The Planning Board is where CEO, PM, and head of UX spend the majority of the time. It has the following columns: Next Up,  Spec (This means “someone needs to write a spec”.  Design (This means that the card needs a designer to take a look at it), Ready (We have a spec that’s been reviewed by the idea creator and by the design team. )
    • It sounds 3 amigos style meeting that helps sprint plan.
    • Have a single prioritised list for the product team to work from. Don’t have a separate system for bugs because from they experience having more than one list breaks down a prioritisation.


    Overall, the useful article to read if you want to learn on how to organise your team when what tools can you use if you don't want to spend the fortune on Atlassian products.



    FOLLOW AUTHOR:

    LINKEDIN: https://www.linkedin.com/in/rrwhite/
    TWITTER: https://twitter.com/rrwhite

    17 March 2017

    What I learn from 014 conference talk: Pair testing by Raji Bhamidipati


    BDDX ’2016 in London PAIR TESTING



        Sometimes ago, I  managed to watch Pair testing by Raji Bhamidipati from #BDDx'2016 and it was great. It was about pair working (from tester point of view).
    It was interesting talk about pair working with focus on pair testing.

    What I took from this talk :
    • Different styles of pair testing
      • Expect-Expert like Exploring tester with Security tester, where instead of going back with feedback and forwards . Time saved on loop
        Expert-Novice
        Novice-Novice works because they have different strategies so while
        Driver-Navigator
        Ping-Pong Pairing swapping
        Mob popular in testing. Group of people testing at the same time.
      • Advantages
        • Team building and collaboration
        • Share knowledge
        • Mix of skill set based on requirement
      • Disadvantages of pair testing
        • work overload
        • conflicts when paired incorrectly due personality incompatibility
        • do not let pair testing create favouritism or elitism within your teams. let's opportunities to everybody not only one person.
      • When to pair
        • training newbies
        • coaching and mentioning other team members
        • when deadlines approaching (dev-test pairing)
      • Common problems with introduction of pair testing
        • fair of change
        • not time efficient as 2 people are  doing the same task

      In my person opinion pair working is great for many reason (some of them are mentioned above) . I think communication and argument skills are one of the most important to improve while doing pair working. Communication seems be obvious but why argument ? Well , you need to learn how to argue to get best output based on comprise of few opinions without hurting. From my experience using pair technique in valid context generated much better quality code , less buggy  and give higher confidence to all stakeholders. It doesn't need be applied all the time as some people suggest.
      Anyway, if you haven't see this talk. It is worth check it out if you are interesting in pair testing (it applies to pair programming too).


      Follow Raji Bhamidipati on:














      3 March 2017

      What I learn from 013 talk: Code Review Matters and Manners by Trisha Gee and Maria Khalusova

          I watched an very interesting talk "Code Review Matters and Manners" by Trisha Gee and Maria Khalusova.
          A code review is a  process of  source code verification to check is code does what is supposed to do and is it meet criteria set by rules (acceptance criteria, quality and so on)
      Code review is an important technique,because:

      1. It helps me as developer to :
      • write better code
      • verify did I understand acceptance criteria correctly. 
      2. It helps code base to:
      • have better quality
      • to be consistent and
      • to follow agreed  approach and practices
      • increase confidence to other stakeholders (other developers, QA  and so on ) that code does what is suppose to do .
          In my opinion code review is very useful for above reasons. From my experience there is only one problem. A human factor and way how feedback is given. In my little work experience, it happens once when when I was annoyed by given feedback. Problem was with feedback that was given by person who behave like princess Goggle, where they are maniac about give as much as negative feedback as possible. Even for a minor detail and pretend this is always better. In practice large amount of time on detail that ... does not matter from functionality point of view.

      This talks covers how to do code review and how to give feedback.

      From this talk I learn ( re-learn or remind myself) about code review that:

      I should focus on:
      • Functionality :
        • Is it doing what is suppose to do ?
        • Is meet acceptance criteria and non-functional  requirements ?
      • Code usability:
        • Readability
        • Maintainability
        • Extensibility
      We  should NOT focus on little annoying things that can be automated . Personally I found this kind of things annoy people rather than helps.

      Code review is too late for design discussion and suggestion like:
      • Is it in right place?
      • Is it use right data structure , pattern ?
      • is code is overly complex or over-engineered?
      • Is use existing library or introduce new dependencies ?
      About Give Feedback I learn that:

      • You should have some code review manners rules written somewhere, where you should include things like:
        • Discuss changes, not people
        • Be specific
        • Suggest alternatives.
        • Don't be rude and don't offend people (directly or indirectly).
          • Example of offend people indirectly is by using words like obviously ,simply.
          • Refer to code not person This code not your code.
        • and so on.
          I read somewhere recently that "Learning how to deliver negative feedback effectively is crucial." I think it is worth to add it is important to decode useful bits from feedback. As was told by Maria during talk we should "be grateful for it and try to decode what person mean as written words do not reflect real intention". I agree with this. It is specially visible when you working in international team where people come from different  work cultures and they may have a language barrier when communicate.

         It is important to give feedback that focus on improve code based on agreed standards without blame or attack directly or indirectly person, because in the end our goal is to deliver good enough code that deliver value to product.

          I have a lot to improve with my feedback . I need use better and more accurate vocabulary and reduce amount of sarcasm as I am very sarcastic person.

      On side note. In order to write better code I am trying do code review in few ways.
      • I use IDE  (IntelliJ IDEA has awesome inspector feature) , Sonar and  plugins like Checkstyle and Findbugs 
      • I ask my colleague to double check my code (walktrough style) 
      • At work we are doing code review in real time during pair programming.
      That's all.

      Trisha Gee presence on Internet Universe

      Maria Khalusova presence on Internet Universe

      You can watch this talk here:
      https://vimeo.com/182087729