Monday, June 5, 2017

How Software Development Reminds Me of the Things I Learned in the Military

A long time ago (seems like just a few years but the calendar says a few decades) I was in the military. I was very young when I joined, seventeen and freshly graduated high school. My time in the military has defined everything that came after. There were some great lessons there that I chuckle about when I consider my career in software development. Here are some of my favorites.

There is the right way, the wrong way and the Army way.
When on software projects you will see a lot of things that are good and bad. You may try and change them and people may or may not listen. At the end of the day you are still part of a project and you have to work as a team, even though that occasionally means doing things you know are not optimal. Tabs vs. spaces just isn't that big a deal, do what the team agrees on. Just running off and doing your own thing can be more harmful than the practice you dislike. Luckily, unlike the military, if you find the practices too poor and the project swirling the drain you can always leave a sinking ship.

Don't draw fire, it irritates those around you / don't be a blue falcon. 
Look we all mess up once in a while, but don't always be the guy who breaks the build or doesn't make his sprint commitments. Software development is portrayed as an industry of introverted loners but the reality of most our careers are far different. Well not the introvert part, that's true. But we are not loners. For the most part we work in teams and we have to depend on each other. You need to trust the people you work with and they need to trust you.

When the pin is pulled, Mr. Grenade is not our friend.
Having the credentials and ability to deploy software to production is not something that should be treated casually. Sure it has great power but it's dangerous as heck. They have the power to do good things for your company but can also unleash great destruction and if you are not careful it will be your fault. Did I mention don't be a blue falcon?

Cluster bombing from B-52s are very, very accurate. The bombs are guaranteed to always hit the ground.
Everything you change in the code is going to have an effect. Many times it is hard to understand what that effect will be. That little refactoring you want to do right before the release because you can do it better? Be prepared for that to come back at you in some way you don't expect. You can be sure it will change something, just not perhaps what you think. Code changes are in many cases better done with a scalpel instead of wholesale, "well, while I'm here" type changes.

Weather forecasts are horoscopes with numbers.
And so are large project estimates. I don't think I need to go too far into this, but they are rarely right. Humans are horrible estimators of things we haven't done before and almost all truly custom software is doing things we have not done before. The larger the estimate the more likely it is to be underestimated.

Flashlights are tubular metal containers kept in a flight bag for the purpose of storing dead batteries.
All those backups you have and contingency plans are useless when you don't use them or test them. Your computer will crash or something is going to go wrong. The cloud has made things so much easier to make sure you don't loose everything. These days there is no excuse to be stuck with dead batteries. But once in a while you still will be. Expect that too and at the most inopportune time.

Mountain? Hell, it was flat on the map!
Code changes always seem easy when talking about them. How hard could it be. Well that is until you start and find out all the complexities hiding under the hood...

X Days and a wake up.
Sometimes you get on that one horrible project, the death march. No matter how crummy it is, it will come to an end (in one way or another). Your time in purgatory will be limited and one day you will be done with it.

If it ain't raining, it ain't training.
You will learn more when things are going bad than when they are going right, usually much more. When things are going badly it should prompt you to start thinking, what can I learn from this?

Go to the flight line and get some rotor wash.
You can figure this one out. Don't forget to have fun, don't take yourself too seriously and never hesitate to give the rest of your team a good natured hard time.

Sunday, April 16, 2017

The Continued Rise of Cross Platform Tools

This morning I read this: learn to write Android applications in Swift and share code with your iOS app. The mobile market is maturing and unlike what many of us have been used to for a very long time, no one operating system came out on top. Neither Android or iOS will be likely to at this point. The proponents of Android or iOS will point to some movement around the edges, but that's mostly wishful thinking. Until the next revolution, multiple platforms will be the norm and now everyone wants to know how to code for multiple platforms.

