Hadi Hariri Jekyll 2025-04-19T20:47:18+02:00 https://hadihariri.com/ Hadi Hariri http://hadihariri.com/ [email protected] <![CDATA[Advocacy and your personal brand]]> https://hadihariri.com/2022/01/07/advocacy-and-your-personal-brand 2022-01-07T00:00:00+01:00 2022-01-07T00:00:00+01:00 Hadi Hariri https://hadihariri.com [email protected] <p>There are many aspects that contribute to being successful in Developer Advocacy. Branding is probably one of the most important elements of a successful advocacy career. During my years as an Advocate, there are some collected wisdoms I’ve learned which I’d like to share:</p> <h3 id="believe-in-what-you-do">Believe in what you do</h3> <p>This may seem quite obvious, but if you don’t believe in the product that you’re advocating for, it’s going to be very difficult for you to project any confidence to people when you’re talking about it. Not only will it be hard, but it negatively damages your own brand. People can sense your sincerity.</p> <h3 id="practice-what-you-preach">Practice what you preach</h3> <p>Every single person that I’ve interviewed, and I’ve asked why they want to join advocacy, tell me that it’s because they’ve been doing “advocacy on the side” and have so much knowledge they want to write and speak about it. They say they love the idea of being able to do it full time. Forgetting for a moment that advocacy isn’t just about content (in any form), one of the greatest challenges in Advocacy is continuing to have that input stream of “stuff” to talk about. See, when you’re a full time developer or consultant, you’re constantly faced with interesting challenges that sprout new ideas in your head. When you’re a full time advocate, this no longer happens. Once the well of ideas you brought with you dries up, what’s next?</p> <p><br /> <br /> That’s when you risk becoming a pundit, and consequently damaging your brand. This is why it’s critical that you continue to do “stuff”, not just talk about it. Whether it’s internal projects, whether it’s working on OSS, or helping customers with issues, having hands-on experience is key to keeping your brand credible.</p> <h3 id="work-on-your-brand-internally">Work on your brand internally</h3> <p>As an advocate, our primary goals (at least at JetBrains) are to educate folks and provide feedback to product teams to improve our products. As important as it is to work on your brand externally, it’s also important to do so internally. Make sure that your colleagues understand the work you’re doing, communicate with them, bring them digests of what you say in the community, help them improve the product by showcasing workflows or things they may not be aware of. Build your reputation just as you would with the community.</p> <h3 id="have-integrity">Have integrity</h3> <p>If you think a competitor’s product is better than yours, say it. Don’t deny it. If you feel something in your product isn’t right, accept it. Take the feedback and help improve it.</p> <p><br /> <br /> If your company is doing something you don’t agree with and feel it’s wrong, don’t look the other way when someone asks you about it. I realise that it’s not always easy to speak your mind, but at the end of the day, we all have to make our choices as to where we draw the line of what is or is not defensible.</p> <h3 id="be-yourself">Be yourself</h3> <p>Avoid having multiple personas. Don’t play one character online and be someone completely different offline. It speaks volumes to your character, your integrity, and of course your brand. Trust me, word gets around.</p> <h3 id="stay-humble">Stay humble</h3> <p>No matter how successful you are, and how well you work on your brand, stay humble. Don’t forget your beginnings. Don’t ignore people because your time is too valuable. Treat every person with respect, and not by how far they may take you.</p> <p>As sad as it is, I’ve seen folks grow their brand in the community only to become unapproachable. Don’t forget, no matter how famous you may be, you’re still a nano-celebrity.</p> <h2 id="everyone-starts-from-nothing">Everyone starts from nothing</h2> <p>It seems that in the IT world, advocates are in high demand, judging by not only the job offers but some salaries that go with it. Every other company seems to be competing for the “big names”.</p> <p><br /> <br /> That leaves you wondering - how can I get into this field if I don’t have an established name? First off, not all <a href="https://hadihariri.com/2022/01/03/applying-for-developer-advocacy/">companies just go for names</a>. Secondly, it’s not that hard to make a name for yourself (trust me, to more or less extent I’ve done it so everything is possible). Find something you love and work on that - whether it’s speaking, doing screencasts, doing a podcast, writing, helping people in the community. It doesn’t matter if you’re not even an expert on the topic. I’ve seen so many folks start from nothing, learn in the open, and build their brand in this way. Inspiring people isn’t always easy, but you don’t have to be an expert to do it.</p> <p><br /> <br /> Lastly, it’s important to understand that whether we like it or not, our brand and our company’s brand are intertwined. Especially when it comes to negativity. If we do something that damages our brand, ultimately it can hurt our company’s brand also, and vice-versa. No disclaimer that says “opinions are my own” will fix that.</p> <p><a href="https://hadihariri.com/2022/01/07/advocacy-and-your-personal-brand/">Advocacy and your personal brand</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on January 07, 2022.</p> <![CDATA[Applying for Developer Advocacy]]> https://hadihariri.com/2022/01/03/applying-for-developer-advocacy 2022-01-03T00:00:00+01:00 2022-01-03T00:00:00+01:00 Hadi Hariri https://hadihariri.com [email protected] <p>We have a few positions open for <a href="https://www.jetbrains.com/careers/jobs/?role=Developer%20Advocate">Developer Advocacy at JetBrains</a>, and for the past several months I’ve been going through CVs. I usually look for specific things that stand-out for the role and thought it might be worth sharing these.</p> <h2 id="developer-experience">Developer Experience</h2> <p>Developer Advocacy is first and foremost about Software Development. You are someone that will be helping developers. You are someone that will be helping the product teams make a better product. Both of these are hard to accomplish if you don’t have the experience and war-stories. Highlight your experience as a developer in your CV.</p> <p><br /> <br /> In the 12 years I’ve been involved in Advocacy, only on a couple of occasions did we hire someone with little real-world developer experience, but these were justified for other reasons.</p> <h2 id="experience-with-jetbrains-tools">Experience with JetBrains Tools</h2> <p>We want folks that join JetBrains to believe in what we’re doing, and enjoy using our products. If you don’t, then you probably won’t be happy at your job. If you use our products, make sure you point it out. You don’t need to be an expert, but believing in them and wanting to help improve them is important. We are strongly against hiring shills.</p> <h2 id="communication-skills">Communication Skills</h2> <p>Communicating is critical in the role. Whether it’s talking to a customer at a booth, or talking to developers inside the company, it must be something that you’re not only good at but enjoy doing. As such, highlighting communication skills is important when applying for the role.</p> <h2 id="community-presence">Community Presence</h2> <p>As a Developer Advocate, having a community presence is important. Provide information about your community activities and/or online presence, whether it’s speaking, organising events, social media accounts, GitHub or other repository accounts.</p> <p><br /> Note however that while community presence is important, it’s not critical. You don’t have to be a micro-celebrity in your community to get a job as a Developer Advocate at JetBrains. We’re not particularly looking for big names. We’re looking for people that are aligned with the role and enjoy doing what they do.</p> <p><br /> When I joined JetBrains, I had somewhat of a presence in the .NET community (I’d spent many years in the Delphi community). I gradually worked on this. I then moved to Kotlin (after a brief stint with JavaScript) and built up my name in the Java community. Building your name is something that will be part of your job.</p> <h2 id="teaching-skills">Teaching Skills</h2> <p>Highlight your teaching skills - whether it’s screencasts, public speaking, written-content. As a Developer Advocate you’ll be doing a lot of content in different formats. Knowing how to teach people is critical.</p> <p><br /> Lastly, it’s important to understand that much like Developers, QAs, and other roles, it’s not expected of you to be proficient in all of these areas (except development). It’s absolutely OK if you are better skilled in some areas, but less in others. You can work on building these up. This is something that we actively encourage on the Advocacy team at JetBrains.</p> <p><a href="https://hadihariri.com/2022/01/03/applying-for-developer-advocacy/">Applying for Developer Advocacy</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on January 03, 2022.</p> <![CDATA[Organising with Checkvist - A new sublist]]> https://hadihariri.com/2021/03/04/organising-with-checkvist 2021-03-04T00:00:00+01:00 2021-03-04T00:00:00+01:00 Hadi Hariri https://hadihariri.com [email protected] <p>I’m a big fan of <a href="https://checkvist.com">Checkvist</a> and today in response to my <a href="https://twitter.com/hhariri/status/1367385436931383297">praise on Twitter</a>, <a href="https://twitter.com/tastapod">Dan</a> asked a few questions around it:</p> <blockquote class="twitter-tweet"><p lang="en" dir="ltr">Ok you realise I&#39;m going to be nagging you all day now?<br />- One list or multiple lists?<br />- All projects in one list?<br />- How do you organise your tasks?<br />- How do you use tags?<br />- Will you shut up and take my money?</p>&mdash; Daniel Terhorst-North (@tastapod) <a href="https://twitter.com/tastapod/status/1367407589496139776?ref_src=twsrc%5Etfw">March 4, 2021</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p><br /> <br /> Better than a Twitter thread, I promised him I’d write a short post to answer these.</p> <h2 id="how-do-you-organise-your-tasks">How do you organise your tasks?</h2> <p><br /> Most of what I have written about <a href="https://hadihariri.com/2015/10/19/organizing-my-week-with-checkvist/">how I work with Checkvist still stands</a>, namely</p> <ul> <li>I have a single list where I organise my weekly tasks. Anything that I do or gets done, goes into the list.</li> <li>I have a few integrations with things such as Slack and Gmail where I can send items as tasks.</li> </ul> <p><br /> These two things help me (attempt) to keep focus, and try and avoid forgetting things. What’s really useful is sending things from other apps to Checkvist (namely Slack). I’m not a fan of Slackbot and my ad-hoc decision of making up some random time in which I want to be reminded of a message again only to snooze it for some other random amount of time picked out of thin air. I just star a message and it goes to Checkvist. Done.</p> <p><br /></p> <h2 id="one-list-or-multiple-lists">One list or multiple lists?</h2> <p>I still have one main list for work which is <code class="language-plaintext highlighter-rouge">TODO</code>. However, since I manage/involved in multiple projects, I’ve found having multiple lists can come in useful, especially when we’re talking about repetitive tasks.</p> <p><br /> <img src="https://hadihariri.com/images/checkvist-1.png" alt="TODO List" /> <br /></p> <p>The first entry is my weeky list of tasks (collapsed for sake of space). I then have a “linked list” for specific projects. To focus on these lists, I can easily navigate to them using the keyboard (ll) or obviously mouse. Or I can simply navigate to it from the item itself (gg). This will then focus on that list.</p> <p><br /> <img src="https://hadihariri.com/images/checkvist-2.png" alt="TODO List" /> <br /></p> <p>Notice the due date entries on these items? These are all repetitive tasks, a wonderful feature of Checkvist, allowing you to create repetitive tasks on a certain frequency. When you mark it as done, it will be ticked off, and Checkvist will create a new entry for the next date. This alone justifies having lists per projects because it gives me a nice, clean, and organised view of each project. That is not to say that you can’t have these as items of a single list and then focus exclusively on these (Checkvist allows that too), but I’ve just found keep it separate per project is useful.</p> <p><br /> And since it’s really easy to navigate back and fourth between lists, there is no friction.</p> <h2 id="how-do-you-use-tags">How do you use tags?</h2> <p>To be honest, I don’t really make use of tags. I’ve not found a need for them. I’m sure there are valid cases, but for now I seem to do fine without them.</p> <h2 id="will-you-shut-up-and-take-my-money">Will you shut up and take my money?</h2> <p>Yes. I’ll shut-up. Now show me the money! Or better yet show it to <a href="https://checkvist.com">Checkvist</a>, cause while there’a a free tier that provides already an amazing amount of functionality, the folks behind it deserve our support. So if you like it, make sure you upgrade to the Pro account. It’s only $39 a year!</p> <p><a href="https://hadihariri.com/2021/03/04/organising-with-checkvist/">Organising with Checkvist - A new sublist</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on March 04, 2021.</p> <![CDATA[A few words on Git.]]> https://hadihariri.com/2020/10/14/a-few-words-on-git 2020-10-14T00:00:00+02:00 2020-10-14T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>I tweeted something about Git. Do I regret it? A little bit. Why? Because it had a grammar mistake. <br /> <br /></p> <blockquote class="twitter-tweet"><p lang="en" dir="ltr">Git is not a success story. Git is a failure as a system with a crap user experience that forces you to learn more about the tool you&#39;re using that about getting your work done.</p>&mdash; Hadi Hariri (@hhariri) <a href="https://twitter.com/hhariri/status/1314178925610885120?ref_src=twsrc%5Etfw">October 8, 2020</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p><br /> <br /></p> <p>The tweet made some rounds and died off. Then someone posted it on Hacker News, and it made more rounds, and then it died. Then someone posted it on Reddit, and the damn thing just doesn’t die off!</p> <h2 id="the-feedback">The feedback</h2> <p>The replies to the tweet can be grouped in two: <br /> <br /></p> <ol> <li>Folks that agree</li> <li>Those that don’t agree (and some are very angry)</li> </ol> <p><br /> <br /> I want to address the second group because it seems many of them don’t seem to get my point, and I keep repeating myself in replies to the tweet. Of course, it’s wishful thinking if anyone reads this post because at times, I find folks often don’t even read Twitter threads. <br /> <br /></p> <p>Having said that, let’s try and categorize the responses: <br /> <br /></p> <h3 id="youre-an-idiot-for-saying-its-not-successful-its-used-everywhere">You’re an idiot for saying it’s not successful. It’s used everywhere!</h3> <p>Let’s first address what I mean by success. If we’re talking about reach, Git is successful, yes. It’s probably the most used Version Control system. If we’re talking about people being frustrated and banging their heads to the wall because of Git, I’d say it probably is also successful. <br /> <br /></p> <p>Jokes aside though, the success I was talking about is actually in the context of the tweet - it is not (remember, this is my opinion) successful at its job of being a distributed version control system, because it fails at the user experience. More on why later. <br /> <br /></p> <p>So let’s put success into context - especially on Twitter. Remember we only read single tweets. <br /> <br /></p> <h3 id="youre-a-professional-learn-the-tool-or-gtfo">You’re a professional. Learn the tool or GTFO.</h3> <p>I suck at Git. But let’s say for a moment that I didn’t suck at Git. The response of “learn the tool” is not only assuming that you know my knowledge about Git, but also implying that everything is wonderful, and the problem lies only in that we, as users, don’t have enough knowledge. <br /> <br /></p> <p>In this category, there’s also the <br /> <br /></p> <p><em>“Git isn’t for average developers”</em> <br /> <br /></p> <p>Great. Well, consider me average. Now allow me to complain. <br /> <br /></p> <p>That a tool is complex isn’t something that should be seen as meritable. What’s meritable is making the difficult simple. More on that later.</p> <h3 id="if-you-dont-like-cli-use-a-gui">If you don’t like CLI, use a GUI</h3> <p><em>“If you don’t like the command line, use a GUI”</em> <br /> <br /></p> <p>Someone even told me that IntelliJ IDEA has a GUI tool. I WAS NOT AWARE! <br /> <br /></p> <p>I actually am a fan of command line tools, but that’s not the point. What’s shocking is how folks quickly equate the bad user experience of Git with it being a command line tool. While obviously having to remember commands, their parameters, and orders in which they’re applied isn’t the most useful usage of one’s time, user experience isn’t just about whether the interface is textual or graphical. As I mentioned in another tweet <br /> <br /></p> <blockquote class="twitter-tweet"><p lang="en" dir="ltr">The UI affects the UX but the UX isn&#39;t just about the UI. Putting nicer lipstick on a pig is still a pig.</p>&mdash; Hadi Hariri (@hhariri) <a href="https://twitter.com/hhariri/status/1314523004655874048?ref_src=twsrc%5Etfw">October 9, 2020</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <h3 id="git-is-just-a-folder-and-branches-are-just-pointers">Git is just a folder, and branches are just pointers.</h3> <p><em>“Git is actually quite simple, if you understand how it works under the covers”</em> <br /> <br /></p> <p>I’m sure it is, but why would I need to understand how a tool works under the covers to be able to use it effectively? Do you understand how IntelliJ IDEA parses an abstract syntax tree or what the PSI is, when you want to perform a refactoring?</p> <h3 id="git-is-better-than-what-we-had">Git is better than what we had</h3> <p>This reasoning is - “well it’s better than SVN or CVS, so stop complaining”. <br /> <br /></p> <p>Sure, and SVN was better than zipping up files and sharing them on a drive. Point being? That because we’ve improved (in some aspects) on previous tools, we should just accept that Git is it? This is as good as it’s going to get? <br /> <br /></p> <h2 id="the-git-user-experience">The Git User Experience</h2> <p>Now, coming back to the actual user experience. <br /> <br /></p> <p>As a developer, technical writer, build engineer {place here any other job that leads you to use version control}, I want to get my work done. This could be fixing bugs, creating features, writing documents, whatever it is. My focus should be on my job, not on grunt work. <br /> <br /></p> <h3 id="safety">Safety</h3> <p>When I use a version control system I’d like a system that doesn’t make me want to make local copies of my files in case I screw things up, and then have to: <br /> <br /></p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rm -rf /project git clone git@.... </code></pre></div></div> <p><br /> (btw, lost count the number of times folks have thanked us for <a href="https://www.jetbrains.com/help/idea/local-history.html">Local History in IntelliJ platform</a> because they messed up with Git) <br /> <br /></p> <p>But you could say “Hadi learn your tool, so you don’t mess up”. Sure I could, but I’d also like to have a tool that doesn’t make it overwhelmingly simple for me to mess-up.</p> <h3 id="workflows">Workflows</h3> <p>When I use a version control system, I’d like that system to take care of remembering my workflow for me, not have me remember it. <br /> <br /></p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git branch git checkout rebase oh wait, was it merge? Crap. Back to git clone </code></pre></div></div> <p>You could say you get used to it. I’m sure I would, but why should I? Why should I have to add this to my workflow? We seem to take pride as developers in automating things. We go and brag at conferences about how “With a single click I can deploy my system to my customers”. And yet when it comes to version control - it’s OK to remember manual steps. Not only remember them, but take pride in the ceremony. <br /> <br /></p> <p><em>“But DVCS is complex”</em> <br /> <br /></p> <p>They say… <br /> <br /></p> <p>Why is it so far-fetched that I’d like a tool to allow me to define my branching/collaboration strategy and help me do it without surfacing the complexity? <br /> <br /></p> <h2 id="in-summary">In summary</h2> <p>Many people were angry at me for saying that Git isn’t a success, that while I had valid points, GIT (as some call it) is successful. Once again, it really does depend on what you mean by success, and I tried to have a self-contained tweet define that. Did I fail at that? Probably. I’ll do better next time. However, I still stand by what I’ve said in this post - Yes, DVCS is complex. So is collaboration, but that doesn’t mean that tools should surface this complexity or make us perform manual error-prone repetitive tasks. Whether that tool is something written from scratch, or an abstraction over Git is an implementation detail if you will.<br /> <br /> <br /></p> <p>In regard to Git’s success in terms of usage, yes it has been successful, and I’m pretty sure GitHub has had quite a lot to do with it. I mean even at JetBrains we only support Git on our new product Space. However, <strong>the fact that something is widely used doesn’t mean that we cannot do better</strong>. <br /> <br /></p> <p>Or have we all forgotten Sourceforge?</p> <p><a href="https://hadihariri.com/2020/10/14/a-few-words-on-git/">A few words on Git.</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on October 14, 2020.</p> <![CDATA[From Zero to Lambda with Kotless]]> https://hadihariri.com/2020/05/12/from-zero-to-lamda-with-kotless 2020-05-12T00:00:00+02:00 2020-05-12T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>I know, the title is cringeworthy. In fact the only thing worse is using a subtitle</p> <p><br /></p> <p><em>“with only one line of code”</em></p> <p><br /></p> <p>But allow me to indulge somewhat, because it really is accurate if one were to consider my knowledge of AWS Lambdas, Terraform, and AWS in general as somewhat zero. I mean sure, I know what they are, but I’ve not really played with them that much in the past.</p> <p><br /></p> <p>Today, I managed to create a new AWS account, set up my credentials, write a function in Kotlin and deploy it to AWS without even having to open up a single Terraform file. And all with <a href="https://site.kotless.io">Kotless</a>.</p> <p><br /></p> <p>In this post I’m going to walk you through the process. Using Kotless and deploying is in fact the smallest part of the entire thing. Most of this post is about setting up an AWS account and credentials, as well as my very superficial explanation of serverless. If you know all that, just skip right ahead to <strong>Writing our function</strong>.</p> <h2 id="what-is-serverless">What is Serverless?</h2> <p>I’m pretty sure <a href="https://en.wikipedia.org/wiki/Serverless_computing">Wikipedia</a> will offer you a much better definition than I can, but in its simplest form, imagine you want to run a function in the cloud without the overhead of having to have an HTTP application or set-up Docker, or anything else. You just want to run a simple Kotlin function, something like:</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fun</span> <span class="nf">sayHello</span><span class="p">()</span> <span class="p">=</span> <span class="s">"Say Hello!"</span> </code></pre></div></div> <p>which would respond to an endpoint <strong>/hello</strong>.</p> <p><br /></p> <p>Different technologies allow you to do that, including AWS Lambdas, Google Cloud Functions, as well as Azure Functions. And with the majority of them you can use their web control panel to write some function and deploy it. But we all know that in real-world applications, you’re not using GUIs to write and deploy apps!</p> <h3 id="terraform-galore">Terraform Galore</h3> <p>So what do you do in the real world? You write <a href="https://www.terraform.io/docs/providers/aws/r/lambda_function.html">Terraform files</a> to deploy your functions. And you don’t just write one, you write a lot! And the more functions, the more you need. The more resources you use (databases, files, etc.), the more complex these become.</p> <p><br /></p> <p>But what’s more, if you look through most of these configurations, they’re somewhat defining things that could be deduced from the actual code. And that’s where Kotless comes in.</p> <h2 id="welcome-to-kotless">Welcome to Kotless</h2> <p>Kotless is based on the idea that the code you write is already defining the infrastructure it needs (infrastructure as code) and thus uses this concept to deduce the necessary configuration files, write them out, and deploy it all for you. The only thing you have to do is write Kotlin code.</p> <h3 id="setting-up-aws">Setting up AWS</h3> <p>If you’re already an expert in AWS, what you’ll need is</p> <ul> <li>IAM credentials (and stored locally too)</li> <li>A bucket (and region)</li> </ul> <p>and you can skip the rest of this section and go directly to Writing our function.</p> <p>If like me however, you’re mostly new to managing AWS, not only can it be extremely overwhelming, but the help is also overwhelming too. In this section I’ll briefly walk you through what you need to get the above set up.</p> <p><br /></p> <p><strong>Step 1 - <a href="https://portal.aws.amazon.com/billing/signup?nc2=h_ct&amp;src=default&amp;redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start">Create an AWS account</a></strong>.</p> <p><br /></p> <p>You need to provide credit card details, but stick to the free tier and you should be fine. In addition, make sure you set up some alerts in case you suddenly go beyond what free provides. For these demos though you most certainly won’t hit anything beyond free!</p> <p>While you may want to download <a href="https://aws.amazon.com/cli/">AWS CLI</a> for certain management aspects, note that Kotless doesn’t need it.</p> <p><br /></p> <p><strong>Step 2 - Create IAM credentials</strong></p> <p><br /></p> <p>This is required by Kotless (Terraform actually) to deploy your functions. To do this, go to the <a href="https://aws.amazon.com/console/">AWS Management Console</a> (make sure you’re logged in) and search for IAM</p> <p><br /></p> <p><img src="https://hadihariri.com/images/Panel.png" alt="Panel" /></p> <p><br /></p> <p>Once in the IAM section, proceed to create a new user account by clicking on Users</p> <p><br /></p> <p><img src="https://hadihariri.com/images/Side-Panel.png" alt="Side Panel" /></p> <p><br /></p> <p>and then the <strong>Add User</strong> button</p> <p><br /></p> <p><img src="https://hadihariri.com/images/Add-User.png" alt="Add User" /></p> <p><br /></p> <p>This takes you through a series of steps to provide information for the new user. It’s important to remember here the name we give the user, which is the same one which will be defined on our local machine for Kotless to use. For this example, I’ve named it <strong>my.kotless.user</strong>.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/New-User-1.png" alt="New User Step 1" /></p> <p><br /></p> <p>Make sure <strong>Programmatic access</strong> is ticked.</p> <p><br /></p> <p>In the next step we’re going to define permissions. Obviously this needs to be fine-tuned based on what’s needed. For now we’re going to give full Admin</p> <p><br /></p> <p><img src="https://hadihariri.com/images/New-User-2.png" alt="New User Step 2" /></p> <p><br /></p> <p>The next step we’ll skip (as it’s to define tags), leading us to the final step which is to review and create the user.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/New-User-3.png" alt="New User Step 3" /></p> <p><br /></p> <p>Once done, you’ll be prompted with the user along with two values: <strong>Access key ID</strong> and <strong>Secret Access</strong> key.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/New-User-Final.png" alt="New User Final Step" /></p> <p><br /></p> <p><strong>Step 3 - Create an S3 bucket</strong></p> <p><br /></p> <p>Go back to the AWS Management Console and search for S3.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/Create-S3-1.png" alt="Create Bucket Step 1" /></p> <p><br /></p> <p>Click on <strong>Create bucket</strong> providing a name and region. Again, keep track of these two values as we’ll use them later.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/Create-S3-2.png" alt="Create Bucket Step 2" /></p> <p><br /></p> <p>Leave all other options as default.</p> <p><br /></p> <p><strong>Step 4 - Store the credentials locally</strong></p> <p><br /></p> <p>Kotless is going to need access to the credentials created, and we need to somehow provide these. These are stored in the user directory (on macOS/Linux this would be ~/.aws and on Windows in the home directory).</p> <p><br /></p> <p>Create a file name <strong>~/.aws/credentials</strong> and type in the following contents</p> <p><br /></p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[profile my.kotless.user] aws_access_key_id={the_access_key_id} aws_secret_access_key={the_secret_access_key} </code></pre></div></div> <p><br /></p> <p>Notice how the profile name matches the name of the IAM credential we created earlier.</p> <p><br /></p> <p>And that’s it. We’re now ready to write our function and deploy with Kotless.</p> <p><br /></p> <p><strong>Important</strong> - When you set up your AWS account, the system itself asks you to follow a series of good practices, such as removing root access, setting up MFA, defining groups with restricted permissions, etc. It’s important to go back and do this at some point. I’m avoiding it in here cause I know HOW EXCITED YOU ARE TO SEE THIS WORK! So let’s move on.</p> <h2 id="writing-our-function">Writing our function</h2> <p>Create a new build.gradle.kts project with the following contents (Kotless only supports Gradle Kotlin Script)</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nn">io.kotless.plugin.gradle.dsl.kotless</span> <span class="k">import</span> <span class="nn">org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile</span> <span class="n">group</span> <span class="p">=</span> <span class="s">"com.example.kotless"</span> <span class="n">version</span> <span class="p">=</span> <span class="s">"0.1"</span> <span class="nf">plugins</span> <span class="p">{</span> <span class="nf">kotlin</span><span class="p">(</span><span class="s">"jvm"</span><span class="p">)</span> <span class="n">version</span> <span class="s">"1.3.61"</span> <span class="n">apply</span> <span class="k">true</span> <span class="nf">id</span><span class="p">(</span><span class="s">"io.kotless"</span><span class="p">)</span> <span class="n">version</span> <span class="s">"0.1.3"</span> <span class="n">apply</span> <span class="k">true</span> <span class="p">}</span> <span class="nf">repositories</span> <span class="p">{</span> <span class="nf">jcenter</span><span class="p">()</span> <span class="nf">mavenCentral</span><span class="p">()</span> <span class="p">}</span> <span class="nf">dependencies</span> <span class="p">{</span> <span class="nf">implementation</span><span class="p">(</span><span class="nf">kotlin</span><span class="p">(</span><span class="s">"stdlib"</span><span class="p">))</span> <span class="nf">implementation</span><span class="p">(</span><span class="s">"io.kotless"</span><span class="p">,</span> <span class="s">"lang"</span><span class="p">,</span> <span class="s">"0.1.3"</span><span class="p">)</span> <span class="p">}</span> <span class="n">tasks</span><span class="p">.</span><span class="n">withType</span><span class="p">&lt;</span><span class="nc">KotlinJvmCompile</span><span class="p">&gt;</span> <span class="p">{</span> <span class="nf">kotlinOptions</span> <span class="p">{</span> <span class="n">jvmTarget</span> <span class="p">=</span> <span class="s">"1.8"</span> <span class="n">languageVersion</span> <span class="p">=</span> <span class="s">"1.3"</span> <span class="n">apiVersion</span> <span class="p">=</span> <span class="s">"1.3"</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>The settings.gradle.kts should contain</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">rootProject</span><span class="p">.</span><span class="n">name</span> <span class="p">=</span> <span class="s">"kotless"</span> <span class="nf">pluginManagement</span> <span class="p">{</span> <span class="nf">repositories</span> <span class="p">{</span> <span class="nf">gradlePluginPortal</span><span class="p">()</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>and import it into IntelliJ IDEA (or your IDE of choice). Now create a new package with the same name as that provided in the group (this is important) and inside it create a new file named anything - we’ll call it <strong>Functions.kt</strong></p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="nn">com.example.kotless</span> <span class="k">import</span> <span class="nn">io.kotless.dsl.lang.http.Get</span> <span class="k">fun</span> <span class="nf">sayHello</span><span class="p">()</span> <span class="p">=</span> <span class="s">"Say Hello!"</span> </code></pre></div></div> <p>So far, the only thing we’ve done is simply create a function that returns a string. What we want to do now is tell Kotless (i.e. AWS Lambda), where we want to respond with this function, i.e. what endpoint. For this we annotate the function with a @Get.</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Get</span><span class="p">(</span><span class="s">"/hello"</span><span class="p">)</span> <span class="k">fun</span> <span class="nf">sayHello</span><span class="p">()</span> <span class="p">=</span> <span class="s">"Say Hello!"</span> </code></pre></div></div> <h3 id="testing-locally">Testing locally</h3> <p>Before deploying, we can test this locally to see if it works by running the Gradle <strong>local</strong> task, and opening up the browser at <strong>http://0.0.0.0:8080/hello</strong></p> <h3 id="deploying-to-aws">Deploying to AWS</h3> <p>If everything works well, we can now proceed to deploy to AWS. For this we need to tell Kotless a few things, namely the profile, bucket (and region), we created earlier.</p> <p>Add the following configuration block to the end of the <strong>build.gradle.kts</strong> file</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">kotless</span> <span class="p">{</span> <span class="nf">config</span> <span class="p">{</span> <span class="n">bucket</span> <span class="p">=</span> <span class="s">"my.kotless.bucket"</span> <span class="nf">terraform</span> <span class="p">{</span> <span class="n">profile</span> <span class="p">=</span> <span class="s">"my.kotless.user"</span> <span class="n">region</span> <span class="p">=</span> <span class="s">"eu-west-1"</span> <span class="p">}</span> <span class="p">}</span> <span class="nf">webapp</span> <span class="p">{</span> <span class="nf">lambda</span> <span class="p">{</span> <span class="nf">kotless</span> <span class="p">{</span> <span class="n">packages</span> <span class="p">=</span> <span class="nf">setOf</span><span class="p">(</span><span class="s">"com.example.kotless"</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Notice how we’re using the previously defined values, namely <strong>my.kotless.bucket</strong>, <strong>eu-west-1</strong>, <strong>my.kotless.user</strong>, and <strong>com.example.kotless</strong>. It’s important to get this correct.</p> <p>That’s all that’s needed. Now we can simply run the Gradle <strong>deploy</strong> task and watch as magic happens!</p> <p><br /></p> <p>If all goes well, the process should end with build output providing you the root URL where you can access the function</p> <p><br /></p> <p><img src="https://hadihariri.com/images/Output.png" alt="Output" /></p> <p><br /></p> <p>Copying the URL to the browser and appending /hello should give the text output from the function.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/Browser.png" alt="Browser" /></p> <p><br /></p> <p>By the way, if you’re interested in seeing the generated Terraform files, check these under the <strong>build/kotless-gen/deploy</strong> folder in the project.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/Terraform.png" alt="Terraform Files" /></p> <p><br /></p> <h2 id="but-wait-theres-more">But wait, there’s more</h2> <p>Kotless not only supports simple functions but also <a href="https://ktor.io">Ktor</a> server-side applications, meaning you could now deploy your Ktor apps as lambdas. When it comes to AWS resources, there’s support for DynamoDB, static resources, and more. And in cases where you still need extra customization , you can write <a href="https://site.kotless.io/plugin/extensions">Terraform extensions</a>.</p> <p><br /></p> <p>Currently it only supports AWS but the actual code already provides a layer of abstraction making it possible to add support for Google Cloud and Azure. Imagine being able to take advantage of serverless technology without having vendor lock-in (to a certain extent at least). And to do all this without needing to write massive amounts of Terraform configuration files. This is where Kotless is providing value!</p> <p><br /></p> <p>The project itself is OSS and available on <a href="https://github.com/JetBrains/kotless">GitHub</a>, and gladly accepts contributions.</p> <p><br /></p> <p>Before wrapping up, I wanted to thank my colleague <a href="https://github.com/tanvd">Vladislav Tankov</a>, for not only creating this awesome framework, but also for his help and reviews.</p> <p><a href="https://hadihariri.com/2020/05/12/from-zero-to-lamda-with-kotless/">From Zero to Lambda with Kotless</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on May 12, 2020.</p> <![CDATA[Focus]]> https://hadihariri.com/2020/04/24/focus 2020-04-24T00:00:00+02:00 2020-04-24T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>A few years ago I started using an application for macOS called <a href="https://heyfocus.com">Focus</a>, which allows you to block applications and websites for a period of time.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/focus-0.png" alt="Focus Site" /></p> <p><br /></p> <p>On getting a new laptop, I never got round to installing it, despite its usefulness.</p> <p><br /></p> <h2 id="the-negativity-rabbit-hole">The negativity rabbit hole.</h2> <p>With the recent COVID-19 pandemic (leaving a note for those reading this post in 20 years from now and not being born yet), it has become extremely difficult to avoid a constant flow of negative news. While it is certainly important to know what is going on, the media currently has a very strong focus on making sure every article is negative.</p> <p><br /></p> <p>I’m sure it’s not easy to find positivity in the current climate, yet at the same time, I’m even more certain many don’t even try. Bad news makes great headlines. Headlines sell! Of course one should wonder what it is anyone is actually selling these days given we’re all confined to our homes and consumer economy around the world has essentially shut down. However, that’s another question.</p> <p><br /></p> <p>This constant negativity can end up draining you emotionally and mentally. I recently found myself in this situation. I’d get up in the morning, read the news, and already this would set me up in a bad spot. I’d start work, forget for a while, and yet during every pause, I’d check Twitter or some news site and then end up again with negative emotions.</p> <p><br /></p> <p>I decided it was time to stop, which is where Focus came to the rescue.</p> <p><br /> I’ve now installed Focus again and have a schedule that blocks certain applications and websites from 7 am in the morning until 5 pm. <br /> <br /></p> <p><img src="https://hadihariri.com/images/focus-2.png" alt="Focus Site Block" /></p> <p><br /> <br /></p> <p>You can add as many websites as you like, albeit it already comes with a good list (of bad habits) to begin with.</p> <p><br /> <br /></p> <p><img src="https://hadihariri.com/images/focus-1.png" alt="Focus Site Block" /></p> <p><br /> <br /></p> <h2 id="is-it-working">Is it working?</h2> <p>For now, it seems to be, yes! I can tell you that in the past 2-3 weeks since I’ve installed it, not only has my mood improved, but I also feel like I’m getting more done. The app in fact allows me to take small breaks (up to 30 minutes during the entire period), and while initially I found I was using this to its maximum extent, lately I don’t even use much of this time. About the only time I do use the break is if I need to access Twitter for some reason (yes, that includes tweeting this post).</p> <p><br /> Of course, I can still use my phone to access any site (and Twitter), but again I’ve found that not having that habit of “let me just open up a news site while I’m waiting for this to build”, has really helped me.</p> <p><br /> Many of you may not need, as you may have a native application built-in (called discipline). But for those of us that sometimes struggle, I’d suggest you give it a try!</p> <p><a href="https://hadihariri.com/2020/04/24/focus/">Focus</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on April 24, 2020.</p> <![CDATA[Our reliance on a few big players]]> https://hadihariri.com/2020/04/05/our-reliance-on-a-few-big-players 2020-04-05T00:00:00+02:00 2020-04-05T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>And the world shut down.</p> <blockquote> <p>As long as I can still order things on Amazon…</p> </blockquote> <p><br /></p> <p><em>and Amazon’s stock continued to go up</em></p> <p><br /></p> <p>In our globalized world, with complex supply chains, as the world shut down, and the street corner hardware stores, restaurants, coffee shops, all pulled their blinds down, the only place we had left to order our non-essentials (and often essentials) was Amazon. Because you can find anything on Amazon.</p> <p><br /> Amazon and Amazon Market Place, a site where everyone could sell anything suddenly has become the key provider in a world where everything else seems to have come to a halt. The problem of course is when this also comes to a halt, or at a minimum, slows down. And it has - <a href="https://www.vox.com/recode/2020/3/22/21190372/amazon-prime-delivery-delays-april-21-coronavirus-covid-19">Prime deliveries taking longer</a>, non-essential goods are being <a href="https://slate.com/culture/2020/03/amazon-book-delivery-delays-coronavirus.html">deprioritized</a>.</p> <h2 id="the-effects-of-globalization">The effects of Globalization</h2> <p>It’s now clear to many that Globalization does have its drawbacks. Outsourcing certain types of supplies such as medical equipment to other countries, and relying now on the good faith of not only your suppliers, but of other countries <a href="https://www.theguardian.com/world/2020/apr/03/mask-wars-coronavirus-outbidding-demand">not intervening to bid higher</a> for things you’ve ordered, has a cost - that of human lives. Of course, you can’t blame any single country. Each one is looking out for their own people. But ultimately this is one of the many costs of Globalization. The other ones, such as low income wages, horrendous working conditions, have been rather foreign to many of us in the Western world because they haven’t really impacted our lives.</p> <p><br /> But Globalization is also present online. Except in this case we don’t call it Globalization, we call it Big Tech. Our reliance on a few large companies has become so critical that not only has it hindered competition, but it can also stop the livelihood of many businesses at a time when they’ve had to close their doors and their own potential source of income is online activity.</p> <h2 id="dont-compete-with-big-tech">Don’t compete with Big Tech</h2> <p>In the IT industry it’s common knowledge that you try not to compete with “Big tech”. Any idea you have, make sure you’re not going to compete with the big ones, cause they have infinite money, more resources, better infrastructure, and if push comes to shove, pretty sure they can offer whatever it is for free, or cheaper than you can.</p> <p><br /> Of course this not only hinders competition, but also innovation. The reality is that this is not limited to IT. Many types of businesses are affected by a few big players. They either decide to not compete or rely on their platforms when it comes to providing any value-added service.</p> <p><br /> You have a candle store and also sell online? Why set up everything yourself? Rely on Big Tech to take care of it for you. It’s much cheaper and more effective. And as a bonus, you don’t even have to worry about how to price things. They’ll make sure you never price it more than they want you to.</p> <p><br /> Now of course, these are exceptional times, and even if we were to diversify, it wouldn’t guarantee that things would be significantly better. But at the same time, we all know that all eggs in a single basket (or should I say cart) isn’t a great strategy.</p> <h2 id="lessons-well-learn">Lessons we’ll learn</h2> <blockquote> <p>It’s going to get worse before it gets better</p> </blockquote> <p>A phrase repeated so often nowadays. A sentence that plays tricks on your mind, to prepare you for bad times, but then give you a glimmer of hope. This is not the first pandemic, nor is it certainly the last. And of course we will recover from this and things will get better. The question though is what lessons will we learn.</p> <p><br /></p> <ul> <li>Will our leaders understand that we need to invest more in public health care?</li> <li>Will they reconsider outsourcing critical products and services?</li> <li>Will they invest more in research and vaccines to be better prepared for the next one?</li> <li>Will business owners start to look for alternative ways to market their products, that isn’t only with the walk-in customer?</li> </ul> <p><br /> And us, in the IT industry, the ones that can help others take advantage of technology, what will we learn?</p> <p><br /> It is not the inaction that we’ve taken or the mistakes that we’ve made that we should be focusing on when this is over, but the lessons that we can learn from them moving forward.</p> <p><a href="https://hadihariri.com/2020/04/05/our-reliance-on-a-few-big-players/">Our reliance on a few big players</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on April 05, 2020.</p> <![CDATA[Routing in Ktor]]> https://hadihariri.com/2020/04/02/Routing-in-Ktor 2020-04-02T00:00:00+02:00 2020-04-02T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>One of <a href="https://ktor.io">Ktor’s</a> strong points is in the flexibility it offers in terms of structuring your application. Different to many other server-side frameworks, it doesn’t force you into a specific pattern such as having to place all cohesive routes in a single class name <code class="language-plaintext highlighter-rouge">{XZY}Controller</code> for instance.</p> <p><br /> Of course, not being forced into using a specific pattern also has its downsides. How am I meant to structure my app? What’s the best convention to follow?</p> <p><br /> <br /> I recently asked the same question on Twitter <br /> <br /></p> <blockquote class="twitter-tweet"><p lang="en" dir="ltr">If you&#39;re using Ktor for server-side, how do you organise your routes? If other, please feel free to reply below. Also RT appreciated.</p>&mdash; Hadi Hariri (@hhariri) <a href="https://twitter.com/hhariri/status/1243493271105667072?ref_src=twsrc%5Etfw">March 27, 2020</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p><br /> and the results were somewhat surprising - didn’t expect 25.3% of folks to put them all into a single routing function. For anything beyond a simple application this could get quite ugly quite quickly.</p> <p><br /> <br /> But it did get me thinking in that maybe it would be good to provide some different samples of how one could structure an application.</p> <p><br /> <br /> For our example we’re going to assume that our application deals with Customers and Orders.</p> <h2 id="defining-routes">Defining routes</h2> <p>Before we talk about how we can group routes, let’s first discuss ways in which we can define them. Something which is again quite flexible in Ktor.</p> <p><br /> Generally routes are defined using the <code class="language-plaintext highlighter-rouge">routing</code> function. We can then create routes using verbs and paths</p> <p><br /> <br /></p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">routing</span> <span class="p">{</span> <span class="k">get</span><span class="p">(</span><span class="s">"/customer/{id}"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="nf">post</span><span class="p">(</span><span class="s">"/customer"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="k">get</span><span class="p">(</span><span class="s">"/order/{id}"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p><br /> or we can group routes by URL <br /></p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">routing</span> <span class="p">{</span> <span class="nf">route</span><span class="p">(</span><span class="s">"/customer"</span><span class="p">)</span> <span class="p">{</span> <span class="k">get</span> <span class="p">{</span> <span class="p">}</span> <span class="nf">post</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p><br /> and of course we can also have sub-routes <br /></p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">routing</span> <span class="p">{</span> <span class="nf">route</span><span class="p">(</span><span class="s">"/order"</span><span class="p">)</span> <span class="p">{</span> <span class="nf">route</span><span class="p">(</span><span class="s">"/shipment"</span><span class="p">)</span> <span class="p">{</span> <span class="k">get</span> <span class="p">{</span> <span class="p">}</span> <span class="nf">post</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <h3 id="using-route-extension-functions">Using Route Extension Functions</h3> <p>A common pattern is to use extension functions on <code class="language-plaintext highlighter-rouge">Route</code> to define the actual routes, allowing us easy access to the verbs, and remove clutter of having all routes in a single <code class="language-plaintext highlighter-rouge">routing</code> function. We can apply this pattern independently of how we decide to group routes. As such, the first example could be represented in a cleaner way</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">routing</span> <span class="p">{</span> <span class="nf">customerByIdRoute</span><span class="p">()</span> <span class="nf">createCustomerRoute</span><span class="p">()</span> <span class="nf">orderByIdRoute</span><span class="p">()</span> <span class="nf">createOrder</span><span class="p">()</span> <span class="p">}</span> <span class="k">fun</span> <span class="nc">Route</span><span class="p">.</span><span class="nf">customerByIdRoute</span><span class="p">()</span> <span class="p">{</span> <span class="k">get</span><span class="p">(</span><span class="s">"/customer/{id}"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> <span class="k">fun</span> <span class="nc">Route</span><span class="p">.</span><span class="nf">createCustomerRoute</span><span class="p">()</span> <span class="p">{</span> <span class="nf">post</span><span class="p">(</span><span class="s">"/customer"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> <span class="k">fun</span> <span class="nc">Route</span><span class="p">.</span><span class="nf">orderByIdRoute</span><span class="p">()</span> <span class="p">{</span> <span class="k">get</span><span class="p">(</span><span class="s">"/order/{id}"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> <span class="k">fun</span> <span class="nc">Route</span><span class="p">.</span><span class="nf">createOrder</span><span class="p">()</span> <span class="p">{</span> <span class="nf">post</span><span class="p">(</span><span class="s">"/order"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>This now leads us to the question at hand - how do we group these routes? We certainly don’t want everything in a single file.</p> <h2 id="grouping-by-file">Grouping by file</h2> <p>The most voted-for solution is grouping routes that are related in a single file. In our case, this would mean having a <code class="language-plaintext highlighter-rouge">CustomerRoutes</code> and an <code class="language-plaintext highlighter-rouge">OrderRoutes</code> file for instance</p> <p><br /></p> <p><strong>CustomerRoutes.kt</strong></p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fun</span> <span class="nc">Route</span><span class="p">.</span><span class="nf">customerById</span><span class="p">()</span> <span class="p">{</span> <span class="k">get</span><span class="p">(</span><span class="s">"/customer/{id}"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> <span class="k">fun</span> <span class="nc">Route</span><span class="p">.</span><span class="nf">createCustomer</span><span class="p">()</span> <span class="p">{</span> <span class="nf">post</span><span class="p">(</span><span class="s">"/customer"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p><strong>OrderRoutes.kt</strong></p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fun</span> <span class="nc">Route</span><span class="p">.</span><span class="nf">orderByIdRoute</span><span class="p">()</span> <span class="p">{</span> <span class="k">get</span><span class="p">(</span><span class="s">"/order/{id}"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> <span class="k">fun</span> <span class="nc">Route</span><span class="p">.</span><span class="nf">createOrderRoute</span><span class="p">()</span> <span class="p">{</span> <span class="nf">post</span><span class="p">(</span><span class="s">"/order"</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>What would happen with sub-routes? Such as <code class="language-plaintext highlighter-rouge">order/shipment</code> for instance? It somewhat depends on what we understand by this URL. If we’re talking about these as resources (which they are), <code class="language-plaintext highlighter-rouge">shipment</code> itself could therefore be a resource, and could easily map to another file <code class="language-plaintext highlighter-rouge">ShipmentRoutes.kt</code>.</p> <p><br /></p> <h3 id="grouping-routing-definitions">Grouping routing definitions</h3> <p>One advantage of this approach is that we can also group the routing definitions, and potentially features, per file. For instance, let’s assume that we follow the group per file layout as above. Even though are routes in a different files, we need to declare them at Application level. As such our app would look something like the following</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">routing</span> <span class="p">{</span> <span class="nf">customerByIdRoute</span><span class="p">()</span> <span class="nf">createCustomerRoute</span><span class="p">()</span> <span class="nf">orderByIdRoute</span><span class="p">()</span> <span class="nf">createOrderRoute</span><span class="p">()</span> <span class="p">}</span> </code></pre></div></div> <p>If we have tons of routes in our app, this could quickly become long and cumbersome. Since we have however routes grouped by file, we can take advantage of this and define the routing in each file also. For this we could create an extension for <code class="language-plaintext highlighter-rouge">Application</code> and define the routes</p> <p><strong>CustomerRoutes.kt</strong></p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fun</span> <span class="nc">Application</span><span class="p">.</span><span class="nf">customerRoutes</span><span class="p">()</span> <span class="p">{</span> <span class="nf">routing</span> <span class="p">{</span> <span class="nf">customerByIdRoute</span><span class="p">()</span> <span class="nf">createCustomerRoute</span><span class="p">()</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p><strong>OrderRoutes.kt</strong></p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fun</span> <span class="nc">Application</span><span class="p">.</span><span class="nf">orderRoutes</span><span class="p">()</span> <span class="p">{</span> <span class="nf">routing</span> <span class="p">{</span> <span class="nf">orderByIdRoute</span><span class="p">()</span> <span class="nf">createOrderRoute</span><span class="p">()</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p><br /> Now in our actual <code class="language-plaintext highlighter-rouge">Application.module</code> startup, we’d simply call these functions, without the need for <code class="language-plaintext highlighter-rouge">routing</code> block</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fun</span> <span class="nc">Application</span><span class="p">.</span><span class="nf">module</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// Init....</span> <span class="nf">customerRoutes</span><span class="p">()</span> <span class="nf">orderRoutes</span><span class="p">()</span> <span class="p">}</span> </code></pre></div></div> <p><br /> We can even take this one step further - install features per application, as needed, especially for instance when we’re using the <code class="language-plaintext highlighter-rouge">Authentication</code> feature which depends on specific routes. One important note however is that Ktor will detect if a feature has been installed twice by throwing an <code class="language-plaintext highlighter-rouge">DuplicateApplicationFeatureException</code> exception.</p> <h3 id="a-note-on-using-objects">A note on using objects</h3> <p>Using objects to group routing functions doesn’t provide any kind of performance or memory benefits, as top-level functions in Ktor are instantiated a single time. While it can provide some sort of cohesive structure where you may want to share common functionality, it isn’t necessary to use objects in case you’re worried about any kind of overhead.</p> <h2 id="grouping-by-folders">Grouping by folders</h2> <p>One disadvantage of the above two solutions is that if our route handlers are somewhat complicated (read long), having everything in a single file can become a bit cumbersome. What we could do instead is use folders (i.e. packages) to define different areas and then have each route in its own file.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/ktor-routing-1.png" alt="Grouping by Folders Project Layout" /></p> <p><br /></p> <p>While this certainly does provide the advantage of a nice layout when it comes to routes and the individual actions, it could certainly lead to “package overload”, and potentially having tons of filenames named the same, making navigation somewhat more difficult. On the other hand, as we’ll see in the next example, we could also merely prefix each file with area (i.e. CustomerCreate.kt for instance).</p> <h2 id="grouping-by-features">Grouping by features</h2> <p>If you’ve ever worked with frameworks such as ASP.NET MVC (or Ruby on Rails), you may be familiar with the concept of structuring applications using three folders - Model, View, and Controllers (Routes).</p> <p><br /></p> <p><img src="https://hadihariri.com/images/ktor-routing-2.png" alt="Model View Routes" /></p> <p><br /></p> <p>This isn’t far-fetched with the schema we have above which is grouping routes in their own packages/files, our views in the <code class="language-plaintext highlighter-rouge">resources</code> folder in the case of Ktor, and of course, nothings prevents us from having a package <code class="language-plaintext highlighter-rouge">model</code> where we place any data we want to display or respond to HTTP endpoints with.</p> <p><br /> But it does beg the question - is this actually the best approach? Wouldn’t it make sense to group things by features as opposed to the infrastructure-level functionality? i.e. instead of having the project distributed by <code class="language-plaintext highlighter-rouge">routes</code>, <code class="language-plaintext highlighter-rouge">models</code> and <code class="language-plaintext highlighter-rouge">views</code>, have these groups by specific behaviour/features, i.e. <code class="language-plaintext highlighter-rouge">OrderProcessPayment</code>, <code class="language-plaintext highlighter-rouge">CustomerAddressChange</code>, etc.</p> <p><br /></p> <p><img src="https://hadihariri.com/images/ktor-routing-3.png" alt="Change Address Layout" /></p> <p><br /></p> <p>With many frameworks, this kind of organization of code isn’t viable without seriously hacking the underlying conventions. However with Ktor, given how flexible it is, in principle it shouldn’t be a problem. With one caveat - when we’re using a template engine, resources could be an issue. But let’s see how we could solve this.</p> <p><br /> How this problem is solved very much depends on what is used for Views. If our application is merely an HTTP backend and we’re using client-side technology, then this is a no-brainer as usually all rendering is client-side. If we’re using Kotlinx.HTML, then once again it’s not an issue as the page can be generated from any Kotlin file placed anywhere. The issue arises more when we’re using a templating engine such as <a href="https://freemarker.sourceforge.io/">FreeMarker</a>. These are peculiar in how and where template files should be located. Fortunately some of them offer flexibility in how templates are loaded.</p> <p><br /> For instance with FreeMarker, we can use a <code class="language-plaintext highlighter-rouge">MultiTemplateLoader</code> and then have templates loaded from different locations</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">install</span><span class="p">(</span><span class="nc">FreeMarker</span><span class="p">)</span> <span class="p">{</span> <span class="kd">val</span> <span class="py">customerTemplates</span> <span class="p">=</span> <span class="nc">FileTemplateLoader</span><span class="p">(</span><span class="nc">File</span><span class="p">(</span><span class="s">"./customer/changeAddress"</span><span class="p">))</span> <span class="kd">val</span> <span class="py">loaders</span> <span class="p">=</span> <span class="n">arrayOf</span><span class="p">&lt;</span><span class="nc">TemplateLoader</span><span class="p">&gt;(</span><span class="n">customerTemplates</span><span class="p">)</span> <span class="n">templateLoader</span> <span class="p">=</span> <span class="nc">MultiTemplateLoader</span><span class="p">(</span><span class="n">loaders</span><span class="p">)</span> <span class="p">}</span> </code></pre></div></div> <p><br /> Obviously this code isn’t ideal as it uses relative paths amongst other things, but it’s not hard to see how we could actually have this loop through folders and load templates, or even have a custom build action that copies views to our <code class="language-plaintext highlighter-rouge">resources</code> folder prior to execution. There are quite a number of ways to solve the issue.</p> <p><br /> The benefit of this approach is that we can group everything related to the same functionality in a single location, by feature, as opposed to the technical/infrastructure aspect of it.</p> <h2 id="whatever-works-for-you">Whatever works for you…</h2> <p>As we can see, Ktor is extremely flexible when it comes to not only how we define routes but how we group and structure them. Each have their own benefits and disadvantages, and ultimately I’d recommend using one that works best for you in your scenario.</p> <p><br /> If you have other approaches, would love to hear about them though. Please feel free to leave some comments!</p> <p><a href="https://hadihariri.com/2020/04/02/Routing-in-Ktor/">Routing in Ktor</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on April 02, 2020.</p> <![CDATA[Making a habit of giving feedback]]> https://hadihariri.com/2020/01/31/making-a-habit-of-giving-feedback 2020-01-31T00:00:00+01:00 2020-01-31T00:00:00+01:00 Hadi Hariri https://hadihariri.com [email protected] <p>How many times have you heard yourself or someone else say</p> <blockquote> <p>“We should give more feedback”</p> </blockquote> <p>I’m pretty sure it’s too many to count.</p> <p><br /> When it comes to feedback however, we usually think about it in terms of hierarchy; that is, I should receive feedback from my manager, and hopefully also give them feedback. The reality at times though is that we often forget to give feedback to our managers. In her book <a href="https://www.radicalcandor.com/">Radical Candor</a> Kim Scott highlights this point and places emphasis on how important it is for managers to also be recipients of feedback. However, she also talks about another important aspect which is peer-to-peer feedback. This is certainly something we don’t do as often as we should.</p> <p><br /></p> <h3 id="well-actually">Well, actually!</h3> <p>The last sentence isn’t entirely correct. Sometimes we’re actually quite good at giving <em>feedback</em> to colleagues, very quickly highlighting <em>issues</em> we see. We call it constructive criticism, albeit sometimes it’s far from constructive, even if we have no ill-intent. In a recent research by Marcus Buckingham and Ashley Goodall, they wrote about <a href="https://hbr.org/2019/03/the-feedback-fallacy">The Feedback Fallacy</a> and how not everything we perceive about feedback is what it seems.</p> <p><br /> But the article also points out, much like Kim does in her book, that feedback can help. As individuals, we strive to improve. Often times the line of work we do doesn’t provide us with enough data to know whether we’re on the right path. Having external folks guide you can be very beneficial. And of course positive reinforcement is also extremely important as it can help motivate and inspire us to continue to do what we do.</p> <p><br /></p> <h3 id="id-love-to-give-feedback-i-just-dont-always-remember-to">I’d love to give feedback, I just don’t always remember to</h3> <p>Many of us have good intentions and want to give feedback. Yet, we’re all busy doing our thing and often de-prioritize this task. On the Developer Advocacy team at JetBrains, we decided to try and put our feedback where our mouth is (sorry…) and do something about it that wouldn’t just end up in words. We decided to make it a rule that every person has to review the work of someone else during current or past week, and give them feedback on it. In order to do this, we decided to write a small bot for <a href="https://jetbrains.com/space">Space</a> that takes the list of folks on the team, randomly assigns them in pairs and emits a message once a week, indicating the feedback pairs for that week. On a side note, I now have a more difficult job hiring people - we need to make sure we have an even number of people on the team. Otherwise one person ends up with having to give feedback twice! But they’ll also receive it twice, so that’s great.</p> <h3 id="the-code">The code…</h3> <p>The code itself is too simple to even bother mentioning, but in case you’re wondering, we simply use the HTTP API to get a list of team members, create a set of pairs and emit a message to a feedback channel. And that’s scheduled to happen every Monday morning.</p> <div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fun</span> <span class="nf">createRandomPairs</span><span class="p">(</span><span class="n">input</span><span class="p">:</span> <span class="nc">List</span><span class="p">&lt;</span><span class="nc">SpacePerson</span><span class="p">&gt;):</span> <span class="nc">Set</span><span class="p">&lt;</span><span class="nc">Pair</span><span class="p">&lt;</span><span class="nc">SpacePerson</span><span class="p">,</span> <span class="nc">SpacePerson</span><span class="p">&gt;&gt;</span> <span class="p">{</span> <span class="kd">val</span> <span class="py">shuffled</span> <span class="p">=</span> <span class="n">input</span><span class="p">.</span><span class="nf">shuffled</span><span class="p">()</span> <span class="kd">val</span> <span class="py">items</span> <span class="p">=</span> <span class="n">shuffled</span><span class="p">.</span><span class="nf">windowed</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="k">true</span><span class="p">)</span> <span class="k">return</span> <span class="n">items</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="nc">Pair</span><span class="p">(</span><span class="n">it</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="k">if</span> <span class="p">(</span><span class="n">it</span><span class="p">.</span><span class="nf">count</span><span class="p">()</span> <span class="p">==</span> <span class="mi">2</span><span class="p">)</span> <span class="n">it</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="n">shuffled</span><span class="p">.</span><span class="nf">first</span><span class="p">())</span> <span class="p">}.</span><span class="nf">toSet</span><span class="p">()</span> <span class="p">}</span> <span class="kd">data class</span> <span class="nc">SpacePerson</span><span class="p">(</span><span class="kd">val</span> <span class="py">id</span><span class="p">:</span> <span class="nc">String</span><span class="p">,</span> <span class="kd">val</span> <span class="py">username</span><span class="p">:</span> <span class="nc">String</span><span class="p">)</span> <span class="kd">class</span> <span class="nc">FeedbackBotAlert</span> <span class="p">{</span> <span class="kd">val</span> <span class="py">spaceClient</span> <span class="p">=</span> <span class="nc">SpaceClient</span><span class="p">()</span> <span class="nd">@Scheduled</span><span class="p">(</span><span class="n">cron</span> <span class="p">=</span> <span class="s">"0 0 8 * * 1"</span><span class="p">)</span> <span class="nd">@Synchronized</span> <span class="k">fun</span> <span class="nf">feedbackAlert</span><span class="p">()</span> <span class="p">{</span> <span class="kd">val</span> <span class="py">list</span> <span class="p">=</span> <span class="nf">feedbackList</span><span class="p">()</span> <span class="nf">sendFeedbackMessage</span><span class="p">(</span><span class="n">list</span><span class="p">,</span> <span class="nc">Constants</span><span class="p">.</span><span class="nc">SPACE_CHATID_FEEDBACK_BOT</span><span class="p">)</span> <span class="p">}</span> <span class="k">fun</span> <span class="nf">sendFeedbackMessage</span><span class="p">(</span><span class="n">feedbackList</span><span class="p">:</span> <span class="nc">Set</span><span class="p">&lt;</span><span class="nc">Pair</span><span class="p">&lt;</span><span class="nc">SpacePerson</span><span class="p">,</span> <span class="nc">SpacePerson</span><span class="p">&gt;&gt;,</span> <span class="n">channelId</span><span class="p">:</span> <span class="nc">String</span> <span class="p">=</span> <span class="nc">Constants</span><span class="p">.</span><span class="nc">SPACE_CHATID_FEEDBACK_BOT</span><span class="p">)</span> <span class="p">{</span> <span class="n">spaceClient</span><span class="p">.</span><span class="nf">sendChatMessage</span><span class="p">(</span><span class="n">channelId</span><span class="p">,</span> <span class="s">"## This is your feedback bot"</span><span class="p">)</span> <span class="n">feedbackList</span><span class="p">.</span><span class="nf">forEach</span> <span class="p">{</span> <span class="kd">val</span> <span class="py">firstPerson</span> <span class="p">=</span> <span class="s">"@{${it.first.id}, ${it.first.username}}"</span> <span class="kd">val</span> <span class="py">secondPerson</span> <span class="p">=</span> <span class="s">"@{${it.second.id}, ${it.second.username}}"</span> <span class="n">spaceClient</span><span class="p">.</span><span class="nf">sendChatMessage</span><span class="p">(</span><span class="n">channelId</span><span class="p">,</span> <span class="s">"$firstPerson and $secondPerson, you need to give each other feedback this week"</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span> <span class="k">fun</span> <span class="nf">feedbackList</span><span class="p">():</span> <span class="nc">Set</span><span class="p">&lt;</span><span class="nc">Pair</span><span class="p">&lt;</span><span class="nc">SpacePerson</span><span class="p">,</span> <span class="nc">SpacePerson</span><span class="p">&gt;&gt;</span> <span class="p">{</span> <span class="kd">val</span> <span class="py">advocates</span> <span class="p">=</span> <span class="n">spaceClient</span><span class="p">.</span><span class="nf">getTeamByName</span><span class="p">(</span><span class="nc">Constants</span><span class="p">.</span><span class="nc">SPACE_TEAM_DEVELOPER_ADVOCACY</span><span class="p">)</span><span class="o">?.</span><span class="n">memberships</span> <span class="o">?:</span> <span class="nc">MembershipCollection</span><span class="p">()</span> <span class="k">return</span> <span class="nf">createRandomPairs</span><span class="p">(</span><span class="n">advocates</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="nc">SpacePerson</span><span class="p">(</span><span class="n">it</span><span class="p">.</span><span class="n">id</span><span class="p">,</span> <span class="n">it</span><span class="p">.</span><span class="n">member</span><span class="p">.</span><span class="n">username</span><span class="p">)</span> <span class="p">})</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p><br /> At this point it’s too early to tell whether this will be effective and we’ll stick to the schedule. For now we’ve just decided to keep it simple and use the bot as means to randomly pick people and remind us to give feedback. And that’s really all we need when it comes to automation. The next and most important step is for us to make sure we actually deliver on this task. Hopefully we will. And I’ll let y’all know in a few months. Or years…</p> <p><a href="https://hadihariri.com/2020/01/31/making-a-habit-of-giving-feedback/">Making a habit of giving feedback</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on January 31, 2020.</p> <![CDATA[Your privacy, your control.]]> https://hadihariri.com/2019/11/17/your-privacy-your-control 2019-11-17T00:00:00+01:00 2019-11-17T00:00:00+01:00 Hadi Hariri https://hadihariri.com [email protected] <p>I’m sure you’ve probably heard Mark Zuckerberg talk about how they are giving their users the choice when it comes to privacy. That they’re putting privacy in the hands of you, the user. That you’re in control of what you want to share and with whom you want to share it. <br /> <br /> It’s a lie. <br /> <br /> Lie is harsh? Fair enough. Let’s call it misleading.</p> <h2 id="control-center">Control Center</h2> <p>I’m on LinkedIn and recently I decided to go through the privacy options for my account…</p> <p><br /></p> <p><img src="/images/linkedin-1.png" alt="LinkedIn 1" /> <br /></p> <p><img src="/images/linkedin-2.png" alt="LinkedIn 2" /> <br /></p> <p><img src="/images/linkedin-3.png" alt="LinkedIn 3" /> <br /></p> <p><img src="/images/linkedin-4.png" alt="LinkedIn 4" /> <br /></p> <p><img src="/images/linkedin-5.png" alt="LinkedIn 5" /> <br /></p> <p>And these were just about Privacy. Then we have an entire tab for Advertising, and one more for Communications <br /> <br /> <img src="/images/linkedin-6.png" alt="LinkedIn 6" /> <br /></p> <p>I’d consider myself a tech-savy person who cares about their privacy, so I probably would take the time to go through all this and try to configure everything. Do you think though that that is something that your everyday user would do? Most likey not, which leaves them in the vulnerable position of relying on what the default options are. And guess what? At times these aren’t trying to favour your privacy but maximise the return on your data.</p> <p><br /> And just so it’s clear, I’m not singling out LinkedIn. Fortunately I deleted my Facebook account years ago, but I’m guessing that it’s somewhat in the same league.</p> <h2 id="we-should-be-favouring-simplicity">We should be favouring simplicity</h2> <p>Giving users a command center which at times feels more complex than an plane’s cockpit, allowing them to toggle 50 different options to indicate exactly what data they want to share, is not the way we should be defining interfaces if we truly care about our users privacy. We should be making it extremely simple for them to do this, and defaulting to sharing as little as possible.</p> <p><br /> And yet what we’re seeing in the industry is a move to more fine-grained control of what exactly we want to be exposed to as a user, whether this is privacy settings or the cookies we want to receive.</p> <p><br /> <br /> We disguise this under the pretext of <em>being transparent</em>, yet what we’re really trying to do is harvest as much personal information as possible and then tell users (or authorities if they come knocking), that you’re in control.</p> <p><a href="https://hadihariri.com/2019/11/17/your-privacy-your-control/">Your privacy, your control.</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on November 17, 2019.</p> <![CDATA[Getting Started with Kotlin for .NET Developers]]> https://hadihariri.com/2019/08/16/getting-started-with-kotlin-for-net-developers 2019-08-16T00:00:00+02:00 2019-08-16T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>I’ve been asked quite a few times by .NET Developers (as well as those not familiar with Java/JVM), what material to use to get started with Kotlin coming from a non-Java background. As such, I feel it’s probably more efficient to have this outlined in a blog post as opposed to a series of tweets.</p> <h3 id="kotlin-was-kotlinjvm-it-no-longer-is">Kotlin was Kotlin/JVM. It no longer is.</h3> <p>When we first started Kotlin, the only platform it supported was the JVM. Today we have Kotlin/JS and Kotlin/Native, which opens up possibility to many targets such as iOS, macOS, Windows, etc. And of course Android. <br /></p> <p>But it’s no secret that originating on the JVM, there’s a heavy influence of this in the documentation, learning material and available courses, most of them assuming that you know some Java and are familiar with the JVM. The good news is that we’re working on improving all this, but as with anything, it takes time.</p> <p><br /> In the meantime, hopefully you’ll find some of following useful.</p> <h3 id="getting-up-to-speed-with-the-jvm-and-the-tooling">Getting up to speed with the JVM and the tooling</h3> <p>I wrote the following guides when I first came to Kotlin and the JVM, so they very much are from the perspective of a .NET developer.</p> <ul> <li><a href="https://hadihariri.com/2013/12/29/jvm-minimal-survival-guide-for-the-dotnet-developer/">JVM Minimal Survival Guide</a></li> <li><a href="https://hadihariri.com/2014/01/06/intellij-idea-minimal-survival-guide/">IntelliJ IDEA Minimal Survival Guide</a></li> </ul> <p>They’re mostly still relevant and a good starting point to get you up to speed with the JVM and also IntelliJ IDEA. While there are a lot of comparisons with .NET, obviously any developer can read it and hopefully it will be useful. Also, if you want to learn a bit more about IntelliJ IDEA, there’s <a href="https://www.youtube.com/watch?v=eq3KiAH4IBI">my IntelliJ IDEA 42 Tips and Tricks talk</a></p> <h3 id="getting-up-to-speed-with-kotlin">Getting up to speed with Kotlin</h3> <p>If you’re completely new to Kotlin, there are quite a few courses available to get you up to speed</p> <ul> <li><a href="https://www.atomickotlin.com/atomickotlin/">Atomic Kotlin</a> by Sveta Isakova and Bruce Eckel. This one assume not only zero knowledge of Java, but also of programming.</li> <li><a href="http://shop.oreilly.com/product/0636920052982.do">My Intro to Kotlin O’Reilly Course</a> and <a href="http://shop.oreilly.com/product/0636920052999.do">Advanced one</a>. I’ve tried to keep this one mostly assuming you may not have a background in Java.</li> <li><a href="https://www.coursera.org/learn/kotlin-for-java-developers">Kotlin for Java Developers</a> by Sveta. It does assume some background knowledge of Java (if the title weren’t obvious).</li> <li><a href="https://www.pluralsight.com/courses/kotlin-getting-started">Kevin Jone’s course on Pluralsight</a></li> </ul> <p><br /> I also strongly recommend the book <a href="https://www.manning.com/books/kotlin-in-action">Kotlin in Action</a>, once again by Sveta and Dmitry Jemerov. Gives you a lot of insight and explanations of the why and how of things in Kotlin. <br /></p> <p>Hopefully some of the above can get you started, and then from there you can dive deeper in to the different areas, be it mobile, server-side, native, etc. For more links and information check-out the <a href="https://kotlinlang.org/docs/reference/">Learn section on the website</a> as well as the <a href="https://kotlinlang.org/docs/tutorials/">tutorials</a> and of course <a href="https://play.kotlinlang.org">Play</a>.</p> <p><br /> Have fun!</p> <p><a href="https://hadihariri.com/2019/08/16/getting-started-with-kotlin-for-net-developers/">Getting Started with Kotlin for .NET Developers</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on August 16, 2019.</p> <![CDATA[Slack and the false sense of urgency]]> https://hadihariri.com/2018/12/17/slack-and-the-false-sense-of-urgency 2018-12-17T00:00:00+01:00 2018-12-17T00:00:00+01:00 Hadi Hariri https://hadihariri.com [email protected] <p><br /> Slack brought us the promise of reducing emails and having all the knowledge of your company in one place, searchable. While I still feel it’s completely failed to deliver on the latter, on the former it most definitely has delivered. Internal emails at JetBrains have been significantly reduced. At least in my case. But I personally feel that it’s come at a cost; that of productivity.</p> <p><br /> As a remote person, I very much advocated and encouraged the use of Slack at JetBrains, and I believe that it has greatly benefited our company. In fact, most of our team is remote and we have a channel on Slack which is esssentially the same as a watercooler; giving us a sense of working together and constantly being in touch. Much the same way, it has contributed positively to non-remote workers too.</p> <p><br /> But Slack has also given us the feeling that we can reach out to anyone at any time for anything. The consequence of this however is that frequent interruptions can often lead to context switches which in turn, much like with threads, can impact performance.</p> <p><br /> Now of course, many may say - don’t blame the tool but how you use it. And that’s OK. In fact many times I’ve used the same argument, and this post isn’t about me “rage-quiting Slack”. Instead it’s about changing the way I’m now using Slack.</p> <h2 id="a-simple-rule">A simple rule</h2> <p>This change is reduced to a very simple rule:</p> <p><br /> <br /> <strong>Unless it is urgent, I do not ping a person or a group of people (understanding by this a group DM or small private channel) directly. Instead use email or issue tracker</strong> <br /> <br /> I’ve moved(ing) back to making use of the right tool at the right moment, as opposed to believing Slack should be used for everything, i.e.:</p> <ul> <li>Email or issue tracker for non-urgent discussions or issues that need attention. At JetBrains we make heavy use of YouTrack, not just as a software project management tool, but for many things including organising shows, trips, payments, etc. We also at times use it to have discussions and make decisions. The benefits over email are that people can leave and join at any time, and everything is documented</li> <li>Email when pinging someone to see if and when they’re available for a chat (when not urgent).</li> <li>Issue tracker for logging bugs as opposed to some random code snippet or unexpected behaviour, expecting everyone to drop something and attend to my problem.</li> </ul> <p>About the only time I will post a question to a channel is -</p> <ul> <li>It’s something urgent</li> <li>I have no idea who could help me with the question at hand</li> </ul> <p><br /> Now while some of you may suggest to just shut down Slack and open it once in a while, the point here is about being available for when it is important and benefing from the many good things that Slack does provide, while at the same time not feeling completely overwhelemed by the many notifications.</p> <p><br /> Finally, I think it’s important to not confuse being open and willing to help with constantly being available on Slack, responding to any notification instantly. We can all still be open and helpful to others. It’s about appreciating that at times one tool may be more appropriate than another when asking for something.</p> <p><a href="https://hadihariri.com/2018/12/17/slack-and-the-false-sense-of-urgency/">Slack and the false sense of urgency</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on December 17, 2018.</p> <![CDATA[Public Speaking - Should I speak?]]> https://hadihariri.com/2018/09/04/public-speaking-should-i-speak 2018-09-04T00:00:00+02:00 2018-09-04T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>This is part 7 of a multi-post series on public speaking</p> <ul> <li><a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with nerves</a></li> <li><a href="/2018/08/19/public-speaking-talk-structure">Talk Structure</a></li> <li><a href="/2018/08/21/public-speaking-slides">Slides</a></li> <li><a href="/2018/08/23/public-speaking-timing">Timing</a></li> <li><a href="/2018/08/24/public-speaking-questions">Questions</a></li> <li><a href="/2018/08/26/public-speaking-speaking">Speaking</a></li> <li><a href="/2018/09/04/public-speaking-should-i-speak">Should I speak?</a></li> </ul> <p>One question people often ask themselves is whether they should actually give a talk and if so, on what. I’ll address these topics as a series of FAQs in this post.</p> <h4 id="should-i-give-a-talk">Should I give a talk?</h4> <p>If it’s part of your job, yes. If it’s not, only if you enjoy it. However, given you really don’t know whether you enjoy something until you’ve experienced it a few times, then yes. Give a talk.</p> <h4 id="what-if-im-nervous">What if I’m nervous?</h4> <p>It’s OK. We’re all nervous. See <a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with nerves</a></p> <h4 id="what-if-i-dont-enjoy-it">What if I don’t enjoy it?</h4> <p>Then stop. Don’t even need a FAQ entry, right? Amusing however the number of times I encounter people that aren’t even forced to give talks as part of their job, and yet despite not enjoying it, they continue to do so.</p> <h4 id="where-should-i-start">Where should I start?</h4> <p>Generally I’d recommend starting with smaller crowds, be these inside your own company, a user group, etc. My first public talk wasn’t however at a small event, but a proper conference. Lesson learned.</p> <h4 id="what-should-i-talk-about">What should I talk about?</h4> <p>Whatever you feel strongly about. Whether it’s something you’ve learned and want to share with others, or a topic you’re deeply passionate about. I think one of the most important things is to be passionate about a topic. That really does impact a talk.</p> <h4 id="what-should-i-not-talk-about">What should I not talk about?</h4> <p>Anything that you’re not passionate about…obviously. Jokes aside, this also is something I’ve made the mistake of myself and seen others make. Don’t pick a topic just because you want to get to speak at a conference on it (whatever your reasons may be). If the topic is not of interest to you, it again shows in the talk.</p> <h4 id="what-if-im-not-an-expert">What if I’m not an expert?</h4> <p>It’s absolutely fine. You don’t need to be an expert to give a talk on a topic. Just make sure you set expectations. If you’re a beginner, say you are. In the other series of posts I touch on this topic a few times.</p> <h4 id="what-if-others-more-experienced-are-talking-about-this-same-topic">What if others more experienced are talking about this same topic?</h4> <p>That’s like saying “I’m not going to write a book because there’s already a book on this topic”. OK, maybe not entirely the case, because writing a book is big investment you don’t take lightly. But the point is that every talk, much like every article, every blog post, has more value than just the topic it touches on. It should bring insight and personal experience. And that is unique to each of us.</p> <h4 id="what-are-the-key-things-i-should-make-sure-my-talk-has">What are the key things I should make sure my talk has?</h4> <p>Generally I’d say a talk should have the following</p> <p><br /> <strong>Provide value</strong>. You have an audience that is dedicating their time to come and see you give a talk. Make sure they walk away with something, beyond you and your ego.</p> <p><br /> <strong>Be inspirational</strong>. A talk should be a catalyst for people to want to learn more. It should pique their interest to want to dive deeper into a topic.</p> <p><br /> <strong>Be engaging</strong>. Nobody likes a boring talk. The most interesting topic in the world can be projected in the worse way if you’re boring as a speaker. The reverse however usually doesn’t hold - even a boring topic can be made interesting by a good speaker. Make sure your talk is engaging.</p> <p><strong>Be thought-provoking</strong>. There’s nothing better than a thought-provoking talk, something that challenges our beliefs and understandings. A talk in which everything the speaker says we agree with and nod, well while it will reaffirm our knowledge, it doesn’t really challenge us mentally.</p> <p><br /> I’d say these are the basic four ingredients. Depending on the type of talk, you maybe want to vary the dosage of each one.</p> <h4 id="whats-more-important-contents-or-speaker">What’s more important? Contents or Speaker?</h4> <p>Both are just as important. A good topic and great contents with a bad speaker will provide a bad overall experience. A good speaker with a very bad topic or no contents (note - different from boring content), will also provide a bad experience.</p> <p><br />And note the key word there - <em>experience</em>. Kathy Sierra summarised very well when she talks about what the most important aspect a talk should provide:</p> <p><br /></p> <blockquote> <blockquote> <p><em>“It’s about the experience</em>” <br /></p> </blockquote> </blockquote> <p>Until next time.</p> <p><a href="https://hadihariri.com/2018/09/04/public-speaking-should-i-speak/">Public Speaking - Should I speak?</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on September 04, 2018.</p> <![CDATA[Learning to play the guitar]]> https://hadihariri.com/2018/09/02/learning-to-play-the-guitar 2018-09-02T00:00:00+02:00 2018-09-02T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>I’ve always wanted to play the electric guitar and despite an attempt at doing so over 25 years ago, I gave up. Partially cause I had no sense of time-management (as if I do now), partially cause I always felt that being left-handed and playing a right-handed instrument would always hinder me. And yes, I tried the Jimi Hendrix approach, ending up wrecking my guitar.</p> <p><br /> This year I decided to try again, but properly - buying a left-handed guitar. While I haven’t been playing for a long time and I’m still below novice, I’ve tried a few different techniques, some have worked, others haven’t. Below is a list of the services/sites I’ve used and my evaluation of them.</p> <h3 id="fender-play">Fender Play</h3> <p><img src="https://hadihariri.com/images/guitar-6.png" alt="Fender" /> <br /> <br /></p> <p>Having purchased a Fender Squire, the first thing I did was follow the marketing material that came with it and signed up to <a href="https://www.fender.com/play">Fender Play</a>. The trial seemed OK but I was so overly excited that I decided to sign up for a whole year. A month later I abandoned.</p> <h4 id="the-bad">The Bad</h4> <p><strong>Incomplete</strong>. I don’t feel it’s complete. While it has 5 levels, I think it seriously lacks contents.</p> <p><br /></p> <p><strong>No learning path</strong>. The learning path isn’t really a learning path. While it has support for progress of what you’ve done, etc. I really feel it lacks guidance and proper steps.</p> <p><br /></p> <p><strong>No exercises</strong>. No real exercises that you’re <em>tested</em> against. I’ll come back this later.</p> <p><br /></p> <p><strong>Various instructors</strong>. While this has positives, it also feels like it contributes to a lack of continuity.</p> <p><br />Unfortunately I’ve signed up for a year, and not much I can do about it, but despite having paid over $100 for this, I just don’t use it and have written it off as a loss.</p> <p><br /> <em>Verdict</em>. Not happy and wouldn’t recommend it. Having said that, I’ve not gone back to the site for some time so it might have changed a bit for the better.</p> <h3 id="yousician">Yousician</h3> <p><img src="https://hadihariri.com/images/guitar-7.png" alt="Yousician" /> <br /> <br /></p> <p>After a hiatus of a few months, partially influenced by my bad experience with Fender Play, I tweeted about my disappointment, and a few people responded recommending I try <a href="https://yousician.com">Yousician</a>.</p> <p><br />Best way to describe Yousician is like Guitar Hero but in real life. I immediately got hooked. But this time I didn’t make the same mistake as Fender Play. I did the entire trial period (unfortunately only 7 days) before signing up for a year (I know…).</p> <p><br />Different to my last mistake however, I do not regret it. Yousician is excellent and I’m still very much happy with it. A few great things it has:</p> <h4 id="the-good">The good</h4> <p><strong>It’s listening</strong>. This is the best feature! It actually listens to you play and tells you if you’re getting the right notes or not. It’s supported on macOS, Android and iPhone, and you can use either a microphone or a device such as the <a href="https://www.amazon.de/IK-Multimedia-P953-Gitarre-Interface/dp/B00T631UTC/ref=sr_1_3/257-2314689-6609221?ie=UTF8&amp;qid=1535885596&amp;sr=8-3&amp;keywords=irig+2">iRig2</a>. The latter is what I use. Connected to an external speaker along with Garage Band, it not only allows Yousician to work, but also provides me an amplifier (well the app does have a built-in amp, I’ve not had good results with it, so I stick to the aforementioned setup).</p> <p><br /></p> <p><strong>Learning paths</strong>. It has three learning paths:</p> <p><br /></p> <ul> <li>Lead. For building up dexterity in your fingers when playing those solos.</li> <li>Rhythm. For learning chords, power chords, etc.</li> <li>Theory. Some basic music theory</li> </ul> <p><br /> <strong>Challenges</strong>. It poses new challenges for you and entices you to get to the next level on each path. There are around 16 levels in total and once you reach the same level on each path, you go to the next. Unfortunately though, theory stops at level 6.</p> <p><br /> <strong>Free play</strong>. It has a bunch of different songs, including classical, popular, blues and folk that you can play along too. The premium subscription (and I’ll get to this again next) has some additional famous songs. And apparently they’re adding more every day.</p> <p><br /> <strong>Gamification</strong>. It’s gamified. I’m not a big fan of this, but if you like it, then great for you. It also allows you to connect with friends, share progress, etc.</p> <p><br /> <strong>Different exercises.</strong>. It has a variety of different exercises that help you memorise chord, scales, sliding, hammering, pull-ups, etc. Each dedicated to a single specific task and repetitiveness helps you improve these skills.</p> <p><br /> <strong>Practice and Perform</strong>. For every exercise, it allows you to practice and gradually increase the speed. Only when you’re ready you can perform and see if you pass. The increase of speed I’ve found extremely useful.</p> <h4 id="the-bad-1">The bad</h4> <p><strong>I can’t play a thing</strong>. This is a sentiment that I’ve been feeling for some time now and shared by a few other people that are using it. While using Yousician, you feel like you’re drastically advancing and getting strength in fingers and speed, without it it feels like I have no idea on how to play the guitar (apart from knowing the chords, some scales and power chords, etc.). In other words, put me in front of Yousician and I can play pretty decently. Take it away and I can’t even play Happy Birthday (OK that one I can actually).</p> <p><br /> <strong>Fret positions, not notes</strong>. Your typical interaction with Yousician looks like this:</p> <p><br /> <img src="https://hadihariri.com/images/guitar-1.png" alt="Fret positions" /></p> <p><br /></p> <p>and when you first start, this is how to play. The numbers indicate the fret (0 being open string) and the colour, the finger to use. It’s great. It really helps you build up speed and but it’s also an issue (which contributes to the one above). You don’t really understand what note you’re playing.</p> <p><br /> Now, of course, Yousician allows you to use a different style such as combining note with number, or even use music notation</p> <p><br /> <img src="https://hadihariri.com/images/guitar-2.png" alt="Note and number" /> <br /></p> <p><br /> <img src="https://hadihariri.com/images/guitar-4.png" alt="Music notation" /> <br /> <br /> or any combination you can think of…</p> <p><br /> <img src="https://hadihariri.com/images/guitar-3.png" alt="Combinations" /> <br /> <br /> but the problem is that you start with the first one, find it good, start to advance, and then before you know it, you’re at level 5 and don’t really know what note is on what fret. And while it’s very easy to calculate, you’ve not memorised it.</p> <p><br />What I’m now doing is trying to only use notes, no numbers, but it’s not easy and I’ve had to drop down several levels to be able to play fluidly. So take my advice, switch early to notes.</p> <p><br /> <strong>User contributed songs are no more</strong>. One cool thing about it was the ability to create your own songs and have others contribute songs. People would upload for instance a Pink Floyd song which you could use to learn. Unfortunately they got rid of all of this, promising something better. That better thing is a what I mentioned above - a bunch of famous songs that they’re gradually building up. However, this is not available in all countries, and also requires a Premium subscription (i.e. goes from 9.99 euros a month to 14.99 a month), a subscription which previously was about having multiple instruments. Something tells me that they realised the whole business model of playing multiple wasn’t really working out. It’s a shame to be honest.</p> <p><br /> <strong>Lack of theory</strong>. The theory path really lacks contents. It shows you the very basic but stops short of explaining much around music theory.</p> <p><br /> <em>Verdict</em>. I’m happy with Yousician and do not regret purchasing a subscription. Most likely I’ll renew next year, despite its issues. However, I don’t think it’s enough on its own, which brings me to the next service…</p> <h3 id="justin-guitar">Justin Guitar</h3> <p><img src="https://hadihariri.com/images/guitar-5.png" alt="Justin" /> <br /> <br /></p> <p>At the same time that they recommended to me Yousician, a few people talked about <a href="https://justinguitar.com">Justin Guitar</a>.</p> <h4 id="the-bad-2">The bad</h4> <p>I’m going to start with the bad first because it’s actually not entirely bad and there’s a way to solve it when we cover the good.</p> <p><br /> <strong>No forcible progress</strong>. Different to Yousician, Justin Guitar is a bunch of content on a site and there’s nothing stopping you from jumping around. There’s also nothing from making you finish a series of exercises before moving onto something else, which I find problematic in learning.</p> <h4 id="the-good-1">The good</h4> <p><strong>It’s free</strong>. Nearly all the contents is free, including videos, exercise outlines, written explanations, etc. You couldn’t ask for more. Justin’s site uses a donation model and he does sell a bunch of different things which I’ll come to in a moment.</p> <p><br /> <strong>Single and awesome teacher</strong>. He explains things slowly and clearly and really encourages you to learn and not to feel overwhelmed. Something very important and also not easy to transmit via a video. He does a great job at this and kudos to him for it.</p> <p><br /> <strong>Rich and well structured contents</strong>. While similar to Fender Play, in that it’s a web site with contents that you can randomly move around, there are some key differences:</p> <p><br /></p> <ul> <li>It feels way more complete and thorough.</li> <li>If you create an account with the site, you can mark your progress through the course.</li> </ul> <p><br /></p> <p><strong>Justin’s song books</strong>. While most of the contents is free, including the songs that Justin shows you how to play, the actual songbook with the chord progressions is not. However, they’re not only worth every penny, but they also help support his work, so I thoroughly encourage you to buy them as you progress (I’ve currently purchased the <a href="https://www.thejustinguitarstore.com/products/justinguitar-beginners-songbook-volume-1">Beginner song book</a>).</p> <p><br /> <strong>The app</strong>. Justin also has a <a href="https://www.justinguitar.com/apps">few apps</a>. I recently purchased the <a href="https://play.google.com/store/apps/details?id=net.musopia.fourchordsjustin">Justin Guitar Beginner Course</a>. It’s around 65 Euros a year but worth every penny. It helps with the one major issue I have which I pointed out when covering the “The Bad” - forces me through a series of steps. The app provides a bunch of exercises you need to complete to move on to the next step. In addition it has all the songs from the beginner course with step by step notes so that you can play along. They’re not the actual song itself but simplified versions of it. Overall it’s brilliant. About the only thing missing (apart from some usability aspects), is for it to listen to you play like Yousician does.</p> <p><br /> <strong>The theory</strong>. Much like the book and the app, Justin also offers a bunch of contents on music theory, but under a paid model. I started reading this and as expected, great explanations, however, for now I’m holding off subscribing because I don’t want to feel overwhelmed with too much at once.</p> <p><br /> <em>Verdict</em>. Most definitely recommend. However I also encourage you to buy the app, songbook and even theory. Not only do they provide a lot of value, it helps support Justin’s efforts.</p> <p><br /> <strong>Update Tuesday 2nd February 2021</strong> Ben from Strummingly reached out to me recently about the site he’d put together, which has quite a good number of articles about <a href="https://strummingly.com/best-free-guitar-lessons/">guitar lessons</a>, as well as other resources. Worth checking out.</p> <p><br /> <strong>Update Thursday 29th July 2021</strong> Bella from Musicaroo reached out to me regarding some content they have on <a href="https://musicaroo.com/learning-how-to-play-the-guitar/">their site</a>. Having reviewed it, it does contain some good information, and thus worth linking to.</p> <h3 id="summary">Summary</h3> <p>I’m far from even considering myself a beginner but I have found a few important things that are helping me, independently of the service/app you may end up using.</p> <h4 id="force-practice-and-progress">Force practice and progress</h4> <p>I’ve tried many times to set myself a schedule of different things I want to practice on paper and then do them. But it just doesn’t work. I keep getting bored and skipping things or just end up playing a bit and putting the guitar down in frustration. Yousician and Justin’s app have forced me into following specific exercises and it really helps me tremendously. If you have the discipline that you don’t need this, then that’s great. When it comes to guitar, I don’t…I keep falling into the trap of wanting to play some solo from Pink Floyd…</p> <h4 id="practice-daily">Practice daily</h4> <p>Even if it’s just 30 minutes a day, make sure you practice. I travel quite a bit and being away sometimes for a week or more really impacts my progress. I recently, on the advice of <a href="https://twitter.com/robashton?lang=en">Rob Ashton</a>, purchased a <a href="https://travelerguitar.com/ultra-light-electric-black-lefty/">travel guitar</a> which I take with me on trips that are longer than a couple of days.</p> <h4 id="dont-fall-into-trap-of-overwhelming-yourself">Don’t fall into trap of overwhelming yourself</h4> <p>At some point I decided that I want to understand everything around music theory and started to look into it in more details. It’s definitely fascinating but it’s also not easy, and at times can actually confuse you when learning how to play something. While I’m still very much interested in why some things are the way they are (and understanding how scales are formed, etc.), I’m trying to balance my theory with playing.</p> <h4 id="more-than-one-method">More than one method</h4> <p>I’ve reviewed a few different services and while initially I had planned to just stick to one (again to not feel overwhelmed), much like balancing theory, I’m finding that using Yousician and Justin Guitar (especially now with the app) is working out well for me. As such, I don’t think you necessarily have to just stick to one service. But as with many things, this is a personal choice and do what works best for you.</p> <h4 id="get-a-helping-hand">Get a helping hand</h4> <p>Find someone that can help you with questions you may have (especially around theory). I’ve been fortunate enough that <a href="https://twitter.com/robashton">Rob Ashton</a> who himself only started playing a few years ago, is always there to help with questions I have. And while sometimes things he answers go over my head, he really does offer me reassurance and help at times.</p> <h4 id="record-yourself">Record yourself</h4> <p>I admit I should be more active in this but recording yourself can also help show how you’re progressing as well as seeing the mistakes you’re making.</p> <p><br /> Finally, and more as a reminder and encouragement to myself, when you feel frustrated and you think you’re not making progress, don’t give up. Just keep on playing!</p> <p><a href="https://hadihariri.com/2018/09/02/learning-to-play-the-guitar/">Learning to play the guitar</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on September 02, 2018.</p> <![CDATA[Public Speaking - Speaking]]> https://hadihariri.com/2018/08/26/public-speaking-speaking 2018-08-26T00:00:00+02:00 2018-08-26T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>This is part 6 of a multi-post series on public speaking</p> <ul> <li><a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with nerves</a></li> <li><a href="/2018/08/19/public-speaking-talk-structure">Talk Structure</a></li> <li><a href="/2018/08/21/public-speaking-slides">Slides</a></li> <li><a href="/2018/08/23/public-speaking-timing">Timing</a></li> <li><a href="/2018/08/24/public-speaking-questions">Questions</a></li> <li><a href="/2018/08/26/public-speaking-speaking">Speaking</a></li> <li><a href="/2018/09/04/public-speaking-should-i-speak">Should I speak?</a></li> </ul> <p>One of the important aspects of public speaking is what we actually say outside of the contents of the topic we’re speaking on. In this blog post I’ll cover this.</p> <h2 id="words-to-avoid">Words to avoid</h2> <h3 id="fillers-begone">Fillers begone</h3> <p>Em, Hmm, Eh. Mm, Um, Er…</p> <p><br /> Those words we use when we don’t know what to say. Try very hard to cut them out. They are annoying, especially to those that pay attention (like myself). The best alternative to these fillers is to know what you’re going to say (and practice). However, if you find yourself struggling, replace them with a pause. Silence.</p> <p><br />As an anecdote, it’s ironic that the recent demo by <a href="https://www.youtube.com/watch?v=SuqOomotx7M">Google showing how their AI was having a casual conversation</a>, it felt like the processing time (i.e. status progress) was using fillers to replace silence. It might be OK for AI (despite the whole thing being very morally questionable), but it’s not OK for a speaker.</p> <h3 id="repetitive-words">Repetitive words</h3> <p>Beyond fillers, it’s also important to not fall into the trap of constantly repeating specific words. I’m very much guilty of this myself, right, and when listening to some of my talks, right, I often hear myself repeating the same word over and over and over again, actually!</p> <p><br />Some common ones:</p> <ul> <li>Actually</li> <li>In essence</li> <li>For example</li> <li>For instance</li> <li>You know</li> <li>OK?</li> <li>Right?</li> </ul> <p>The only way to know this is happening, is to listen to your own talks, as painful and excruciating as it may be.</p> <h2 id="apologies">Apologies</h2> <p>There may be times you feel the urge to apologise to the audience. For instance</p> <ul> <li>You’ve not slept due to jet lag or a late night out</li> <li>You’ve not had time to prepare everything</li> <li>You’re going to skip a few slides because there’s no time</li> <li>This is the first time you’re giving the talk and you’re not sure how well it will go</li> <li>Your talk was brought forward and you didn’t have time to finish the demos</li> </ul> <p>Of all those, the only time it’s valid to apologise is in none of the cases. First off, let’s be clear - the majority, actually scratch that, all of those are your own fault. Apologising to the audience is you asking for redemption. You’re jet lagged? Not my problem. Should have come a week earlier and get sleep. You couldn’t? Then don’t travel. You’ve not had time to prepare anything? Shame on you and your lack of professionalism. They moved your talk? Aawww, poor thing. Should have not left it to the last minute.</p> <p><br />Hopefully you get the general idea. And I’m telling you this as someone that was guilty of it, and I’m also telling you it from someone that is in the audience listening to how lame these excuses sound.</p> <h3 id="a-subtle-error">A subtle error</h3> <p>If you made a mistake on a slide, or it’s out of order, unless it’s showing some fundamentally wrong information, you don’t have to specifically point it out. Chances are nobody really noticed the mistake apart from you and just saying “Oops, I made a mistake here” provides very little value. Again, as I mentioned, as long as the mistake is not misleading people or giving incorrect information.</p> <h3 id="apologies-for-being-nervous">Apologies for being nervous</h3> <p>Once again, I wouldn’t apologise for this, but I covered this in more detail in <a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with Nerves</a></p> <h3 id="never-apologise">Never apologise?</h3> <p>As this point you may be thinking that an apology is never needed. Not the case. Obviously when you have a demo go drastically wrong, or you’ve given incorrect information and been pointed out by the audience or noticed it yourself, an apology is in order. I’d also say you should apologise if you’ve been rude, but then I’d question why the hell have you been rude to begin with, which takes me to the next section.</p> <h2 id="behaviour">Behaviour</h2> <p>Certain things that are important about how you behave during a talk.</p> <h3 id="rudeness">Rudeness</h3> <p>I’m not going to define what being rude is, I’m sure we’re all grown up enough to know. However let me point out a few things:</p> <h4 id="profanity">Profanity</h4> <p>I’m generally against strong profanity in talks. I’ve never said the word “fuck” in a talk (to my recollection). I have had it on a slide (“Fuck you”) but never repeated it. Other words such as “shit”, “bullshit” etc. I have used at times. But it’s very important to know the setting, the context, the audience. How you speak in front of 20 developers and those you have a strong rapport with may not be the same as a customer seminar where you know very few people and they don’t know you.</p> <h4 id="targeted-jokes">Targeted jokes</h4> <p>I’m often known for making fun of JavaScript and its community. Some may consider this offensive or rude. I’m also equally known for making fun of myself, other technologies and languages and our industry as a whole.</p> <p><br />I do not believe JavaScript, Java or .NET developers are persecuted, nor are they discriminated against and it is wrong and disgraceful to equate them to minorities or groups that are. The lack of satire and the ability to laugh at oneself and our work is not something I believe will benefit humanity if prohibited. And while I am not in favour of intentionally offending anyone, I do accept that it’s impossible to go through life without ever offending anyone.</p> <p><br />Each of us should know where our moral and ethical boundaries are and be comfortable with ourselves. As Gandhi said</p> <p><br /><em>Happiness is when what you think, what you say, and what you do are in harmony</em></p> <h3 id="discrimination">Discrimination</h3> <p>Do not make remarks, say things or make jokes that are discriminatory. It’s just plain wrong. In every setting, not only on stage. Much the same way, do not use slides that imply any of this. I’m also very much against sexual comments and imagery. Fortunately most Code of Conducts of conferences already point many of these things out.</p> <h3 id="be-inclusive">Be inclusive</h3> <p>Not being discriminatory is critical. Being inclusive is just as much.</p> <p><br />Being inclusive isn’t always as easy as one may think and often speakers are just not generally aware of the mistakes they make. I’m not here to judge anyone, but I do want to point out some things you should avoid, and some of them are not easy habits to break, but possible with effort. And the effort is worth it.</p> <h4 id="guys-and-similar-words"><strong>Guys</strong> and similar words</h4> <p>Stop using “guys” in a talk. Just replace it with “folks” or any other valid option that is inclusive of everyone. I’m not going to debate why guys is wrong. I believe it is and <a href="https://twitter.com/mariaKhalusova/status/996709342354333696">there are tons of examples</a> on the Internet as to why.</p> <p><br />Much the same with other words that are gender specific or other words that may be exclusionary (race, religion, gender, sexual orientation) to those in the audience.</p> <h4 id="asking-questions-that-are-inclusive">Asking questions that are inclusive</h4> <p>Generally avoid questions that assume biases, for instance, a question that assumes everyone in the audience identifies as male. If the question however is relevant, then make sure you ask in an inclusive way.</p> <h2 id="be-yourself">Be yourself</h2> <p>While this generally applies to all aspects of speaking, I think it’s very important to highlight in this post as this one is very much about what you say; be yourself. Don’t try and be another speaker. Don’t try and imitate your idols. Learn from them, but don’t be them. If you’re funny, be funny. If you’re not, don’t try excessively hard to be. You’re not a comedian, you’re a speaker trying to transmit a message to people.</p> <p><br />And just like life in general, don’t be one persona on stage and another off. Be the true person you are and aspire to be.</p> <p><br /> Until next time.</p> <p><a href="https://hadihariri.com/2018/08/26/public-speaking-speaking/">Public Speaking - Speaking</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on August 26, 2018.</p> <![CDATA[Public Speaking - Questions]]> https://hadihariri.com/2018/08/24/public-speaking-questions 2018-08-24T00:00:00+02:00 2018-08-24T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>This is part 5 of a multi-post series on public speaking</p> <ul> <li><a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with nerves</a></li> <li><a href="/2018/08/19/public-speaking-talk-structure">Talk Structure</a></li> <li><a href="/2018/08/21/public-speaking-slides">Slides</a></li> <li><a href="/2018/08/23/public-speaking-timing">Timing</a></li> <li><a href="/2018/08/24/public-speaking-questions">Questions</a></li> <li><a href="/2018/08/26/public-speaking-speaking">Speaking</a></li> <li><a href="/2018/09/04/public-speaking-should-i-speak">Should I speak?</a></li> </ul> <p>This post is about dealing with questions, and to be honest there isn’t much to share in this area. Nonetheless, I’ll cover some of the most common sense aspects of it.</p> <h3 id="questions">Questions?</h3> <p>The first question of course should be…should I allow questions?</p> <p><br />My rule of thumb is yes except if keynotes. And even with keynotes there are exceptions to the rule. If it’s a non-technical keynote, then very rarely is there place for questions and most topics I talk about are probably better discussed one on one. As such, a better place to address these types of enquiries and comments is after the talk. If it’s a technical keynote, and if there is time after the talk then sure, a few questions are fine. However, never during the talk itself.</p> <p><br />If it’s not a keynote, then I’m good with questions and I’m fine with people to ask it during the talk as opposed to piling it all up at the end. Ironically most conference organisers keep telling speakers that a session should be X minutes with Y minutes Q&amp;A to end the session. I disagree for two reasons:</p> <ol> <li>If someone has a question which is not addressed, their mind may start to wander and as a consequence, they can get lost. This is even more so when it’s a technical talk and knowledge is built on as the session progresses.</li> <li>If someone has a question, you’re pretty certain that at least someone else has the same question. I can’t prove it scientifically but it’s happened to me so often that there’s a high probability it’s the case.</li> </ol> <p><br /> The flip side of it is that often someone’s question will be answered by yourself during the talk at some later point, and you’d save everyone the trouble by avoiding interruptions. However, it’s up to you to decide whether saying “we’ll get to that” is worth the balance of not allowing questions during your talk.</p> <h3 id="repeat-the-question">Repeat the question</h3> <p>Always repeat the question. It serves two main purposes:</p> <ol> <li>You understood correctly what you were being asked.</li> <li>If your talk is being recorded or live-streamed, those listening can know what was asked. Obvious isn’t it? Yet so often people forget to do this. Including myself.</li> </ol> <h3 id="i-dont-know">I don’t know</h3> <p>Be honest. If you don’t know the answer, just say you don’t. Don’t try and invent something to look smart. If you make up an answer you’re not only misleading people but will also look silly if someone in the room (or those watching the recording) know the correct answer. Early on I was guilty of this. And I profoundly apologise.</p> <p><br />If you do not know the answer, just tell them that you’ll follow-up later or even give the opportunity for someone else in the room to answer if they know. Remember, giving talks and teaching in general is one of the best ways to learn yourself.</p> <p><br />As a reminder - when we covered dealing with nerves in the first part of this series, I said it’s very important to set expectations. If you’re a beginner on a topic, set the expectations. This comes in handy when answering questions too. Nobody will expect you to know everything.</p> <p><br />If none of those approaches work for you, then you can do what I recently coined “Trump a question”.</p> <p><br /></p> <blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">&quot;Trumping a question&quot; - when you&#39;re not sure of the question, let alone the answer, you respond with how awesome you are as a person and how everyone likes you</p>&mdash; Hadi Hariri (@hhariri) <a href="https://twitter.com/hhariri/status/1017671493147353088?ref_src=twsrc%5Etfw">July 13, 2018</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p><br />Yes. That’s a joke.</p> <h3 id="take-things-offline">Take things offline</h3> <p>If a question is derailing off-topic or the answer is way too long to respond then and there, give a brief answer and suggest to take it offline.</p> <h3 id="ignore-the-trolls">Ignore the trolls</h3> <p>Much like you should ignore trolls online, ignore them offline too. Unfortunately though that’s easier said than done. The only thing that will help you in dealing with trolls or people that aren’t necessarily trolls but selfish in terms of wanting to be center of attention or you only focusing on their questions, is experience.</p> <p><br />Having said that, don’t be rude and try and tell them to take things offline. If they’re being insulting or aggressive, then by all means stop the session and ask for one of the organisers to intervene. But please do not engage in a back-and-forth to see who wins. It’s not something the audience enjoys watching.</p> <p><br /></p> <p>Until next time.</p> <p><a href="https://hadihariri.com/2018/08/24/public-speaking-questions/">Public Speaking - Questions</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on August 24, 2018.</p> <![CDATA[Public Speaking - Timing]]> https://hadihariri.com/2018/08/23/public-speaking-timing 2018-08-23T00:00:00+02:00 2018-08-23T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>This is part 4 of a multi-post series on public speaking</p> <ul> <li><a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with nerves</a></li> <li><a href="/2018/08/19/public-speaking-talk-structure">Talk Structure</a></li> <li><a href="/2018/08/21/public-speaking-slides">Slides</a></li> <li><a href="/2018/08/23/public-speaking-timing">Timing</a></li> <li><a href="/2018/08/24/public-speaking-questions">Questions</a></li> <li><a href="/2018/08/26/public-speaking-speaking">Speaking</a></li> <li><a href="/2018/09/04/public-speaking-should-i-speak">Should I speak?</a></li> </ul> <p>A talk that finishes on time ends well. It leaves you with a nice feeling, you’ve nailed it. You’ve finished on time (and on budget)! On the other hand, having a talk end 15 minutes earlier does seem awkward, and trust me I know. It’s happened to me a few times. Your goal should always be to have the talk last pretty much exactly as long as the allocated time. But how to do it?</p> <p><br />There’s really no magic to it beyond practice, practice and more practice. However, given that I’m guilty of not practicing my talks much, over the years I’ve picked up some “tricks” (if you can call them that) you can use to try and adjust things as you go along without it being too obvious, as well as a few things that you should generally avoid. And let’s start with the latter ones</p> <h2 id="things-you-shouldnt-do">Things you shouldn’t do</h2> <h3 id="slides-per-minutes">Slides per minutes</h3> <p>I’ve seen many times people talk about spending 50 seconds on a slide and given 60 slides that makes 3000 seconds, divided by 60, that’s 50 minutes and 10 minutes Q&amp;A and I’m set.</p> <p><br />Here’s the thing, if you can actually time how much you spend on each slide and you have actually managed to master the art of spending the exact same amount of time on each slide, then good for you, go for it. Me? Nah. I don’t buy into that stuff.</p> <p><br />I’ve given talks with 10 slides that have lasted one hour, and I’ve given talks with over 250 slides that have lasted 45 minutes. This whole slides per minute thing is completely overrated. I wish I could even say it provides you a ballpark figure. But it doesn’t, so just don’t waste time over it.</p> <h3 id="skipping-slides">Skipping slides</h3> <p>Nothing looks more unprofessional than a speaker saying</p> <p><br /> <em>“Oh, we don’t have time for this so let’s just skip it”</em></p> <p><br />as they go over a slide.</p> <p>If you don’t have time for a slide, then you should have practiced more and made time. Even if you don’t have time, don’t make it obvious. Try and be very brief on the slide or tell the audience that you’re just highlighting this or that aspect and that it would be it’s own talk. Don’t just completely ignore the contents you’ve put in there.</p> <h4 id="jumping-to-a-slide">Jumping to a slide</h4> <p>Some applications such as PowerPoint, give you the ability to jump to a specific slide by entering the slide number while in presentation mode. For instance, if you’re on slide 30 and you’re really running short on time, you can jump to slide 40 by entering 40 on the keyboard. It might seem great but it also requires a few additional efforts</p> <ul> <li>Memorising slide numbers.</li> <li>Structuring content so that jumps don’t appear incoherent.</li> </ul> <p>Now, think what is less effort and more rewarding - having to do the above so that you can jump around, or just practicing and getting the timing right…</p> <h3 id="too-many-questions">Too many questions</h3> <p>In another post we’ll cover how to deal with long-running questions and trolls, but in terms of timing it’s important to make sure that you do not allow questions to go on for too long (this is if you’re taking questions during the talk), as it can significantly impact your timing. Of course one might not, but if they’re frequent enough, it all adds up.</p> <h2 id="things-you-can-do">Things you can do</h2> <p>Below are a list of things that have helped me deal with timing somewhat.</p> <h3 id="use-presentation-mode">Use Presentation Mode</h3> <p>Presentation Mode, a.k.a. the ability to see the next slide, the number of remaining slides and the time left, is very useful to try and get a better picture of how much contents you have left. There really is no reason why you shouldn’t use it. However, there are some cases when it becomes somewhat more challenging to use, namely:</p> <ul> <li> <p>You’re far away from your monitor and there aren’t any comfort screens. In this case, my only recommendation is to try and stay close to your screen and put it at an angle that doesn’t make it too obvious you’re glancing at it.</p> </li> <li> <p>You’re switching to another tool. When using Presentation Mode, you usually need to configure you laptop to use Dual Monitors, as opposed to Mirrored. This poses a problem if for instance you want to switch to an IDE or Browser window as you’d essentially be operating it on the second screen (i.e. the one that the attendees see). And that is quite challenging. If I have talks where I need to do this, what I try and do is structure the talk so that I minimise switches. For instance, I’d first go through all the slides, leaving the demos to the very end. Right before switching to demos, I’d quickly revert to Mirrored settings and know that if I do have a Summary or Thank You slide, I’m really not going to need the Presentation Mode.</p> </li> </ul> <h3 id="use-a-remote-control">Use a remote control</h3> <p>A remote control is a must. It’s very unprofessional to walk back and forth to the laptop and press space, or for that matter just stay at the laptop and press space. In addition, remotes provide some interesting features that help with timing.</p> <p><br />One of the best remote controls I’ve owned is the <a href="https://www.amazon.com/Logitech-Professional-Presenter-Presentation-Wireless/dp/B002GHBUTU/ref=sr_1_4?s=electronics&amp;ie=UTF8&amp;qid=1535007106&amp;sr=1-4&amp;keywords=logitech+presenter+remote">Logitech R800</a>. It’s best feature is a small screen that shows the remaining time. It’s really useful to be able to glance in a subtle way at your remote and know exactly how many minutes you have left.</p> <p><br />I’ve recently switched though to the <a href="https://www.amazon.com/Logitech-Spotlight-Presentation-Remote-Bluetooth/dp/B01N9X3DBQ/ref=sr_1_1_sspa?s=electronics&amp;ie=UTF8&amp;qid=1535008027&amp;sr=1-1-spons&amp;keywords=logitech+spotlight&amp;psc=1&amp;smid=A1CIO1FZK7A4ZD">Logitech Spotlight</a> which is awesome, especially the spotlight feature, but I do miss the screen. It does though provide a software counter, but to be honest, I usually now just use the Presentation Mode time features.</p> <p><br />However, both remotes also have a setting which make the presenter vibrate when there are X minutes left. While very useful, you still need to be aware that you have to mentally keep track of the few minutes left.</p> <h3 id="have-a-story-ready">Have a story ready</h3> <p>Stories and anecdotes, even jokes to a certain extent, are very useful to “adjust timing”. If you’re going too fast, you can take a pause and tell a story. If you’re going too slow, you can skip it and nobody will know. Also specific topics that you know can cover in 2 or 5 minutes are useful, because they provide a sliding buffer.</p> <h3 id="know-the-end-is-near">Know the end is near</h3> <p>One thing that really looks weird is you’re giving a talk and then suddenly you encounter the last slide that shows a “Thank you”, your contact details, or what’s worse, your presentation software flips out of presentation mode.</p> <p><br />Know when your talk is about to end. That’s another reason a Summary slide is important, because it allows you to know that it’s the end of the talk and gives you some time to recompose and summarise the things you’ve covered. If you find yourself with a few extra minutes, you can also try and stretch it somewhat on the summary slide.</p> <p><br /> Until next time.</p> <p><a href="https://hadihariri.com/2018/08/23/public-speaking-timing/">Public Speaking - Timing</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on August 23, 2018.</p> <![CDATA[Public Speaking - Slides]]> https://hadihariri.com/2018/08/21/public-speaking-slides 2018-08-21T00:00:00+02:00 2018-08-21T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>This is part 3 of a multi-post series on public speaking</p> <ul> <li><a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with nerves</a></li> <li><a href="/2018/08/19/public-speaking-talk-structure">Talk Structure</a></li> <li><a href="/2018/08/21/public-speaking-slides">Slides</a></li> <li><a href="/2018/08/23/public-speaking-timing">Timing</a></li> <li><a href="/2018/08/24/public-speaking-questions">Questions</a></li> <li><a href="/2018/08/26/public-speaking-speaking">Speaking</a></li> <li><a href="/2018/09/04/public-speaking-should-i-speak">Should I speak?</a></li> </ul> <h2 id="its-not-about-the-slides">It’s not about the slides</h2> <p>First and foremost - a talk isn’t about slides. The slides are there to help. They’re not the centerpiece of your talk. If you’re revolving your entire presentation around how awesome your slides are, then just post them online and save yourself the trouble of giving a talk.</p> <p>Having said that, there are some things that can help and other things you should generally avoid when preparing slides.</p> <h3 id="the-tooling">The tooling</h3> <p>Each of us have our favourite tool for preparing slides. Mine is Keynote. Choose what you’re comfortable with and use it. But please, please, don’t roll your own. The only time it would make sense to roll your own presentation tool is if you’re giving a talk about how to create a presentation tool and instead of the demo you surprise people by saying “Well, I’ve been using it all along”.</p> <p><br />Otherwise, the only good thing about rolling your own is to brush your own ego.</p> <h3 id="text-on-slides">Text on slides</h3> <p>Don’t put too much text on a slide. If you have enough text on a slide that will entice people to read your slide, you’ve lost the audience. They’re now focusing on the text as opposed to you. And by the time they come back to you, you’re ahead so now they’re completely lost.</p> <p><br />So you might ask how much text should I put on a slide? Essentially what you want to avoid is people taking more than a second or two to read what’s on your slide. And when we cover bullet points shortly, this is something important to remember.</p> <h3 id="single-phrases">Single phrases</h3> <p>What I often have on slides is just single sentences of 4-5 words at most, or a single word, highlighting a point I want to make. That word or phrase is also a self-reminder of what it is I want to cover at that point in the talk.</p> <h3 id="bullet-points">Bullet points</h3> <p>I’m sure you’ve all read some variation of “Death by PowerPoint” or “Death by Bullet Points”, with the general notion that you shouldn’t do slides full of bullet points. I tend to agree. However, bullet points are also valuable if used efficiently.</p> <p><br />When I use bullet-points, I try and always make sure that</p> <ul> <li>It’s really needed, i.e. it’s to list a series of items that are related and probably do not deserve their own slide.</li> <li>They are timed to appear as I speak</li> </ul> <p>The second point is important - please avoid dumping all your bullet points on the screen at once. This again leads to people reading your slides and not following you. Have a gradual transition with bullet points and have them appear as you talk about them. One feature I use quite often with bullet points is “Highlight by bullet point” which adds the effect of having bullet points appear as I need them, and dims the ones I’ve covered as I advance</p> <p><br /> <img src="/images/speaking-bulletpoints.png" alt="Bullet points" /> <br /></p> <h3 id="slide-animation">Slide Animation</h3> <p>Keep it to the absolute bare minimum. I usually avoid slide transitions, and in terms of animations, I only use “Disolve” or “Appear”. Please do not go overboard with animations. It’s annoying as hell. If you want that, you might as well use something like Prezi (which is not my cup of tea and makes me really dizzy as a spectator).</p> <h3 id="images-and-animated-gifs">Images and animated GIFS</h3> <p>“An image is worth a thousand words”. Yes. True. Unless every other bloody slide is an image. Because then it’s worth squat!</p> <p><br />The whole point of using an image is to use it to help people identify something with an important point you want to make. If every point you’re making is an image, how do you expect people to remember every single image? Use it as an impact. Don’t flood your presentation with images.</p> <p><br />Regarding animated GIFS, don’t even get me started on that. Sorry, maybe I’m just too old for this, but much like Prezi, it’s not my cup of tea. Or coffee!</p> <p><br />When using images, a few useful resources and tools:</p> <ul> <li><strong><a href="https://search.creativecommons.org">Creative Commons Search</a></strong>. Good resource to find images and the corresponding licenses. Always make sure you give proper attribution to images or other resources you use.</li> <li><strong>Alpha Blend in Keynote</strong>. Feature in Keynote that helps remove background colours of an image.</li> </ul> <h3 id="code-on-slides">Code on Slides</h3> <p>If you’re putting code on slides, make sure you don’t cram everything into a single one. Use syntax highlighting. Most IDE’s, including IntelliJ family, allow you copy/paste code with syntax highlighting directly into Keynote. Also make sure you use a good font size that’s readable from the very back.</p> <p><br />One technique people often use, and <a href="https://twitter.com/JakeWharton">Jake Wharton</a> is great at doing this, is use the “Magic Move” transition in Keynote to provide highlighting on specific areas of code in a slide. Results are fantastic, but every time I’ve tried it….way too much work!</p> <h3 id="slide-templates">Slide Templates</h3> <p>Really up to you what slide template you want to use, but a few things I generally stay away from</p> <ul> <li><strong>Using Conference Templates</strong>. That’s a big no-no. I usually give the same talk more than once. Having to adapt it each time to a different template is time-consuming and really not justified. At most, I’d place a Title slide in front of the talk.</li> <li><strong>Company Branding</strong>. Title slide, logo and/or name. Ending slide logo and/or name. That’s it. Please don’t place your company name on each slide. It’s really cheap.</li> <li><strong>Your name</strong>. First slide and/or last slide with your contact details. That’s it. And remember - no “About me” Slide.</li> <li><strong>Slide Numbers</strong>. No. Just no!</li> <li><strong>Everything else</strong>. Anything else on the template that distracts from the actual content, generally avoid.</li> </ul> <h3 id="presenter-notes">Presenter Notes</h3> <p>I don’t use them. I find that if I have to squat to read the notes or what’s worse, read a script, then</p> <ul> <li>I don’t know my material well enough</li> <li>It looks horrible. Ever notice people constantly looking at comfort screens reading along? It feels too rehearsed and unnatural.</li> </ul> <p>As I mentioned earlier on, often I use a few words on the slide to remind me what I have to speak about. And that’s generally enough without the need for scripting.</p> <h3 id="repeating-slides">Repeating slides</h3> <p>If during your talk you need to refer back to a slide, don’t start navigating back and forth. Repeat that slide in a certain position. It feels much more natural and doesn’t make people dizzy while you’re trying to find exactly where you put it.</p> <p><br />Of course you don’t have to make a verbatim copy of it. You can modify some of the contents to add more context for the position in which it appears again. The main point however is that it’s OK to repeat slides to rehash or refer to content covered already.</p> <h2 id="no-slides">No Slides</h2> <p>Generally you should be prepared to give a talk without slides. It’s not easy but at times it may be necessary. A few months ago in fact this exactly happened to me. I was giving a presentation to a smaller group of people (fortunately it was only around 30), and the electricity went, meaning no projector. I didn’t have any notes on papers, but I essentially ended up giving a talk without really using any slides.</p> <h3 id="live-codingdemos-instead-of-slides">Live coding/demos instead of Slides</h3> <p>If you’re giving a technical talk which may involve code, you could always try and go for using your favourite IDE or Editor and do the entire thing in that. Once again, <a href="https://twitter.com/venkat_s">Venkat</a> is a master at this. And it’s not easy.</p> <p><br />My general recommendation (which unfortunately I don’t follow myself) is to try and avoid live coding unless you really want to or need to; in which case, make sure you practice enough. And if you think a shortcut to this is to copy/paste or have a series of predefined templates you can spit out, then please, avoid it. Nobody enjoys seeing how awesome you are at copying/pasting!</p> <p><br /> One thing we left out is the number of slides you should have per talk, but that is actually related to timing (or not?), which I’ll cover in another post.</p> <p><br /> Until next time.</p> <p><a href="https://hadihariri.com/2018/08/21/public-speaking-slides/">Public Speaking - Slides</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on August 21, 2018.</p> <![CDATA[Public Speaking - Talk Structure]]> https://hadihariri.com/2018/08/19/public-speaking-talk-structure 2018-08-19T00:00:00+02:00 2018-08-19T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>This is part 2 of a multi-post series on public speaking</p> <ul> <li><a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with nerves</a></li> <li><a href="/2018/08/19/public-speaking-talk-structure">Talk Structure</a></li> <li><a href="/2018/08/21/public-speaking-slides">Slides</a></li> <li><a href="/2018/08/23/public-speaking-timing">Timing</a></li> <li><a href="/2018/08/24/public-speaking-questions">Questions</a></li> <li><a href="/2018/08/26/public-speaking-speaking">Speaking</a></li> <li><a href="/2018/09/04/public-speaking-should-i-speak">Should I speak?</a></li> </ul> <p>A talk usually consists of three parts:</p> <ul> <li>The Intro</li> <li>The Contents</li> <li>The Summary</li> </ul> <h2 id="the-intro">The Intro</h2> <p>The intro should give the audience a brief overview of what it is they’re going to be hearing, and more importantly set expectations. If it’s a technical talk, tell them the level of coverage for instance. Use it as a way to make sure everyone has read the abstract (assuming you’ve done a good job writing it) and are on the same page. It’s also a good way for those that are in the wrong talk, to apply the <a href="https://opensource.com/business/10/8/darwin-meets-dilbert-applying-law-two-feet-your-next-meeting">law of two feet</a>.</p> <p><br />It should be short though, not more than a minute.</p> <h3 id="agenda">Agenda</h3> <p>I personally dislike agenda slides. I think they’re boring and useless. People often spend a good two to three minutes going over, point by point everything they’re going to cover in a talk. For what?</p> <p><br />Do you believe members of the audience are going to remember the agenda? You think they’re going to take a picture of it and reproach you later on if you didn’t exactly cover what you mentioned? It’s also rare that anyone would come to a talk just because they want to make sure one or two specific items will be covered in it, which an agenda highlights. If you’re going into that level of detail in your agenda slide, then you’re already spending way too much time on it.</p> <p><br />Th abstract along with an intro should be more than enough to set the tone for the talk.</p> <h3 id="about-me">About me</h3> <p>If there’s something I dislike more than an agenda slide, it’s an “About Me”. If you want my opinion (and given you’re reading this blog I assume you do), drop it. Completely get rid of any slides that are about you. Time and time again I witness talks where the speaker spends a good couple of minutes talking about themselves, their cats, dogs, kids, what they’ve done or haven’t done with their life. And all of this is usually following a disclaimer of “I don’t normally talk about myself”….but here’s 20 minutes into my life that you don’t care about.</p> <p><br /> “But but but I have to establish credentials”…you may say.</p> <p><br />Generally, if someone is coming to your talk, they’ve probably read your bio. And if afterwards they’re really interested, or concerned, about things you’ve said, they’ll look you up.</p> <p><br />In summary, my recommendation regarding “About me” slides, or sections - you don’t need them. If you really feel the urge to talk about yourself before the talk or need to “advertise” your company, just say “My name is Hadi. I work at JetBrains”. Done.</p> <h3 id="does-an-intro-always-apply">Does an intro always apply?</h3> <p>No. Not every talk needs an intro. In fact many talks such as keynotes or “soft-skill talks” in our industry, don’t necessarily need to have an intro and in fact can be awkward. I’ve never really given an intro during a keynote, even if it’s been a technical one (which I’m not really a fan of giving technical keynotes but that’s a completely different discussion). Having said that, if you want to intro your talk as a story, as a reason of why you’re giving the talk, then that can work but it has to be very subtle and blend in to the story narrative. Not stand out like a soar thumb.</p> <h2 id="the-contents">The Contents</h2> <p>The contents of the talk is the core part. It’s essentially why everyone is at the talk. What you can talk about and how you should do it is a topic for a different blog post, but focusing on the structure aspect of the talk, there are a couple of important things to take into account.</p> <h3 id="focused-and-coherent">Focused and coherent</h3> <p>When giving a talk, especially a technical one, sometimes we try and cram too much in. I’m very much guilty of this myself. It’s important to remember that people’s attention span isn’t that big. And in a world where any text longer than a tweet is considered a novel to read on vacation, cramming too much contents into a talk can leave the audience lost and overwhelmed.</p> <p><br />It’s important to keep the talk focused. I know you want to share as much of your knowledge as you can, and I know you’re excited, but cramming too much into an hour or 45 minutes won’t help anyone, apart from your own ego. One of my all-time favourite speakers, <a href="https://twitter.com/venkat_s">Venkat Subramaniam</a> does a very good job of keeping his talks focused.</p> <p><br />Much like keeping focus, it’s also important for your talk to be coherent, and this is much harder when giving non-technical talks. I’ve struggled with this quite a bit with some of my non-technical talks, or as some call them, <a href="https://vimeo.com/181766947">rants</a>. Much like trying to keep the focus, you need to keep the talk coherent. If you’re talking about all sorts of things and there is no connection between them, it’s very easy to lose the audience and have the talk fail. One way to avoid this is to have a central theme to keep coming back to and making sure that everything you say always fits this narrative, can always be driven home to the main theme.</p> <h3 id="creating-flow">Creating flow</h3> <p>If there’s one thing that can make or break a talk (actually there’s many things but I’ll probably keep using this phrase), that’s flow. You may be the most interesting person in the world, or have a ton of information you want to share. Unless you share this in a manner that makes sense, has a proper flow to it, you’re going to lose the audience and it will feel as if you’re a squash ball jumping from side to side.</p> <p><br />With technical talks it’s not that hard to create a proper flow. You essentially rely on building up concepts. If you’re giving a talk about functional programming to a newbie audience, start with higher-order functions and then move on to monads. Not the other way round.</p> <p><br />With non-technical talks it’s much harder however. You have to tell a story, talk about many different things and often it’s not easy to find the right flow. What I do, is use the “Light Table” view in Keynote. Essentially when I’m creating a new talk, I dump all my ideas into Keynote. This usually ends up in a bunch of slides with either a couple of words on them, or some bullet points. These aren’t the final slides. They’re just a dump of everything I want to talk about. Once I have most of my ideas in slides, I then switch to Light Table mode and start to move slides around, trying to get a better flow. I then start working on the final slides and once again iterate over the order of them.</p> <p><br />Once I’m done with all the contents, I then go through my slides from start to finish. I don’t usually practice my talks (and please, don’t do as I do, practicing is very important, but again a topic for another blog post), however, I do murmur through each slide quickly making sure I know what I have to say and that the flow works. I find this technique very useful.</p> <h2 id="the-summary">The Summary</h2> <p>You’d think the summary slide is the easiest wouldn’t you? For many years I used to avoid having a summary slide. Every time I’d try and write one I’d struggle and would just put some random bullet points on there and not give it much thought. But I realised, that my struggle was because my talk wasn’t either focused or coherent, or even worse, had no value.</p> <p><br />Summary slides are not easy to do but are also warning signs that maybe your talk isn’t well-structured, focused or coherent. Think of it as a safety-check. If your summary slide has too many bullet points, maybe you’re covering too much. If you’re struggling coming up with a summary, maybe your entire talk needs work.</p> <p><br />In addition to serving as a final check, a summary is also extremely important to drive home the point(s) you’re making, to remind people of your message or things you’ve covered. It’s a perfect ending to a talk, an opportunity to leave people inspired.</p> <p><br />And if it’s none of that, think of it as a way for yourself to not be surprised that your talk has ended!</p> <p><br /> Until next time.</p> <p><a href="https://hadihariri.com/2018/08/19/public-speaking-talk-structure/">Public Speaking - Talk Structure</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on August 19, 2018.</p> <![CDATA[Public Speaking - Dealing with nerves]]> https://hadihariri.com/2018/08/15/public-speaking-dealing-with-nerves 2018-08-15T00:00:00+02:00 2018-08-15T00:00:00+02:00 Hadi Hariri https://hadihariri.com [email protected] <p>This is part 1 of a multi-post series on public speaking</p> <ul> <li><a href="/2018/08/15/public-speaking-dealing-with-nerves">Dealing with nerves</a></li> <li><a href="/2018/08/19/public-speaking-talk-structure">Talk Structure</a></li> <li><a href="/2018/08/21/public-speaking-slides">Slides</a></li> <li><a href="/2018/08/23/public-speaking-timing">Timing</a></li> <li><a href="/2018/08/24/public-speaking-questions">Questions</a></li> <li><a href="/2018/08/26/public-speaking-speaking">Speaking</a></li> <li><a href="/2018/09/04/public-speaking-should-i-speak">Should I speak?</a></li> </ul> <p>I do not consider myself an expert on the topic of public speaking. However, over the years I’ve picked up a few tips and tricks that have helped me, and by sharing them in a series of blog posts on public speaking, I hope they’ll help you.</p> <p><br />Also, I don’t believe a workshop, a presentation, let alone a blog post (or series of them) will make you a better speaker. Just like playing the guitar, the only way you’ll get better at it, is by practicing. Albeit if it’s any consolation, it’s much easier than learning to play the guitar!</p> <h2 id="dealing-with-nerves">Dealing with nerves</h2> <p>We all get nervous when giving talks. It’s normal. In fact some, including myself, would say it’s a sign of caring about what you’re doing. The objective is to try and handle the nerves and bring them under control.</p> <p><br />The following series of pointers that may help you.</p> <h3 id="dont-tell-people-youre-nervous">Don’t tell people you’re nervous</h3> <p>People can already tell if you’re nervous. Unless you can hide your nerves very well (which also probably means this blog post is useless to you), people can see it. They can tell by your appearance, they can tell by your voice.</p> <p><br />Telling people you’re nervous generally doesn’t help you be less nervous. About the only reason you’d do it is to find compassion. And you may get some, but you’d probably get it anyway without explicitly asking for it.</p> <p><br />In addition, it really doesn’t look all that professional standing on stage and telling people you’re really worried about being there.</p> <h3 id="know-your-topic-and-set-expectations">Know your topic and set expectations</h3> <p>There are many things that make people nervous about speaking - they may forget the words they were going to say, lose their pace, there may be a technical fault. But by and large one of the things that probably contributes the most to being nervous is not being sure of the subject you’re presenting. That feeling of “getting caught out” or feeling like an impostor can really dawn on you.</p> <p><br />Knowing your topic well really helps reduce this variable that influences things dramatically when giving a talk. But what’s more important is setting expectations. If you’re talking about a topic you’re not an expert in, tell people, come clean. Tell them you’re a beginner, tell them you’ve just only started learning this and are sharing your experience. On the other hand, if you’re an expert, well, good for you, but no need to boast about it either. Just keep it to yourself. You’ll know that while many things may go wrong, you’re good on the knowledge front.</p> <h3 id="be-passionate-about-your-topic">Be passionate about your topic</h3> <p>Be passionate about the topic you’re speaking about and convey this passion. Imagine you’re talking amongst a group of friends about something you feel strongly about. Your nervousness can be projected as positive emotions. It will display a sense of confidence.</p> <h3 id="get-to-know-members-of-your-audience">Get to know members of your audience</h3> <p>Often times when I used to give talks, I’d stand by the door and watch people walk into the room. I’d greet them, say hello, get a smile from them. I would also walk up to people in the front row before the talk and chat with them. This allowed me to “get to know” a few people, which in turn would convert a room full of strangers, into a room with one or two friendly faces which I could then use as acknowledgement during my talk. I no longer felt alone. I felt like I knew a few people.</p> <p><br />Not feeling like a stranger can very much help cope with your nerves. In general feeding off of the audience is an extremely valuable tool for having a successful talk, but we’ll cover that in another post.</p> <h3 id="tell-a-joke">Tell a joke</h3> <p>Breaking the ice with a joke is a wonderful way to allow your nerves to settle in. But it’s not that easy, because if your joke goes wrong, it can just end badly. You’re now not only a nervous wreck, but a nervous wreck who just flopped on a bad joke. At this point you have two options: run away or …..well just run away.</p> <p><br />In all seriousness though, if a joke goes bad, you can just accept it and move on or push it a bit further to try and get the audience to laugh, mostly by laughing at yourself and your sucky jokes. But once again, this isn’t always easy and you’ll only get better at this over time.</p> <p><br />In summary, jokes are a great way to break the ice, but have a good one ready. And a second one just in case. However, if you’re not comfortable with humour, best avoid them all together.</p> <h3 id="ask-a-question">Ask a question.</h3> <p>Asking questions can also be a good way to engage with the audience and disrupt that overwhelming feeling of being stared upon by 300 eyes waiting and watching your every move to see where you’re going to fail!</p> <p><br />Similar to jokes however, questions can backfire in several ways</p> <ol> <li> <p>The audience doesn’t answer questions. Yes. Believe it or not, different cultures respond differently. Even to simple yes or no questions, many times audiences remain silent. Personally I just push them to get an answer and usually it works. Sometimes it does fail though and when it does, I usually make a joke out of it. But then that takes you back to telling jokes…</p> </li> <li> <p>The answer isn’t what you expected and can make you more nervous. For instance, you’re giving a talk on “Intro to XYZ”, and based on a series of questions you realise the majority of the audience are experts on the topic. What do you do? Do you adjust your talk? Do you stick to the original plan? Are you going to bore people if so? These are all important questions that we’ll answer in another post, but the point in this case is that it can make you more nervous by challenging your plans.</p> </li> </ol> <h3 id="share-a-story-or-start-with-an-anecdote">Share a story or start with an anecdote</h3> <p>Stories are great, especially ones the audience can relate to, or are somehow related to the topic you’re speaking on. Don’t make them too long though. I’ve been at talks where the speaker has spent a good 10% of the talk telling a story, that while amusing had nothing to do with the actual topic.</p> <p><br />Anecdotes are also good and much easier than stories. For instance you’re traveling to a location to give a talk, share an anecdote of your travel or a local encounter. But please, avoid cliches.</p> <h2 id="nerves-or-excitement">Nerves or excitement?</h2> <p>Recently I tweeted about being nervous when giving talks, which has now led to these series of blog posts.</p> <blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">I&#39;ve been giving talks for around 2 decades now. Still before every single talk I get nervous and it takes me a few minutes to settle in. It&#39;s OK to be nervous. It shouldn&#39;t stop you from giving talks if you enjoy doing it.</p>&mdash; Hadi Hariri (@hhariri) <a href="https://twitter.com/hhariri/status/1028984915214389248?ref_src=twsrc%5Etfw">August 13, 2018</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <p>One of the replies pointed <a href="https://www.youtube.com/watch?v=dqrZ3GDVf9s">to a talk by Simon Sinek</a> about how he channels his nerves and perceives them as excitement. To be honest I’ve never thought about it that way, but I also admit that I’m pretty much always excited about giving a talk so maybe it does make some sense.</p> <p><br />However you think of nerves, just know that you’re not alone. We all suffer from being nervous, and it’s a good thing.</p> <p><br /> Until next time.</p> <p><a href="https://hadihariri.com/2018/08/15/public-speaking-dealing-with-nerves/">Public Speaking - Dealing with nerves</a> was originally published by Hadi Hariri at <a href="https://hadihariri.com">Hadi Hariri</a> on August 15, 2018.</p>