This is good news for tools that are created for writing cross platform apps, really good news. We see a lot of them out there, Xamarin, ReactNative, NativeScript, Cordova, Progressive Web Apps, ReactXP, the list keeps going. Where do I think this will lead?

  • The mobile platforms are maturing and the need to write apps for multiple platforms may be necessary for many companies.
  • For internal enterprise apps where the main driver is cost, some organizations will either try to only hit one platform or make a bet on one of the cross platform tools like Xamarin.Forms.
  • Native tools that can only hit one platform, like Xcode or Android Studio will loose traction in many scenarios to lower cost cross platform tools. Increasingly these will be used in scenarios where only one platform is needed or there is some need to stay abreast of the latest and greatest on a platform on the way that a non-platform vendor has difficulty keeping up with.
  • First generation cross platforms tools will loose traction to better tools with many of the same advantages. In particular, Cordova is in danger of this happening in favor of something like ReactNative.
  • The web is coming to mobile with Progressive Web Apps. They still have significant challenges on iOS devices but the popularity of the HTML5, CSS, Javascript platform will drive IT departments in this direction. This may have secondary impacts on if iOS will be able to continue to make inroads in many organizations as corporate devices due to their limitations unless they relent (unlikely at the current time due to the need to protect their app store revenue).
  • Tools that can go cross platform, particularly on the UI layer, will become increasingly popular in scenarios where the UI can be good enough (Xamarin.Forms holds great promise here).
  • Cross platform tools that can do a few platforms in a focused way may win out over cross platform tools that attempt to hit every platform. The coding situation becomes too tough and abstracted when too many platforms are at play; the situation also becomes too difficult for the maintainers to keep up with changes for all the different platforms. Cross platform tools that only target 2-4 platforms will likely do a much better job of it than ones that try to do every one under the sun.
  • Cross platform quality control, build, life cycle, monitoring and tooling products will become more mature. Microsoft's recent attempt at this, Visual Studio Mobile Center, shows great promise for where it could go.
There is a lot of things still going on in mobile. But we are not so much waiting for the next version of the OS, the next announcements at WWDC or Google I/O. The changes there will likely be incremental. The changes that are exciting now are watching how we develop for these diverse platforms matures. Better tooling, better process, better quality control. If you are doing mobile development now you should be thinking about how to have a solid, controlled, and automated process and your tool set for most cases should be cross platform as well. Very exciting for those of us who develop the apps but it leaves me wondering where the excitement will be for the consumer of the devices themselves?

Wednesday, March 8, 2017

Visual Studio Mobile Center - First Thoughts

For several weeks now I've been playing with Visual Studio Mobile Center at If you haven't looked at it yet, it is a mobile build server, mobile cloud testing platform, crash reporting and analytics all rolled into one. The vision is ambitious and there are very few other products you can find that will give you as many different features as VSMC does in one spot.

Just to set some expectations, this is a product in preview mode. Not everything is there that you would expect to be. For example, you can currently only tie the build process into GitHub for source control. If you want a full and complex build process that you need to modify, an app distribution method where you can attach release notes or something beyond the basics, it currently won't do enough for you. But what it does do is easy to work with, very intuitive and I have really not encountered any major problems other than trying to tie it to my enterprise MSDN account for table and identity services.

This appears to be a product that was started before Microsoft purchased Xamarin as the items they implemented first are what was important to Xamarin and not Microsoft as a whole. For example, while there are plans to tie into VSTS for source control, that has not been done yet. While there are plans to implement UWP apps, they are not in there yet either. Microsoft may have Cordova tools in Visual Studio (TACO), but compiling for Cordova is no where to be seen in VSMC. These things will likely all come in time but wasn't the focus of the initial pass.

The general features of VSMC can been summarized as follows:

Build Services - For iOS and Android. Soon to feature UWP.
Cloud Test platform - 1000s of devices in the cloud that can run your Calabash, Appium or Xamairn.UITests. Currently just runs tests from the command line.
App Distribution - Manage different versions of your app and allow testing groups to download and use your app. HockeyApp lite.
Table Services - A light weight front end to Azure tables storage.
Identity Services - A light weight front end to Azure identity services.
Crash Reporting - Track when your apps crash, seems to work for iOS, Android and UWP.
Analytics - Write custom events about how users interact with your app, also seems to work for iOS, Android and UWP.

In some ways I question the usefulness of the table services and identity services that front end Azure in anything other than very simple apps. There is not a lot of control over what is happening under the covers. I'd probably go directly to Azure's Mobile Apps for anything of consequence. However, if you want to stand up a quick app any your needs are really basic, the table and identity services may work for you.

I think it is fair to say the same about many of the things that are currently in VSMC. The most basic functionality is there but there just isn't much else. Some of this is likely to be an artifact of the fact that the product is in preview but also I think to some extent it is by design. For basic apps and people just getting into mobile and really don't have the capability to set up CI/CD build servers, HockeyApp, set up Azure, etc it's a nice place to get started.

A nice bonus feature for those without Macs and are doing something like a Xamarin Forms app, it can build the iOS version of app for you. The only other thing you will need is an Apple developer account for the certificate and provisioning profile and you can then use VSMC to build and deploy the app so you can install and try it on your iPhone/iPad.
I've hear rumors that HockeyApp and Xamarin Test cloud will at some point be rolled into VSMC. It will need a lot of work and features for that to happen. I've also heard from the team that individual pieces of of VSMC may be able to be purchased independently. That would be good if you don't need the build services or cloud app testing but really want the crash reporting and analytics pieces.

Overall the product looks promising. If I were to position it I would say it is currently intended for indie developers and small start up companies without a lot of mobile infrastructure expertise. Complex features and ability to do customization isn't there yet but given this will be under the Azure umbrella those capabilities may come with time. I don't know the pricing yet but overall this is a product to watch.

Tuesday, February 14, 2017

Using an AutomationId with a Cell in Xamarin.Forms

In Xamarin Forms version 2.2 the AutomationId was introduced for iOS and Android. The AutomationIds are tied to renderers and elements that are derived from VisualElements. CellRenderers in their various flavors implement the IRegisterable interface but do not derive from VisualElementRenderer nor does the TextCell class derive from VisualElement. Instead it inherits directly from the Element class.

The upshot of the deal is that while there is a AutomationId property on the TextCell from parent Element class (or any of the other classes that derive from Cell) setting it does nothing. If you do have a design that uses the TextCell and want to use the AutomationId what can you do? I came up with this solution.

First I created a class that derives from the TextCell. It does nothing, it's only purpose is to create a type that we can create our own renderers for. An alternate approach to this one would be to use the default TextView with an Effect.

 public class AutomationTextCell : TextCell  
   public AutomationTextCell()  

Now we can create some custom renderers from it. Before that, I do want to talk a little about the AutomationId property. If we examine Xamarin Forms Element source code we see the property defined as:

 public string AutomationId  
   get { return _automationId; }  
     if (_automationId != null)  
       throw new InvalidOperationException("AutomationId may only be set one time");  
     _automationId = value;  

There is no BindableProperty backing store for this. This means that it will be unresponsive to changes in the custom renderer. The AutomationId that exists when the native control is created is the one that will be used, changes after that will not be honored.


We want to set the ContentDescription property. So what we will do is create a custom renderer in the Android project for our AutomationTextCell and override the GetCellCore method to set the view's ContentDescription property with the current AutomationId value.

 [assembly: ExportRenderer(typeof(AutomationTextCell), typeof(AutomationTextCellRenderer))]  
 namespace YourNamespace  
   public class AutomationTextCellRenderer : TextCellRenderer  
     protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView, Android.Views.ViewGroup parent, Android.Content.Context context)  
       var view = base.GetCellCore(item, convertView, parent, context);  
       view.ContentDescription = Cell.AutomationId;  
       return view;  


We can create another custom renderer in an iOS project to set the AccessibilityIdentifier property of the native view to the AutomationId.

 [assembly: ExportRenderer(typeof(AutomationTextCell), typeof(AutomationTextCellRenderer))]  
 namespace YourNamespace  
   public class AutomationTextCellRenderer : TextCellRenderer  
     public AutomationTextCellRenderer()  
     public override UIKit.UITableViewCell GetCell(Cell item, UIKit.UITableViewCell reusableCell, UIKit.UITableView tv)  
       var tableViewCell = base.GetCell(item, reusableCell, tv);  
       tableViewCell.AccessibilityIdentifier = item.AutomationId;  
       return tableViewCell;  

Now the Marked method in UI test will be able to find the AutomationId's for cells. It is important to note that the TextCell for both platforms contain multiple underlying views so once you get a reference to it in your UI tests you may be doing some further querying to get the exact value you are looking for.

In your UI Test you can use app.Repl(); with the tree command to verify the automation Ids are being set and see the native structure of the cells.

Good luck!

Thursday, January 19, 2017

Why Are We So Awful at Estimating Large Software Projects?

Recently I was talking with some guys over at Xamarin about estimating projects. This got me thinking again about why we are so bad at it. Over the years there has been a continued recognition in the software industry that we are awful at estimating large software projects. There have been a lot of people who have written on this subject and at this point I feel I'm crusty enough where I can write on it too.

We've tried to work our way around our poor estimating skills with Agile models were there is no up front estimating of the project and that's great work if you can get it. But the reality is that in many organizations there is a CFO or another person in control of the budget who is making the decision to allow a project to be funded. He wants to know, "How much is it going to cost?" and he wants to know that before the first line of code is ever written. So we need that upfront waterfall estimate for them, even if we know how difficult such an estimate is likely to be.

When doing estimation of large software projects, for years I've seen a diagram floating around similar to this:


* I'm sorry about my poor drawing skills. This was done on an iPad Pro with a Pencil. The iPad Pro is outstanding (thanks Greg!!!!), my drawing skills are not.

This diagram is of something referred to as the cone of uncertainty. The story goes that when you start a project you know very little about it and thus you don't know its cost. You have a high degree of uncertainty and may think it is more or less difficult than it really is. Over time as you execute on the project you know more about it and the amount of uncertainty about the project and its cost shrinks until the project is done. When it is done you finally know exactly how much it did cost.

At the start of the project you know nothing or very little. This is when people may make some estimates which are shown by the red dots. Some of the estimates will be too high because the complexity and cost was over estimated and some will be too low because the complexity and cost was underestimated. A nice even distribution.

This is a myth we like to tell ourselves. Here is the reality:

What a difference. Most of the estimates are low, way low. A few may be close. These are likely the estimates that when you go out to bid are way higher than the others. Very rarely do any of them match the actual cost at the end.

I'm sure you are thinking this is terrible. Why does it happen? I believe there are several factors that go into it.

  • We have a tendency to think things we don't know well are simpler than they are
When writing custom software we are doing something that has never been done before. When we think about something we have never done before, we tend to think it is simpler than it is because we don't understand the complexities involved. We don't know what we don't know.

Recently I was working with a colleague and we were asked how much does it cost to add internationalization to an application. My colleague thought it was a reasonably simple task and listed off how the Android system handles string resources. I had just completed a project with internationalization and I replied that it could potentially be a large effort. It was a cross platform project so we needed a way to have cross platform resources, we would have to see if we have to do any currency conversion and deal with what exchange rates to use, perhaps we might have unit of measure conversions like pounds to KGs or miles to kilometers, we might have graphics that need to be different per culture, we may even need to tweak the layout to handle making space for languages like German with long words. The amount of complexity in there could be very large but we don't know all the pieces that could be in there until we have done it before.

Since the software we write is custom by definition, some of what we are doing is unique; things we have never done before. As such, we will tend to underestimate the effort.
  • Many times it is some of our best people doing the estimates
Another problem run into when creating estimates is that in many cases it is the senior people who do the estimates on large projects. After all, they are our architects and most experienced people. This is great, but they also tend to be the people who work the fastest and may estimate based on how long it would take them to do the task. The person doing the work may not have the same experience or velocity.
  • We only think of the primary activity and tend to gloss over all the things around it
When thinking about a feature we tend to think in terms of what it takes to actually code it. What is in many cases forgotten are all the activities around it. Creating a feature branch, checking in and out code, merging code, creating pull requests, responding to code reviews and even making tests (if not estimated elsewhere). Additionally user experience design and quality assurance iterations tend to be much larger than people think about. All of these things add up to real time which brings us too:
  • Things that seem small and inconsequential add up
Some of the activities I mentioned can sometimes be discounted. After all, it can be argued that it takes almost no time at all to create a feature branch. The problem with that thinking is that it does take time. A couple of minutes here, a couple of minutes there equates to large buckets of time. When they are not included, our estimate is necessarily too low. We don't tend to add things that aren't there but we almost always discount things that should be, so the estimate is low.
  • People are not machines but many times we estimate as though they are
Sometimes we will estimate thinking their people are going to work eight hours a day, forty hours a week on a project. This is not reality. People need time for bio brakes, admin functions and sprint ceremonies and just time to think. You should probably be thinking more like six hours a day. 
  • Lower estimates make people happy and we like to please people
This bit is one of the more insidious reasons why estimates are low. Many of us are hard wired to try and please people and this includes the people who are making the estimates. They know that they will please more people when the estimates are lower. The business more likely to be won, the project more likely to be funded.

I have a saying, unlike wine, bad news does not improve with age. I fully believe that, but it is not something we take to heart in estimating. In most cases it isn't purposeful, it is just an unconscious desire to please leading to bias for lower estimates. We give the lower estimates now because it is good news. But what I said still applies, bad news does not improve with age and clients don't tend to like finding out a project was underestimated half way through.
  • We tend to estimate the happy path
Lots of things come up when developing. Sometimes we encounter bugs with our tools, sometimes our machines break, sometimes we have to way to get access to some system or an external resource will not be available through no fault of our own. We don't normally think about these things when estimating. An underlying assumption on many of our estimates is that our machines will always work, the services will always be up and well will get immediate access to any resource we need access to. 
  • There are many ways to implement a feature
Recently we did a presentation with a prospect on why we couldn't estimate their project based on the information they had given us to far. We went over several of their features and mentioned three ways that each could be implemented with a very different level of effort for each. 

People who go out to bid in many cases think their RFP and specifications are much better defined than they actually are. Since we tend to like to please people and know lower estimates will do so, our estimates tend to be for the simpler implementations. The problem with this is there wasn't a meeting of the minds between the prospect and the person doing the estimation. They estimated a Yugo when the prospect may be envisioning a Cadillac.
  • We only think we know what the software should do
One of the reasons to go with a minimum viable product in mobile is because only through experimentation do we find out the optimum formula to achieve business outcomes and that formula will have to be tweaked through the lifetime of the application.

I was recently with a prospect and we let them know it may be several iterations before they really get their application to where it is achieving business outcomes. Incredulously they asked us, "Do you mean to say you can't write it right the first time?" to which we replied, "Unfortunately you don't know what needs to be written yet."

This is the reality of a software product. No matter how well thought out a set of waterfall up front specifications are, they will not survive contact with the implementation intact, they will be changed. This will cause reimplementation work that is almost certainly not part of the estimate.
  • We go out for competitive bids
Another problem we run into is when we go out for competitive bids. We give our potential vendors ample incentive to try and come up with best case scenarios, after all they want to get the business. They will play with the model, different ways thinks could be implemented, etc. These changes are not necessarily being made to increase our business outcomes but instead to win the work.

Of course the problem is that much of this work is time and materials. The laws of physics are not being bent with these bids. The effort in the end will be what it will be. But we give our vendors ample incentive to "get creative" in the estimating process. Which brings me to
  • Sales people like to sell
Sales people like to sell. In all consulting companies there is a desire to get the work. In most cases they are not purposely trying to do anything to undermine their clients, but they do want the work. That leads to a situation where tremendous pressure can be put on the people making the estimates to keep them low by the sales staff.

This problem is very pronounced in sales driven organizations where the sales teams can be very influential. After the business is won the delivery teams have to pick up the pieces and try to deliver on unrealistic estimates. If you are bringing in an outside consulting company be very careful to know if that partner is more delivery focused or sales focused. The estimates of a delivery focused organization are likely to be more realistic but likely higher.

I don't Just Want to Complain About How We are Bad at Estimating

If you are trying to estimate a software initiative, particularly if you are trying to bring in a partner, there are things you can do to reduce the impact of all the bad estimating.

  • Understand the bids are all too low, plan accordingly
If you went out to bid based on some specifications you came up with, know that you are at the wide opening of the cone of uncertainly and all the bids are likely clustered at the bottom. Whatever the successful partner's bid is, pad it. With that extra padding the project won't end up as over budget as it otherwise would have been. 
  • Have workshops with potential partners
While the estimates will likely be clustered around the low end of the cone of uncertainty, a way to get them as accurate as possible is to move further along the cone. The more the potential partners know, the more complexity they will understand and the more accurate their estimates are likely to be.

This has the unfortunate side effect of also likely making the estimates higher but by doing these types of workshops you can usually get a feeling for working with the different potential partners and which are better than others. We do such a workshop quite frequently, called a backlog grooming workshop. Our purpose is to move further along the cone of uncertainty and understand more about what the software needs to do while getting a feel for the prospect while they get a feel for us.
  • Examine why bids are different
If you get in several bids, don't be tempted to just take the lower one. If one is much different than the others, try to understand why that is. It may not be an apples to apples comparison, they may be thinking about something the other potential partners are not or the delivery model could be substantially different. 

We do this with planning poker as well. If someone's answer is very different than everyone else's, it pays to find out why. They could very well be thinking of something crucial to why your project may cost a different amount than the other potential partners are thinking.

  • Understand if you are dealing with a sales focused or delivery focused organization

The bids of sales focused organizations may be lower. They also may have cut all kinds of corners in the delivery plan to have that lowest bid. Just be sure you understand what you are getting. Sometimes cheaper is more expensive in the long run. 

In delivery focused organizations the delivery teams tend to have more input in the estimation process are are always asking themselves if they can implement it, because they have to. The delivery plans of such organizations tend to be better thought out and as such may have less cost overruns due to problems with the delivery model itself.
  • Think in terms of product instead of project
Something that we think a lot about with mobile software is it a project or a product. A project has a known scope and when it is done it's more or less done. (see this post by Russ Miller: Mobile Project or Mobile Product). Projects normally have fixed up front budgets, timetables and scope. Since we know the budget is likely too low, projects usually result in cost overruns. 

Products are normally done on a capacity model with a burn rate over a period of time with a variable amount of scope. With a product approach you may not fully know the amount of functionality that will be achieved but with a fixed burn rate, you do know the cost. If there is some flexibility in the scope for an MVP release or the date, a product approach with a capacity team can give you much more accurate period over period cost forecasting and to some extent sidesteps the whole problem with underestimating.
  • Estimate small things
A co-worker has opined and a small 1-2 story point estimate is likely to be 90% accurate while a 40 point epic is likely to only be 50% accurate. The more you know about something and can break it down into smaller chunks, the more accurate the estimate is likely to be. Similarly, if you break your software releases into smaller chunks where a MVP really is the minimum, then the more accurate the estimates for them will be as well.
  • Semper Gumby
At the end of the day be a little flexible with your expectations. We know people are poor estimators and we know some of the real reasons that go into it. Go in knowing that the estimates are too low but also with an understanding of what level of budgetary tolerance you can be off before business objectives are really being impacted. If you can, be somewhat flexible on scope, particularly for the first release. Complex systems take time and iterations to build correctly. 

Understand that the estimates are too low, what functionality is really critical to business success and which is not (if you think it all is, you are likely mistaken), know what tolerance you have for cost overruns and just be as flexible as you can within the constraints of meeting your business goals.

Saturday, January 14, 2017

Don't Feel Bad that You Don't Know Everything

It's been a few months since I've written a blog post. I've been busy re-learning things for my presentations, figuring out how to do all kinds of material design concepts around animations, snack bars and expansion panels, working on a podcast, creating a class, preparing for a workshop, learning the latest and greatest about MvvmCross and playing with my Swift demo code to make updates as a result of Swift 3.

That's just a small sample of of what I've been trying to keep up with in the past several months. I keep telling myself I just have this one last push and it will be over for a while, but there is always another surge of learning and work right around the corner. So here I am at 1:30 AM on a Saturday morning, trying to know everything there is to know about mobile and realizing I still don't.

Mobile and responsive web weren't the first things I did this with. Before that it was various flavors ASP.Net, Silverlight, Remoting. general .Net, VB and COM, FoxPro and before that Clipper and DBase. Most of us understand the idea that we will spend our our entire careers learning and re-tooling. But here's the rub, the velocity of change has increased dramatically and the variety of things to know has similarly increased, seemingly exponentially. If you feel confused or guilty because you don't know it all, don't be. You can't, no one can.

If you go to the latest VSLive or Evolve, don't feel guilty if the speaker is giving a presentation on whatever is new and you haven't touched it yet. Here's the reality. The speaker probably has only been working with some of these new technologies for a few months, because that's all we could have been working with them. Here's another reality check, when I listen to someone else and they know about something I don't, I think to myself "How do they keep up with all this stuff?" I suspect many other speakers similarly think that about others from time to time.

Why do we feel this way, why are we so hard on ourselves? Partially because we've got it in our heads that we have to know it all.

There was a time, probably around 1999, where I though I knew everything about using VB 6 with COM that there was to know. I even knew a great framework to use with it, CSLA. I thought I had it all locked down. I probably was a bit overconfident but wasn't overly far off in my thinking. The amount there was to know about that topic was comparatively finite. Of course all my illusions were shattered soon after when I heard rumblings of something new on the horizon that would become known as .Net.

Fast forward 18 years and I don't think anyone fully knows all there is to know about Xamarin for iOS, Android and Mac, much less everything in Forms. Not even close. There is just too much to unpack. When I think I am getting even remotely close to unpacking it, it will be time to start looking at Android O and iOS 11, oh and by the way here are the new changes to C#. Don't even get me started on Azure.

As an industry we have got to stop expecting that we will know it all. We can't know it all. Instead, keep your eyes and ears open, absorb what you can, when you need to, and write your best code. You don't need to know everything to write good code and create things that provide value. If you don't know the latest language keyword they added to C#, that doesn't make your code bad. People were writing good code without that keyword last year and more than likely your code is still just fine without it.

We have to stop being so hard on ourselves.