With constant updates happening in the tech world, it can be hard to keep up and keep track of all the latest improvements software faces. Today, I’m here to share new insight and offer a look into the specific world of Spring Boot 3, Spring 6, and Java 17+.
My study of these technologies first began when I discovered Bryan Hansen’s insightful Pluralsight Course. If you’re like me, and want a more in depth analysis of the change, I recommend watching his course. This blog however is to provide a quick overview of the changes, why you should pay attention to them, and a tips for upgrading your existing apps.
Why should I care?
Before we really jump in, I do want to acknowledge a pertinent question that may have crossed your mind: “Why should we care?” It’s a legitimate question and the previous changes lately in both Spring and Java often seemed like surface-level adaptations in response to emerging technologies like Kotlin. However, allow me to present a counterargument.
Spring 6 and Spring Boot 3’s exclusive support for Java 17 signifies a pivotal shift. Those seemingly minor updates from Java 8 to 17 have collectively transformed Java for the better. What’s more, they’re quickly becoming interview essentials for innovative teams adopting Spring 6 and Spring Boot 3. Embracing these changes is not just prudent; it’s also remarkably accessible. A few hours of study or even a viewing of the Pluralsight Course mentioned earlier, equips you to effortlessly harness these enhancements as they become mainstream. It is also important to note that Java 21, a new LTS version, was also recently released on September 19, 2023. While we won’t be covering Java 21 much in this blog, you can learn more about its features in our informative Java 21 Webinar.
What’s new in Java?
Many teams I’ve encountered tend to stick with Java 11 or Java 8, both of which are LTS (long-term support) versions and excellent choices for production applications. However, Java has seen a slew of new features added in recent years, making it worthwhile to consider an upgrade.
Here is a short list of the new things in Java 17 you should know about:
Records: Records are a new type of class designed to be lightweight and easy to use. They provide a concise way to represent data, and can be used to improve the performance and readability of your code. Records are immutable by default, which can help to improve the safety and security of your code.
Sealed classes: Sealed classes are a new way to restrict the subclassing of a class. This can be used to improve the safety and security of your code. Sealed classes can be used to create a hierarchy of classes where only certain classes are allowed to extend or implement a particular class. This can help to prevent unauthorized extensions, which can lead to security vulnerabilities.
Switch expressions: Switch expressions are a new way to write switch statements. They are more concise and expressive than traditional switch statements, and they can be used to improve the readability of your code. Switch expressions also allow you to assign values to variables directly within switch cases, which can make the code more concise and eliminate the need for break statements.
Pattern matching for switch statements: Pattern matching for switch statements is a new preview feature in Java 17. It allows you to match against patterns in switch statements, which can be used to improve the readability and safety of your code. Pattern matching can be used to simplify complex conditional logic and make your code more concise and expressive.
Foreign Function and Memory API (incubator): The Foreign Function and Memory API is a new API that allows Java applications to access code from outside the JVM. This can be used to improve the performance of your applications by offloading tasks to native code. The Foreign Function and Memory API is still in the early stages of development, but it has the potential to significantly improve the performance of Java applications.
In addition to these new features, Java 17 also includes a number of other improvements, such as:
Improved performance
Improved security
Improved stability
If you are considering upgrading to Java 17, I recommend that you read the Release Notes to learn more about the new features and improvements. You can also find a number of tutorials and articles online that can help you get started.
What’s New in Spring Boot 3 and Spring 6
Spring Boot 3 brings a host of exciting updates and improvements to enhance your development experience. Here’s a closer look at some of the key features:
Java 17 baseline: Spring 6 is based on Java 17, which is the latest LTS version of Java. This means that Spring 6 will be supported for at least 8 years, which gives you peace of mind when building your applications.
Improved performance: Spring Boot 3 has been optimized for performance, with improvements in areas such as startup time, memory usage, and garbage collection.
Support for Jakarta EE 10: Spring 6 and Spring Boot 3, don’t just support Jakarta EE 10, they were designed with Jakarta EE 10 in mind. This is one of the bigger changes that you will likely have to make to your existing projects to get them upgraded and inline with where the industry is heading.
AOT (Ahead-of-Time) compilation: Spring 6 provides built-in support for AOT compilation, which can significantly improve the startup time and memory consumption of your applications. AOT compilation is a process that converts Java bytecode into machine code, which can be executed directly by the operating system. This can be a major advantage for applications that need to start up quickly or that need to be very memory efficient.
Support for GraalVM native images: Spring Boot 3 now supports GraalVM native images, which can be used to create native executables of your Spring Boot applications.
Improved observability: Spring 6 and Spring boot 3 provides built-in support for Micrometer and Micrometer Tracing, which are open source libraries for collecting and exporting metrics and traces from your applications. This makes it easier to monitor and troubleshoot your applications.
ProblemDetails API: Spring 6 introduces the ProblemDetails API, which is a standard way to represent errors in HTTP APIs. This can be helpful for improving the interoperability of your applications and for making it easier for users to understand and troubleshoot errors.
Improved Security: Security is a top priority, and Spring 6 and Spring Boot 3 introduces improvements to ensure your applications remain resilient against evolving threats.
Improved Documentation: Clear and comprehensive documentation is crucial for any framework, and Spring and Spring Boot continues to refine and expand its documentation to provide developers with the resources they need.
Improved Testing Support: Testing is a fundamental part of the development process, and Spring 6 and Spring Boot 3 enhances testing support to help you write robust and reliable tests for your applications.
Tips for upgrading your app
Use Spring Boot’s new Migration Tool and follow the readme instructions carefully – it is pretty helpful. Also make sure you don’t have your application running on 8080 as that is the port the migration tool will run on.
In Spring Boot 3, you don’t need to include Jakarta.servlet as a separate dependency; it’s automatically included. If you encounter an error related to this, it’s likely because some of your dependencies are still using the older javax package instead of Jakarta. Notably, Springfox, commonly used for Swagger, is an example of this. Unfortunately, there isn’t currently a compatible version of Springfox for Spring Boot 3, and it’s unlikely to receive updates.
To continue using Swagger, I recommend transitioning to Spring Docs, which is a good choice regardless. To do this, simply remove your Springfox configuration and dependencies and replace them with Spring Docs. View Documenting a Spring REST API Using OpenAPI 3.0 to find a step by step easy implementation guide.
If you encounter dependency errors, it’s possible that the new spring boot migrator might have overlooked some of the dependencies you need to upgrade. If you see errors related to a specific dependency, consider researching the version it requires to function seamlessly with Spring Boot 3, before digging in too deep on the error.
We’ve covered a lot about what is new in Java, so now it’s your turn to dive in and explore on your own! If you have any questions, thoughts, or insights to share, please reach out to our team via our Contact Us Page or on any of our Social Media Channels, we’d love to hear from you. Remember, the world of tech is ever-evolving, and staying updated is the key to success. Until next time, happy coding!
By: Jonathan Donkin
This is the 2nd part of a 7-part series. The first part can be found here https://stgconsulting.com/habits-of-highly-effective-software-developers/. As always, I look forward to your thoughts.
Begin with the End in Mind
In the Seven Habits of Highly Effective People, Covey makes the point that this habit is about leadership and your circle of influence. Covey makes the analogy of a team slogging through the jungle and how management is happy with how much jungle has been cut away by the workers, but the leader is in the tops of the trees asking the question “are we going the right direction?”.
As we build our products we should be asking ourselves “are we going the right direction?”. This simple question can be applied to everything from the architecture, framework being used, and even the individuals’ efforts on the story they are currently working on.
Agile Stories
It is my experience that when you start working on a story while following the Agile methodology, it helps to know where you are going and what you are delivering. While this seems to be intuitive for those that have only worked on well flushed out user stories, I have definitely worked on stories that weren’t well flushed out for some reason or weren’t technically reviewed properly. When this happens, time is wasted going back and forth, either to figure out the how or the what of the story. If we begin a user story with the end in mind, then the process becomes much smoother in the long run, and it is easier to deliver what is being asked for by the user.
This starts by getting all of the users’ requirements upfront and then asking the question of what is being delivered. In the what, we should also be looking for any gaps in the requirements such as what is the expected behavior if this form field is not filled out and the submit button is clicked. As those requirements, and with it understanding, is figured out then we begin to focus on the how. How are we going to write this so that the requirements are met? I also think about how I can write the code in a way that it is clean (if you aren’t familiar with what is clean code I highly recommend that you read Clean Code by Robert Martin) and loosely coupled (think SOLID principles).
Architecture
This is where the architecture of our code definitely comes into play. Do we introduce an interface to create a contract between one class and another? I say yes and with this as well as other parts of the SOLID methodology we begin to create decoupled and clean code. Another aspect of SOLID that makes a huge difference in the readability and maintainability of our code is keeping methods/functions small and only doing one thing (Single Responsibility). This all helps with loosely coupled code which makes it easier to maintain and change this code in the future as our user requirements will always inevitably change. So, by following these kinds of principles even if we don’t know what the end is with our project we are still keeping the “End in Mind” by allowing the code to “easily” change as needed.
By: Jonathan Donkin
Recently as I was reading Seven Habits for Highly Effective People by Stephen Covey, it dawned on me that those same habits that Covey says he put together into Seven Habits actually applies to Software Development as well. So as an attempt to gather together my thoughts both from my own experience as well as from technical books I have been reading, I decided to stretch myself and write about the Habits of Highly Effective Software Developers as a monthly blog. As you read along, I look forward to your thoughts and feedback as to what you find to be your habits that have helped you as a software developer.
If you haven’t read Seven Habits of Highly Effective People, I highly recommend you take the time to read that book. I personally see the teaching in that book to apply to far more than business. I have used the techniques in my personal life, relationships and to Software Development. As we go into each habit, you will see some of the development concepts repeated as they can be applied in different ways to each habit.
So to begin here are the Seven Habits:
Be Proactive
Begin with the End in Mind
Put First Things First
Think Win-Win
Seek First to Understand, Then to be Understood
Synergize
Sharpen the Saw
Being Proactive
What does it mean to be proactive? As a software developer being proactive means that I take charge of my outcome. Okay, so what does that mean? In preparing to write this, I found myself reading three books which are The Clean Coder by Robert C Martin, The Software Craftsman by Sandro Mancuso, and The Pragmatic Programmer by Andrew Hunt and David Thomas. As I read each of those books, I would come across something that would jive with what I was thinking it meant to be Proactive and taking charge of my outcome. So far I have two main areas that I see developers being proactive in their work. Take responsibility for your software and take responsibility for your learning. Take Responsibility for your Software
To me every time I write software whether it is my own personal project or a client’s code I take ownership of that code. It would be like a custom furniture builder only taking their time creating the best stuff for themselves while rushing their customer’s products through their shop creating a substandard product that they then deliver to the person who is paying for their product. Our software isn’t much different when we write our own code.
One of the best ways that we can take ownership of our own code is to test our code to make sure that it is functioning correctly. “Therefore, when you release your software you should expect QA to find no problems. It is unprofessional in the extreme to purposely send code that you know to be faulty to QA” (Clean Coder pg. 12). The section goes on in a moment to say will QA find bugs, and the answer is yes. We will test the code to our understanding, and then QA will test it to theirs which isn’t always the same as ours, and that is when they will find the things we didn’t think of initially.
How should we be testing our code? The easiest way for us to test our code is to write unit tests on each unit of work that is done. One other thing here that is important to note is that a great test is only testing one thing, not multiple things. Tools like junit and nunit allow for you to pass multiple parameters into a single unit test allowing for multiple scenarios to be tested against your method. While there is a lot more to be said about testing that is outside the scope of this article and there are currently plenty of articles and videos out there on unit testing. Another way I like to test is to simply run the code and manually make sure that it is behaving like I expect it to. For API’s I like to use Postman to hit my endpoints and for any UI, manually testing and using the chrome debugger tools. Take Responsibility for your Learning
While we are all able to learn while on the job, I personally have found what helps me shine as a software developer is taking control of my learning instead of waiting for my learning to come to me. This idea was inspired from reading the Software Craftsman by Sandro Mancuso who in chapter four asks the question “Who owns your career?” His point it seems is to point out that while most places should be an effort into your learning and training, it isn’t completely their responsibility. He even makes the comparison that if you were to hire a different professional such as a plumber or lawyer, they wouldn’t ask for you to buy them a book for them to do the job in which you have hired them.
So what can we do to take charge of our learning and in essence own our career? Mancuso suggests reading books and not just technical books but books on behavior and other books he terms classics like the Pragmatic Programmer or Design Patterns by the gang of four. Interestingly enough the same thing is recommended by the Pragmatic Programmer which recommends reading a technical book a quarter and non-technical books as well. There are other ways as well that we can learn by reading which is to find and follow a good blog. I personally have found some really good JavaScript blogs on medium.com lately that have helped with various things I have been working on and there are others as well for whatever language you are working in.
I am of the mindset that writing a blog is a great way to learn as well. As I come across something that I need to learn in order to finish what I am working on either for myself or a client, I am inspired to do a deep dive on the subject and put together a blog post teaching what I have learned to others that may find it. For me, this does two things. First, it helps cement what I learned by taking the time to write out the steps needed to solve the problem and second, it acts a way to keep a record of what I did previously to solve the problem. I win and hopefully whoever finds this post learns from it as well.
The Pragmatic Programmer also recommends you learn a new language a year. While I think that in general this is a good idea. My thinking on this is also to consider looking for parts of a language you know but haven’t had a chance to use or learn. Such as learning a new JavaScript framework, C# or Java library that you simply haven’t used before and learn how it works. Of course, the fun in learning something new is to create something with it by writing the code. By implementing the newly learned language into a project of your choosing, this only helps cement that knowledge and like writing the blog give a reference to come back to when you have forgotten something that you previously learned.
The final thing that I love for my own learning is training videos that you can get from many places, but two of my favorite are Pluralsight and YouTube which have many courses to choose from. Ultimately there is more content than any one person can learn in their lifetime.
Author: Matt Chiang
Learning never exhausts the mind. –Leonardo da Vinci
@STG this year, we stayed engaged in learning during the summer by doing a series of automation code challenges. The code challenges were simple at first and gets more difficult. Some concepts were easy to grasp. Others were more difficult. However, in the end everyone learned. STG is opening up the code challenge to everyone who wants to participate. You are welcome to use any programming language or framework you want. Some frameworks/languages will be easier to implement than others and some will have more capabilities than others. To submit your work, go to the Contact Us page (https://stgconsulting.com/contact/) and submit your github repository along w/ your contact info. Make sure you make your project is public so our engineers can review your code submissions. Each code challenge is worth one entry that will be held at the end of February for prizes (Backpacks, Messenger Bags, Apple TVs, Amazon Gift Cards, Camping/Emergency lanterns). We will contact the winners in March 2017 You are also welcome to contact me through linkedIn for help and for code submissions. A grand prize will be given to the first person to complete and turn in all 8 challenges.
Here’s the code challenges:
Automation Challenge 1 (go to a site):
Write a method that will navigate me to any site I want to go to and verify the site is the correct site. Here’s the steps for your automation: 1. Go to https://www.skiutah.com 2. Have your automation get the name out of the <title> tag.
Automation Challenge 2 (Navigation Menu class):
Write a class that will allow me to navigate the main pages on the site. Go to https://www.skiutah.com If you click on Stories, it goes to the Stories page. Remember to make this a class/method that will accept a string value of the menu I want to navigate to and not something that is static. Sample stub code. @test public void automation 1(){ siteName = “https://www.skiutah.com“; validationString = “Ski Utah”; navigateTo = “Deals”; AssertTrue (goToPage(navigateTo, validationString)); }
This is an extension of the previous challenge. Write a class that will allow me to navigate the sub pages w/in the menu on the site. Go to https://www.skiutah.com If hover over the main menu items, you’ll see the hover event and see the submenus. Some items in the menu has submenus and some don’t. Write a method that will allow me to navigate to the submenu by triggering the hover event and then clicking on the item in the submenu that I want to navigate to.
Automation Challenge 4 (Get info):
write a method to return the time each ski resort is from the Airport. Go to https://www.skiutah.com/ click on the link that is on the home page to compare resorts. The method should be able to return a time based on the name of the ski resort that I want to pass in. You can return the value either w/ a string or int. @test public void automation1(){ System.out.println(timeFromAirport(airportName)) }
Automation Challenge 5 (Use search and get info)
Go to https://www.skiutah.com/members/listingWrite a method that will allow me to pass in 3 string parameters (What, By Resort, Sub Category) Return the list of the search results by looking ListingResults-item
Automation Challenge 6 (Crawler):
write a crawler that will automatically navigate to every page on the site. Go to https://www.skiutah.com/ Build a crawler that will start at www.skiutah.com and finds every link/page and goes to that page and finds other pages it needs to visit. Remember to not visit the same page twice and to only visit the pages on the domain.
Automation Challenge 7 (Crawler and get text):
Extension of last project. Use the crawler and catalog every word used and the number of instance each word occurs. Go to https://www.skiutah.com/ use the crawler written in the past challenges and write a method to keep track of all the words on each page on the site and return to me a list or dictionary of words that exists on the site. Also send me the list or dictionary in a text document.
Automation Challenge 8 (Crawler and image verification):
Extension of the crawler challenge. As you navigate through the site, find every broken image. Go to https://www.skiutah.com/ Verify that each reference to an image displays the image correctly and not a dead image.
Author: Matt Chiang
You may have heard the phrase “Data is the new oil” but like oil, data must be refined before it can really be useful. Numeric data is easy to refine – you can add it, sort it, average it, and look for trends. But what about text? How do you add words?
This + That = ?
80-90% of the data in most organizations is Unstructured Data such as emails, text messages, open ended comments from customers, reports, health records, images, and audio/video files to name a few. Unstructured data tools help refine your data into something you can process easier and faster. It can help answer questions like:
Who is talking?
What are they talking about?
How do they feel about it? (sentiment – positive, neutral, negative)
This information can then help you monitor your operations more effectively, build predictive models, perform tasks faster, and deal with data that would otherwise be too big to handle manually. Text analytics is specialized software for unstructured data. It uses linguistic tools to extract meaning and the important pieces from your data as structured pieces which you can then use like numbers. Speech to text converts your audio to text so you can run it through text analytics. Some examples include:
Voice of customer – process open ended comments in real time to address customer issues right away instead of once / quarter.
Call center – 100% monitoring of calls to allow available management resources to focus in on the most important issues instead of monitoring 1-2% of calls at random.
Manual review tasks – things like Medical coding which can’t be totally moderated could be sped up by first processing textual records with unstructured data tools.
Legal and compliance – detect and correct issues in email and other company communications right away instead of finding the problems during a court case.
Chatbots – handle more simple questions and collect intake information in a natural, conversational format allowing human agents to focus on more complex issues.
Social media, news feeds and other data sources – monitor real time and get a digestible summary of the content and sentiment across all of that data. Can be used in applications such as competitive analysis or setting up predictive models.
Images – use image recognition software to classify, compare, and search images. Like your own “google image search” for your image data. Speed up reporting of issues by taking a picture and processing it vs writing a report, detect maintenance issues, and audit access to buildings to name a few.
Unstructured data tools can help you get value out of data that is otherwise sitting idle in storage, increase the productivity of your manual data processing, build predictive models and use data in ways that are just not possible by hand.
>How much are you paying to store data? Are you getting anything out of it? Please contact us to discuss your business and your data. We can identify specific areas where refining the data with unstructured data tools can increase your productivity, reduce risk, and unlock insights that may otherwise stay buried forever.
by Matt Chiang
“Learning never exhausts the mind.”
-Leonardo da Vinci @STG this year, we stayed engaged in learning during the summer by doing a series of automation code challenges. The code challenges were simple at first and then get more difficult. Some concepts were easy to grasp. Others were more difficult. However, in the end everyone learned. STG is opening up the code challenge to everyone who wants to participate. You are welcome to use any programming language or framework you want. Some frameworks/languages will be easier to implement than others and some will have more capabilities than others. To submit your work, go to the Contact Us page and submit your GitHub repository along with your contact info. Make sure you make your project public so our engineers can review your code submissions. Each code challenge is worth one entry that will be held at the end of December for prizes (Backpacks, Messenger Bags, Apple TVs, Amazon Gift Cards, Camping/Emergency lanterns). We will contact the winners in January 2017. You are also welcome to contact me through LinkedIn for help and for code submissions. A grand prize will be given to the first person to complete and turn in all 8 challenges. Here are the code challenges: AUTOMATION CHALLENGE 1 (GO TO A SITE): Write a method that will navigate me to any site I want to go to and verify the site is the correct site. Here are the steps for your automation: 1. Go to https://www.skiutah.com 2. Have your automation get the name out of the <title> tag. AUTOMATION CHALLENGE 2 (NAVIGATION MENU CLASS): Write a class that will allow me to navigate the main pages on the site. 1. Go to https://www.skiutah.com 2. If you click on Stories, it goes to the Stories page. 3. Remember to make this a class/method that will accept a string value of the menu I want to navigate to and not something that is static. Sample stub code: @test public void automation 1(){ siteName = “https://www.skiutah.com“; validationString = “Ski Utah”; navigateTo = “Deals”; AssertTrue (goToPage(navigateTo, validationString)); } AUTOMATION CHALLENGE 3 (NAVIGATION SUB MENU CLASS): This is an extension of the previous challenge. Write a class that will allow me to navigate the sub pages w/in the menu on the site. 1. Go to https://www.skiutah.com 2. If hover over the main menu items, you’ll see the hover event and see the sub menus. Some items in the menu has sub menus and some don’t. 3. Write a method that will allow me to navigate to the sub menu by triggering the hover event and then clicking on the item in the sub menu that I want to navigate to. AUTOMATION CHALLENGE 4 (GET INFO): Write a method to return the time each ski resort is from the Airport. 1. Go to https://www.skiutah.com/ 2. Click on the link that is on the home page to compare resorts. 3. The method should be able to return a time based on the name of the ski resort that I want to pass in. You can return the value either w/ a string or int. @test public void automation1(){ System.out.println(timeFromAirport(airportName)) } AUTOMATION CHALLENGE 5 (USE SEARCH AND GET INFO): 1. Go to https://www.skiutah.com/members/listing 2. Write a method that will allow me to pass in 3 string parameters (What, By Resort, Sub Category) 3. Return the list of the search results by looking ListingResults-item AUTOMATION CHALLENGE 6 (CRAWLER): Write a crawler that will automatically navigate to every page on the site. 1. Go to https://www.skiutah.com/ 2. Build a crawler that will start at www.skiutah.com and finds every link/page and goes to that page and finds other pages it needs to visit. Remember to not visit the same page twice and to only visit the pages on the domain. AUTOMATION CHALLENGE 7 (CRAWLER AND GET TEXT): Extension of last project. Use the crawler and catalog every word used and the number of instance each word occurs.
1. Go to https://www.skiutah.com/ 2. Use the crawler written in the past challenges and write a method to keep track of all the words on each page on the site and return to me a list or dictionary of words that exists on the site. Also send me the list or dictionary in a text document. AUTOMATION CHALLENGE 8 (CRAWLER AND IMAGE VERIFICATION): Extension of the crawler challenge. As you navigate through the site, find every broken image. 1. Go to https://www.skiutah.com/ 2. Verify that each reference to an image displays the image correctly and not a dead image.
Author: Dan Woodruff
Ever had a developer join a team, suggest a radical solution and be shut down? Or have them suddenly be allowed to develop their ideas? I find it fascinating as to how this happens and may have some insight. Each company’s culture, whether they know it or not, has inherent values. For example, do they put security first over maintainable code? Do they allow applications to have bugs and issues just so that they can be first to market? Do they always invest in new ideas instead of making code work? I find the answers by evaluating a company’s set of values as discussed below.
I ran across a book early in my career that has impacted me for the last 10 years. It was all about best practices with 700 examples. I used it as a reference for some time and although concepts and opinions within it have changed, the guidelines and more importantly VALUES of the book have stuck with me.
The values or concepts in that book are: (Paraphrased and listed in descending order)
Robustness – Code must work as intended and not cause fatal errors
Security – Malicious app use is not allowed including class use
Scalability – As the number of users grow, so to must the application
Efficiency – light and fast with no added strain on external resources
Usability – Application should be easy to use and learn
Code Reuse – It should be easy to reuse code for other projects
Extensibility – Extendable classes and localizable with limited effect on current app
Maintainable – Source should be readable and consistent without undocumented features
Language Interoperability – Code should be translatable to another language
Ease of Development – Productive quick coding with less human errors
Shortly after acquiring the book, I also had a respected CIO define values very similar to the book and then rank them. When a development decision had to be made we referred to the values listed on the walls of our cubes. This was a huge win for the development team and I found that when opinions cropped up, or action needed we could always resolve it based on these values.
As I recall they were:
Safety – Code must work and not impact existing production
Maintainable – Source should allow anyone to work on it
Code Reuse – Business logic should be seen in only one location
Innovation – Code must be thought through and creatively crafted
I have reflected on development for the last 17 years as to how teams are productive or not. In many cases those teams that produce great applications have an alignment of their values. They see the bigger picture and have a leader who is consistently adheres to their value system. For those teams that are not producing, look into the values of each team member and take inventory of what each team member thinks. I suspect that if a quiz ranking a list might be helpful.
Regardless of my lists above and my opinions, I truly find it rewarding to understand why developers think the way they do. In our minds, it is logical, we value one idea over another because we have a value system. Please take the time to assess what value system is in your current employer and what value system you have. The best developers in my mind are ones who can adapt to their employers values. Dan Woodruff Team Lead and Senior Software Engineer Software Technology Group References:
Practical Guidelines and Best Practices for Microsoft® Visual Basic® and Visual C#® Developers (Developer Reference).
Software Technology Group (STG) is a software-consulting firm located in Downtown Salt Lake City, Utah. STG is a privately owned and operated company, which enables us to make decisions based on the needs of our employees and our clients, not those of shareholders. Founded 20 years ago, STG has maintained the goal to provide work/life balance along with training to help employees gain the skills they want to further their careers. STG’s core expertise include Java development, .NET development, scripted development, user experience design, mobile development and quality assurance.
Why are we different from other consulting companies?
Our consultants are full-time employees with Salary and Benefits! We always put our employees first. We want to make sure your career is headed in the direction you are most passionate and excited about!
The dreaded “BENCH”
A common fear among developers with consulting is “THE BENCH” DUN DUN DUNNN. No one wants to have a scary gap in their employment without benefits or income. STG did not like this part of consulting we wanted our employees to feel safe and secure in their jobs with us. The founder of our company Jeff Soderberg decided to change the game! Software Technology Group’s consultants are FULL-TIME employees with salary and benefits. Once your project is up, we provide the opportunity to come work on site in our Dev Center. During your time in the Dev Center, you are encouraged to work on your personal development, volunteer to help non-profit companies with their project needs, and work on expanding your skill-set. Also, we provide you with a PluralSight license so you can take online courses. We pay for any job-related certifications you would like to get as well as the study materials that are needed. A bonus is awarded for every certification you take and pass. We also have fantastic practice managers and leads who are here to mentor you. They provide projects for you to work on, allowing you to exercise and develop your skill-sets. You get the awesome perks of working on new projects and with new technologies on different teams in a consulting role, along with the benefits of a full-time position! You never have to worry about being on the Bench again! Instead, you get to turn that time into investing in your career.
Mentors
STG provides our employees with mentors, and development plan to cultivate their skills and achieve their career goals. We also provide ongoing career development and paid training for all employees. Our flexible schedules and open environment help facilitate growth and satisfaction. Those and many other reasons are why STG has been recognized as one of Utah’s Best Places to Work and we also recently won the “When Work Works Award.”
We put our employees first!
What are your career passions? Where do you want your career to go? Which skills do you want to improve? What types of projects interest you? Who do you want as a mentor? What kind of culture environment do you enjoy? What is important to you? These are a few of the many thought-provoking questions we ask our consultants. Software Technology Group wants to make sure you’re working in an environment that’s best suited for you. If you’re excited to get up for work in the morning, we know we are doing our job correctly!
No Debt
Have you worked for a financially unstable company? Have you ever been affected by a company layoff due to company insolvency? YIKES! Not fun. Software Technology Group has been a profitable company for 20 years and 100% debt free for 12 years.
Perks
Gym usage reimbursement
Certification reimbursement
Bonus for every certification you pass.
Paid overtime
PTO (cash out PTO at any time)
To apply please send your resume to jobs@stgconsulting.com
Software Technology is an Equal Opportunity Employer; no applicant for employment with Software Technology Group shall be subjected to discrimination because of race, color, sex, national origin, religion, disability, age, reprisal for engaging in anti-discrimination activities, protected genetic information, sexual orientation or parental status.
Author: Chris Lake One of the ways that STG likes to partner with its clients is to sit in as an observer when we have a candidate interview. We don’t interfere with anything said, but being in the room helps us observe and see both how the candidate does and what needs our client has that perhaps we had not thought to consider in our candidate search. It really is a great opportunity. One of the results of sitting in so many interviews is that I get to see many different interview styles and situations. I’ve seen some candidates just rock the interview and I’ve seen others blow it so badly that it’s almost physically painful to sit and watch them struggle. Although we never share specific interview questions from clients, I’ve noticed a few specific suggestions and ideas that I think every person going through a technical interview should be aware of. PAY ATTENTION to the items below—they may just land you that dream job! There’s no way I could cover everything in a quick blog, but here are just a couple of the big ones.
First impression
It’s often said that you never get a second chance to make a first impression. I’ve heard that it takes typically less than 7 seconds for that first impression to be formed. A lot can go into making those 7 seconds count:
Give yourself enough time so that you will be onsite and checked in 5 minutes early. Don’t show up 15 minutes early as that throws everyone off schedule. Still, that’s better than showing up 2 minutes late. When you’re late, you’re stressed and not only does it make you look unreliable, but you will not be calm and collected when they first meet you (plus you may have some wicked sweat stains and that’s just gross).
Make sure you dress appropriately. As a general rule, be one step dressier than the person who will be interviewing you. If the team is in jeans and t-shirts, come in dockers and a nice golf shirt. If they are in slacks and dress shirts, wear a tie or a sport coat. If you don’t know the dress code, stop by the office the day before to see how people are dressing (or simply call and ask). Dressing up for an interview shows that you take the opportunity seriously and everyone appreciates that.
A firm handshake while making eye contact shows confidence. Shaking hands is something we do every day, but how good are you at it? Have you ever practiced?
Ask for a business card from the interviewer. It will help you remember their name and you’ll need it later on anyway (ooh, a cliff hanger!)
White boarding
Often in a technical interview, they will ask you to go up to a white board and write out a solution to a technical problem. Even if you’ve seen this other people do this a hundred times, when it’s you standing up, it’s almost guaranteed that the pressure of the moment will cause a strange effect of having your intelligence shut off as soon as your knees lock and you lift the marker to write. It happens to the best of them (and that includes you!) Here’s a couple tips to keep in mind:
Remember that the purpose of the question is primarily to learn how you think and approach a problem. The actual task is usually totally irrelevant. As you work, think out loud and explain what you are doing and why you are doing it. If you ever get stuck, step back and explain to the interviewers why you are stuck and the options you are considering. They would much rather hear your thought process and have a half-baked solution than see a “perfect” answer up on the board with you not saying anything.
No one cares about your syntax. Anyone who does in that situation is probably not someone you want to work with anyway. You have no IDE on a white board. Get over it. Pseuo code is your friend and is all you need. If you’re hung up on whether it’s a { or a [ or a ( you will probably miss the deep thinking that will actually be needed to solve the problem.
The most important question:
At the end of almost every interview, you will be asked “So, what questions do you have for us?” Before the interview, you should make a list of questions that you’d like to ask that don’t make you sound like an idiot or someone who doesn’t care enough to ask a real question. Here are some common good topics:
What is the team environment like?
What is the development process of the team (Agile, Scrum, 2-week sprints, etc)?
What is the technology stack that I will be working on and perhaps what new technologies will I be able to learn here?
HOWEVER, the most important question you NEED TO ASK is some variation of the following:
Mr./Ms Interviewer I am extremely interested in working in this role/project, do you have any reservations or concerns regarding my background that I can address?
This question is of utmost importance because if the interviewers have any concerns regarding your experience and you cannot overcome their concerns, you probably will not have a chance of landing this job or being asked back for a second interview. This is a great question and has often turned a negative interview into a positive one—Sell yourself. It’s amazing how you can clear up misperceptions that otherwise would have sunk you as a candidate.
Follow up
Once the interview is over, make sure you thank them for their time, shake their hands like you mean it and walk away like a professional. You will have just been through an experience together and you may feel an urge to confess some deeply personal thing to your new found buddy as you walk out together. Please don’t. Unless they ask about it, now is not the time to start sharing about your personal life and what crazy plans you have for the weekend. You’ve aced the interview. Don’t leave them with a question mark in their minds. Make sure you follow up within 24 hours with a quick note (email is fine) thanking them for the opportunity and reiterating why you feel you are a great fit for the spot. Since you already have their card from the beginning of the interview, it should just take a few minutes of your time. This one thing can help set you apart from the pile of others they talk to and help you be remembered. There is nothing here that is rocket science and nothing you’ve probably not heard before. However, hopefully these few tips will help you turn your next interview into your next position! Author: Chris Lake
Author: Geoffrey Sagers I recently had the opportunity to attend the RootsTech Genealogy conference held in Salt Lake City, Utah. One of the sessions I attended was the Innovator Showdown. It was the final six of numerous of entries to “show off” how technology can improve family history — the world’s largest org chart. Most people think of family history as old books in dusty libraries, cemeteries, huge stacks of papers, and the county clerk’s office. However, the finalists included medical history tracking, hardware-software combination using iPhone technology, data visualization, and digital record-keeping. Each finalist shared the technology they used for their platform and some common threads emerged.
TapGenes uses software to map likelihood of certain genetic traits that could affect other family members such as cancers, chromosomal diseases and heart/stroke risks. This information can then be used by families to create a specific roadmap for testing when they go in for general physicals and diseases could be caught much sooner.
Software technologies used: facebook api, gmail api, family search api.
AncestorCloud created a portal to allow genealogy-related services on-demand. Want someone to take a picture of a headstone in a far-away cemetery? Need a tour guide when you visit the small little town where great-grandma was born? These and so much more are available when using their service, and users could sign up to be a provider as well to earn some money.
JRNL is an online journal-keeping application. Using social and personal media, you can keep a running journal of your daily life. You become your own curator of the museum of your life, marking facebook postings as noteable, removing others completely. They also provided the ability to print to a book, so you have a hard copy for yourself or children/grandchildren.
Studio by Legacy Republic was a scanner built specifically for photo albums where often the size or deterioration of physical medium represents a risk to the quality of reproduction available. Using a system not much bigger than a suitcase, a user can quickly photograph in high resolution, hundreds of photos in an album to pass along to future generations in a non-degrading quality.
The History Project came from the founder’s desire to share experiences with others using historical context. His father had died of cancer when the founder was just 13 and he wanted to “walk in his shoes.” It started by him wanting to pass his experience visiting where his father grew up and spent his time to his children and siblings. Using a mixture of photographs, news articles, videos and other media, he was able to create a rich experience for those who were unable to take the trip with him. He founded The History Project to create the opportunity for others to create these same personal experiences for their loved ones.
Software technologies used: laravel/php, facebook and instagram api, google api, vimeo, amazon web services
Twile was based on data visualization rather than facts/figures. Specifically a user could upload a file of their family history data (GEDCOM), and create a timeline of family member events. Birth, death, christening, etc. and then add to it your own photos and eventually audio and video. This made viewing this same information much more enjoyable and sometimes-hidden events much more obvious.
Bubbling to the top of the most used technologies were javascript and javascript frameworks such as node, backbone, and react. Also popular were both sql and nosql databases. The judges chose TapGenes as the winner, but Twile and Studio also received innovation awards. What was surprising is the number of companies with less than 10 employees that were making enterprise-level applications. This proved to me that less can be more, and throwing more money at a problem doesn’t necessarily solve it, but more technology and people often can. Many problems that used to be insurmountable are now attainable by people from all walks of life.
If you’re interested in learning how Software Technology Group can help your team with development projects, contact us. Our core expertise includes java development, .NET development, scripted development, Ux design, mobile development, and quality assurance. Author: Geoffrey Sagers
Author: Patricia Johnson
Part 1: The Code That Time Forgot
Like me, you probably expect that html code is going to display virtually the same in every browser, with a few known exceptions. There are small foibles in rendering between the assorted web browsers, but with every update, those differences become fewer and fewer, and the CSS “hacks” for these issues are well-known and widely used. Until the first time you’re assigned to program an HTML email. Oh, it looks easy enough, and often it doesn’t even have to be responsive, so you quickly code the email, checking in all the browsers for inconsistencies, and then send it off the test email. And then it explodes in your face. What was beautiful HTML code in your web browser has arrived in your inbox looking like something straight out of Geocities, circa 1996. What happened?! Email clients seem to have a free pass on W3C standards compliance and implementation To some degree, every existing email client has varying, but never complete, W3C standards compliance in their html rendering engine. Some are pretty close (Apple and iOS) and some seem to be thumbing their nose at the W3C and making rude hand gestures at developers everywhere (Outlook 2011 uses IE as its html rendering engine, but every other version, including 2016, uses MS Word). Because of this, developers often flail about virtually, and sometimes actually, when coding their first emails. None of the things you can take for granted when coding a webpage seem to be true, when it comes to programming for email. And since there’s no way of knowing until after the fact which email client your recipient is using, you have to code your email for the least common denominator. Just pretend it’s 1999, and you should be fine. First off, you can stop making that face. There’s no getting around it. I know, if your web portfolio was written like this, you could expect not just to not get the job, but to perhaps be laughed out of the interviewer’s office, and maybe even hear some four-letter words for having wasted their time, on the way out. But this isn’t a webpage, it’s an email, so just grit your teeth and bear it. Say goodbye to stylesheets Due to potential security issues, emails will not allow you to reference an external stylesheet, no matter where you host it. And because Gmail does not support <style> tags, in either the head or body of an email, every bit of CSS you write for the desktop view must be an inline style. Fortunately, there are several free tools available online to help with your inline style needs. Campaign Monitor’s CSS Inliner or Zurb’s Ink allow you to write a <style> tag in the head of your html document – when the time comes to deliver the email, you will copy and paste your code into their tool, which will then add the CSS not found inside media queries (more on responsive emails in a later post) to your html code as inline styles. Just a tip – I would save the version for delivery out as a separate file. It makes it a lot easier to tweak your code, should you find any bugs (and you will) after that first test send. Say Hello to Deprecated, Ugly, Tangled Code While you can use modern HTML and CSS for much of your email, there are a few common elements you won’t want to use, either because it will make adding responsive code easier later if you don’t, or because it simply is not supported in one or more of the major email clients. The first major difference is that divs won’t work for layout anymore. You must go back to using tables to create your grid. Don’t forget to add “cellspacing=’0’ cellpadding=’0’” to every <table> declaration, or Outlook and its incarnations (Hotmail, Outlook.com) are going to add a seemingly random amount of padding and space to your table elements, throwing your design off in a rather spectacular manner. You also want to declare your dimensions in the “td” tags, but not with css – use “width=x” and “height=x”, without “px” after the number. This both prevents box-model issues and makes it much easier to change the dimensions in your media queries, should you use them later. And speaking of Outlook, it doesn’t recognize the “padding” property for p, div and a tags, so you’re going to have to use nested tables with padding added to the <td> tags for your white space needs. To make this an even bigger slap in the face, Outlook.com doesn’t support “margin” at all, so it’s more nested tables to the rescue. Outlook also doesn’t recognize images as block level elements by default, so every <img> must have “display: block” in its style tag, as well as “border=’0’” in its attributes if it’s part of a link, in order to get them to sit where you want them, and not have big blue borders. “Float” is no longer an option, which is why you need tables for columns. If you need something to move to the left or right of something – for example, an image, placed to the right of a paragraph- you’ll need to use “align=’right’” in the image tag. JavaScript is universally stripped from emails at the receiving end, in order to prevent virus transmission, and for the same reason, background images are also inaccessible. So if your designer provides you with a lovely photograph with copy on top, the whole thing will have to be cut as an image, text and all. This is alright for a header banner, but occasionally you get a client who wants to be able to edit their headers (if you’re programming a branded template, for example), so you’ll have to send the design back to the drawing board, so to speak. “Live text”, as it were, needs a solid colored background behind it – usually that’s white, but any other solid color that may be specified with CSS can also be used. Thanks to Outlook (again), you will have to re-declare your font statements – font-family, color, font-size, line-height – every time you add another nested table – it will not inherit past a “table” tag. If you are using one of the inlining tools I linked to previously, you may want to add those declarations to the td, p and a elements, to be sure they are always correct. Otherwise Outlook will pretend you’ve never mentioned font styles, and will serve up times new roman, in black, at the default font-size for the recipients’ version of the client. Additionally, you need to declare font-size and color in every <h> element, now that Outlook.com wants to apply its own formatting to headlines. If you don’t want your h1 tags to be green (I’m not exaggerating – Outlook.com makes all h1 tags green by default), you need to specify what color they should be, even if the color is already declared elsewhere (for example, in the surrounding td tag). Email Best Practices Your email should be roughly 600px wide at its maximum resolution, responsive or not. This prevents side-scrolling in most desktop email clients, and also prevents too much white-space around the email in the reading pane. Do use white space appropriately. Huge blocks of text are hard to read – remember to break up paragraphs with a little spacing in between, and have some padding between columns, if you used them. Do use a web-safe font – you can’t call to a font server in an email, just like you can’t call out to an external style sheet. Georgia and Verdana are easy on the eyes, with Arial and Helvetica a close second. Always add a fallback to your font-family declarations – “Verdana, Arial, Helvetica, Sans-Serif” will make sure no one accidentally gets Times New Roman, even if they don’t have Verdana, Arial or Helvetica. It will save the readers’ eyes, and your design aesthetics. The only exception to the above rule is if you’re programming an email intended solely for internal corporate use, and the font in question is their corporate brand font – it’s safe to assume that everyone in the company will have that font installed on their work computer. Still provide the fallback fonts, because more than half those people are likely to open that email on a personal mobile device, which may not be able to access that font, at one time or another. Keep font sizes at 12px or larger if at all possible. Not only are smaller fonts hard to read on a mobile device, but the Apple email clients will “fix that” for you by blowing up tiny fonts to a larger, more mobile-friendly size – but will not adjust the line-height, so your text may be squished or even have overlapping lines. Optimize your images for file size, and if you’re the designer, try to use no more than 6 per email. Images increase load time on emails, and studies have shown that even increasing load time by a few seconds can dramatically increase the rate of deleting said email before it ever opens, especially on mobile devices. Gmail and some of the other email clients count the number of images in your email, and may flag your email as potential spam if it has more than half a dozen images. Always supply alt tags for your images, for use by screen readers, and hard code the dimensions using the width and height attributes of the img tag, so your layout isn’t askew if the email loads with images disabled by default. Those descriptive alt tags will help get your message across as you intended it, even if the viewer never downloads the images. Tinypng.org offers a free, web-based png and jpeg compression tool that can cut your file sizes by an average of 30 – 75% or more, with no visible loss of quality. And lastly… Remember that unless you’re creating an OFT (Outlook Format Template) or EML file only as the deliverable, your images are not embedded in your file, and the images must be hosted online somewhere, with absolute paths in the html to reference them. Email testing services like Email On Acid or Litmus will save you time and prevent frustration-induced baldness. These services allow you to send a test email to a single email address, upload a zipped file with your html and images, or copy and paste your html code (or all 3), and then shows you a screenshot of how your email looks on arrival in almost every email client conceivable. This is especially valuable if you’re programming responsive emails, but it is always good to see how your email holds up on Apple Mail vs an Android phone vs Gmail in Chrome vs Outlook 2011, whether it is responsive or not. You can quickly check and recheck for any client specific errors in your email with these services, so that the email files you deliver are bulletproof, whatever their format – without having to own an extensive testing lab of computers. There are numerous quality resources online for learning more about the pitfalls of programming emails. The blogs at Campaign Monitor, EmailOnAcid, Litmus, and Mail Chimp are full of extremely helpful information when it comes to troubleshooting your particular email issue. Author: Patricia Johnson
By Quinn Heiner In this article (which has no relation to Covey’s famous book, The 7 Habits of Highly Effective People, except maybe the number seven), we will take a different approach in our discussion of good habits by first pointing out the bad ones. By going from ineffective to effective, we will essentially discover what really separates good engineers from the exceptional. #1: Don’t ever try to re-balance the time-scope-quality triangle. If you do, be sure to never articulate this tradeoff to the customer. More importantly, be sure to ignore Murphy’s three laws: 1) everything takes longer than you think, 2) nothing is as easy as it looks, and 3) if something can go wrong, it will. By doing this, you’ll ensure that a product will be delivered late, have way too many features than originally agreed upon, and be full of bugs (not to mention way over budget). In addition, the customer (who fortunately has a great sense of humor) will have a good laugh and you’ll both be on your merry way to the next project. But seriously. Although this triangle sometimes autocorrects by force, far too many engineers think that this triangle is the PM’s problem (project or product manager). Honestly, it should be both your problems. You as a developer are closer to the product’s internals than anyone else, and it is your responsibility to regularly communicate the current state of the triangle to your managers and recommend re-balancing strategies. Certainly, the biggest problem with analyzing this triangle is that managers tend to use the wrong data to assess progress. That is, they only use timeline and budget as their indicators of progress, when they ought to be incorporating user stories and user acceptance tests as a better indicator. To summarize, people in charge tend to view the time-scope-quality triangle as more of a time-scope-resources triangle, when resources != quality. In reality, not all resources are created equal, and so often times it’s four variables you should take into account, not three: A great article on a shirky.com web blog talked about why healthcare.gov failed and applied it to I.T. projects in general. A quote from it that I really liked, “If I had to design a litmus test…[for managing I.T. projects, and we’ll talk about litmus tests more in habit 4]…I would look for just one signal: Can anyone with authority over a new project articulate the tradeoff between features, quality, and time?”
“When a project cannot meet all three goals—a situation Healthcare.gov was clearly in—something will give. If you want certain features at a certain level of quality, you’d better be able to move the deadline. If you want overall quality by a certain deadline, you’d better be able to simplify, delay, or drop features. And if you have a fixed feature list and deadline, quality will suffer.” The most common scenario in my experience is scope creep with decreasing time–therefore quality has to suffer, or you have to suffer putting in crazy hours to meet a deadline. It doesn’t have to be this way. Sometimes we have to learn to say “no” even if something is feasible, even reasonable. Other times, we have to stretch ourselves and say “yes” even if we know it may take some effort. Question for discussion: What are some strategies or tactics you’ve employed to keep this triangle balanced and happy? #2: Only choose battles you will lose. Time isn’t precious, and so if you know you’re going up against “the man”, or a brick wall of politics, or stubborn customers, keep fighting until you finally lose. Always try to be the martyr, because nothing feels better than telling someone “I told you so! I warned you about this!” afterward. Speaking of battles…why even start one? Just code a bunch of stuff that affects a bunch of other stuff and do not tell anyone. But seriously. Don’t get me wrong on this, you are a consultant and should be actively involved in the decision-making process, and as such should voice your opinion in a professional way. However, you should always choose your battles wisely–only ones that are within your sphere of influence. Doug Turnure has a great Pluralsight course about how to have a better career in software. In it he talks about the need to avoid being a diva by always taking glamorous stands on things. Don’t ever be that guy in a meeting where everybody rolls their eyes as you go off on soapbox after soapbox about things. Worse yet, how would you feel if at the next meeting, you’re not invited because people think you impede progress by arguing and being confrontational on just about every issue? You’re allowed to disagree on issues, but choose your battles wisely, and accept compromise where it makes sense, even if you don’t agree with the outcome. Every company has politics. Do not become too immersed in it, because it almost never ends well. Never mix politics with software development. When we talk about battles, we’re really talking about two kinds:
stakeholders vs. developers. This is usually a battle between the “customer is always right” mentality and the “I as the developer know what’s best for you” mentality.
developer vs. developer. Often times, devs will disagree heavily on architecture decisions, resulting in implementation battles. Or worse, a developer will insist that everyone conform to doing things their way. Software engineers are very opinionated individuals, and some just love a good intellectual battle over ideas on how to solve problems. This is good in some situations. Other times it can mark the slow, painful death of a project.
Questions for discussion: How can we help resolve the “customer is always right” versus the “I as the developer know what’s best for you” battle? How do we resolve implementation battles between developers? How should we balance “rough consensus and working code” with “always doing it someone else’s way? #3: Only strive for 2 out of 3 on the Golden Trifecta for a Model Employee The bottom line is that 2 out of 3 ain’t bad! In other words:
If you’re really smart and able to deliver good results on time, then you’re allowed to be a jerk.
If you’re a super nice guy and able to make people laugh, and you deliver good results, then don’t worry about deadlines because doggonit – people like you and will give you all the time you need.
If you’re a super nice guy and people just adore your personality, and you’re able to code 60 WPM so you get things done quickly, then don’t worry if your deliverables are half-as(s|k)ed or not adding value.
Don’t worry about being a team player that goes against the grain. “This is how I do it, and so should you – it’s my way or the highway” attitude should prevail. It’s better to be a liability than an asset, because adding value to a project is overrated. There is no “I” in team! And finally, when it comes to results, you’re not about solving the problem quickly and effectively. Take your time, since after all, you’re a two-thirds kind of a guy because at least you’re nice. But seriously. Neil Gaiman in a famous address to the University of Arts Class of 2012 talked about what I’m calling the “Golden Trifecta for a Model Employee”, that is that you delivery high quality work, on time, and are a good team player (i.e. easy to get along with). Almost everything you look for in a good employee boils down to these three components. Most good employees are two out of the three. Great employees strive for all three. Regarding being a team player, always remember that negativity breeds more negativity. As Turnure put it, “You tend to see only what you’re looking for. If you actively look for negative things, you’ll find them.” Question for discussion: What is a great way to find out if a prospective employee will meet all three demands of the trifecta? #4: Don’t ever adapt as technology changes – stick to what you know! You should never have to learn or relearn something. You should never have to unlearn something. And once you’re considered senior, you should never have to learn something new–it’s all about the comfort zone! Be a jack-of-all-trades and a master of none. When it comes to all technologies, it’s best to apply a litmus test (i.e. accept/reject it based off a single factor). And above all, always be partial to or show spite for a particular language, tool, or technology. But seriously. A senior developer once told me something that always stuck with me: “The biggest impediment to software engineers is being set in their ways.” Often times, it’s up to you to determine how to implement a solution and what technologies to use; however, more often than not, usually a client has an established technology stack that you have to adapt to. Doug Turnure in his Pluralsight course about having a better career in software defined three things related to this that hurts people in their careers when it comes to their expertise, and they are: 1) picking a fringe technology, 2) clinging to a fading technology, and 3) holding an emotional attachment to a technology. “The essence of marketability is to be good at what other people are using.” Good way to know what’s in demand? One suggestion is to look at conference topics, or see what search terms are popular on job boards. Consulting companies are also experts at knowing what’s in demand, since they work with multiple clients in multiple industries. Avoid only liking what you use and not liking what you don’t use. The reverse is also true. In addition, software engineers can be very opinionated people, and will fight to the death (religiously at times) for their favorite language, tool, or technology, rather than taking the time and effort to carefully weigh the advantages/disadvantages of each technology and making informed decisions. In the end, if you want a successful career in technology, you have to define a continual learning plan in order to adapt and progress, especially since technology changes so rapidly. This includes setting SMART goals (specific, measurable, attainable, realistic, timeline), which may include items such as participation in code challenges, brown bags at work, certification exams, conference attendance, books, and other training resources.
Question for discussion: How do you adapt to changing technologies, both personally and as an organization? #5: Be as unapproachable as possible to devs [who know less than you about stuff] Patience is least important, so stop trying to explain a concept if they don’t understand it the first time. And there’s certainly no need to be teachable. You’re always right, because most people know less than you about stuff. At the very least be condescending so that the developer knows that they’re not worthy of your time and expertise. But seriously. As a software engineer, you are guaranteed to have to be a mentor at some point in your career, and the greatest software engineers are also the greatest mentors. Although knowledge acquisition can take months or years depending on the complexity of the technology, sometimes teaching what you’ve learned to someone else can save both of you a lot of headache down the road, rather than forcing everyone to take your same learning path. It’s tempting to just want to do everything yourself, or just take over someone’s keyboard when they have a coding question. Most often, junior developers just need a few nudges in the right direction, and then they can start to teach themselves. Others may need a bit more hand-holding at first then others. In general, it depends on the person, and you’ll have to take a different, more balanced approach in each situation for each person. If someone just never seems to be progressing regardless of how many ways you try to help, then this could be a sign of deeper issues. In general, the 30-minute rule is a good starting point, which is that if a developer is still struggling for 30 minutes or more after researching to try and find a solution to a problem, then offer to help. In a previous client, I had worked under a senior dev that had trained all of us junior devs so well to be self-sufficient that “he almost wasn’t needed anymore”. But is this ever the case? Do senior developers worry that by training others to do everything they do that they’re somehow progressing toward not being needed anymore? This is a myth in the industry when it comes to job security. The bottom line is, if you can get a team under you working well enough, your ROI will be so high that it will create a win-win situation. You add a ton of value to the company, your burden gets lighter, and then others can recommend you without reservation for higher-stake roles in the future. And please, don’t be condescending. Nothing shatters a fragile developer more than when you belittle them or roll your eyes to others as soon as they leave, as if they aren’t even worthy of your time and expertise. Question for discussion: How do you best deal with other developers that are constantly asking for your help? #6: Assume everything, especially when you think it’s common sense For most assumptions, you don’t need to get a green light from customers beforehand. For the assumptions that do require a green light beforehand, however, just do what you think is best rather than what the customer is actually asking for, because you know better. It’s also important to always talk before you listen. Be opinionated! Never seek to understand the customer’s needs. Never engage in reflective listening. And whatever you do, forget the Platinum Rule (treating others the way they want to be treated) – it’s overrated. But seriously. This habit comes down to setting requirements that are well understood by all. Always restate to the customer what you’re planning on in a language they can understand–getting buyoff earlier saves you a ton of heartache down the road. So many customers hate being bogged down with the technical details of a requirement, and often will tune you out when you start talking about them. Every implementation detail doesn’t necessarily need to be discussed, but the goals of the implementation do. Explain the strategy to the customer, not the tactics. Get your PM’s (both project and product) involved in what you’re trying to accomplish at each sprint, even if you have to by force at times. Far too many managers use the “truck-order-delivery” mentality or some form of the waterfall approach when it comes to software deliverables, and this can lead to disastrous results. In the blog article referenced above from shirky.com, it mentions that “…the vision of technology as something you can buy according to a plan, then have delivered as if it were coming off a truck, flatters and relieves managers who have no idea and no interest in how this stuff works….it’s also a breeding ground for disaster.” While it’s important for the highest management levels to see the bigger picture and have more of a bird’s eye view of the product, this should never be the case for project and product managers. Almost 99% of the time, you will be given incomplete requirements, or wishy-washy ones at best. A vision is not a plan, just as a high-fidelity screenshot with lots of pretty graphics is not a website. Form follows function. Often times you need to be the one to gather requirements, because either the customer doesn’t know exactly what they want, they don’t want to get bogged down with the details, or they simply don’t know the right questions to ask. Requirements should be based off a consensus between you and the customer, not one-sided. Embrace agile, embrace change without too much scope creep, and stop testing in production! Get feedback as early as possible in the chain. It’s also important to utilize different points of view when it comes to setting requirements. Not only end-users, but especially BA’s (if you’re lucky enough to have one), other subject-matter experts, as well as product managers should be a part of the process. Again–setting requirements should be a team effort. Software engineers are creators just as much as they are builders. Everyone needs to be involved in the decision-making process. Question for discussion: So many customers only want to evaluate things in a production-like environment. How can we help to ensure early feedback in a more agile way? How do you best establish requirements for a software project? #7: Try to over-complicate everything, because purism is king, and you’re awesome Prematurely optimize your code to adhere purely to every SOLID principle 100% of the time. Take a philosophical, over-idealistic approach, and always do stuff you just read in that really great academic book from a lifetime CS professor with no practical experience (no offense to CS professors). Never give in to balancing principle and practice. Make sure the next guy looking at your code (which will probably be you) will have to ask you for clarification on what the heck the code is supposed to be doing. This is because your code needs to make you look smart–so smart that if nobody can maintain it due to its complexity, you can smile knowing you’ve accomplished your goal. Hooray for job security! You’re the best now! But seriously. This all comes back to the KISS principle. Premature optimization is the root of all evil. In addition, I’d rather copy and paste some logic twice then having to spend hours architecting a more dynamic solution just to handle two use-cases. Give me a third use-case for a copy-paste, and only then will I seriously consider a more dynamic solution. It’s important to remember that it’s not really about the code, it’s about the business, and understanding why you’re being paid. You’re being paid to solve business problems, not just to write awesome code. Far too often I’ve seen grandiose ideas, plans, or visions that look great on paper, sound great in a team meeting or a lecture, but simply fail to live up to the hype in reality. Large, enterprise-level application code bases will always have technical debt and are never perfect. The reality is that every programmer comes to the codebase with a certain style of doing things, and with varying levels of experience. Rough consensus and working code is important. Don’t get me wrong, I’m all for SOLID principles and design patterns, but these should only be utilized where the objectives are clearly understood by all, and where it’s going to add the most value to the application. The biggest cost factors with purism is complexity (and sometimes performance), not to mention another developer only being able to understand what’s going on in the code after a lengthy architecture presentation by a senior dev. Try to balance principle and practice. Extremes to one end or the other are usually bad. Question for discussion: How do you best balance principle and practice when it comes to writing clean code? Bringing it all together In summary, the main thing that all of these habits have in common is ego–more specifically, learning to control your ego by checking it at the door. They also have to do with managing your own personal brand and being a balanced person. In managing your brand, as Turnure put it, it’s important to realize that you have a user interface. If people don’t know what you can do or how well you do it, how will they know to hire you? How are you marketable at that point? So go out there and be passionate about your work, your brand, and above all, don’t be grumpy.
Author: Quinn Heiner Imagine if your software company had an 18-month hiring process for all of its techs, and that your chances of actually getting hired were slim at best (really slim, as in maybe 5%). But no problem, let’s say you get the job! Great–now for your first project. You’ll be working with an all-volunteer team of about 460 developers on the next exciting app that’s going to influence the world for good and make people’s lives better. You have a week to complete the project, with two developer meetings lasting a total of about 5-10 hours. Oh, and at the end of the week, we’ll expect a demo that will be broadcast on live TV, as well as thousands of other cable, TV, and internet outlets worldwide. But no worries–this volunteer organization has been doing it for over 86 years, and although they’re not all programmers, they represent some of the most disciplined leaders in the world as the Mormon Tabernacle Choir. A recent Forbes article about the choir highlighted five leadership lessons and applied them directly to the business world, but as both a performer in the choir and a software engineer, I couldn’t help but try and apply these lessons to our field as well.
Embrace an engaging cause. You must be passionate about your work as a software engineer and take pride in the product you are creating. As the article points out, “”action without passion will not endure, nor will passion without action”. If someone were to ask you in an interview to talk about a recent project you worked on that you really enjoyed, would you be able to give them an honest answer? Although most of our work involves the less glamorous line-of-business applications (as opposed to thought-provoking algorithms or cool games), you should still strive to find self-fulfillment and purpose in your work. After all, isn’t forcing billions of transistors to obey your every command quite a satisfying feeling?
Insist on sky high standards. Unfortunately, most software projects are just about solving business problems as quickly and cheaply as possible. Far too often, project and product managers view the time-scope-quality triangle as more of a time-scope-resources triangle, when in reality resources != quality. Or slightly better, high standards are discussed but never enforced or followed up on in any measurable way. One huge advantage (and irony) of sky high standards is that the more they are implemented, the more freedom you can achieve. Why do you think Netflix’s employees have unlimited vacation time, no annual performance reviews, and ridiculously high salaries? It’s because their standards are so high that they can treat their employees as “fully formed adults”.
Be of one voice. Okay, so you have a passion to write excellent software and will settle for nothing less than the highest standard, but what about the rest of the team? Are you all on the same page? Software engineers are incredibly opinionated and often times want to do things their own way. Instead of checking their egos at the door, they sometimes feel the need to go against the grain, regardless of if everyone’s on board, because they think they know better. Avoid the need to be a diva and take a glamorous stand on everything. Yes, you will have disagreements, and unification is never easy or perfectly implemented, but clear, concise, and constant communication of mostly agreed upon standards can achieve spectacular results far beyond any one individual’s efforts. Never write code for code’s sake or to show off how awesome you are. Your code is intended for the humans that will be maintaining it.
Think globally, act locally. It’s always important to stay focused on the big picture of your product and implement the vision; however, lifting where you stand and simplifying the complexities of the problems within your own sphere of influence are of equal importance. Always balance long-term and short-term goals. One is all strategy and no tactics. The other is all tactics and no strategy. Too often developers focus on one end of the spectrum and not the other. I like to refer to these as the “dreamers” and the “short-term doers”, respectively. In other words, there are people who love to dream up solutions and complicated architecture all day and forget they actually need to produce working code and release a product in a timely manner. Conversely, there are people who just write narrow-minded, “dirty”, code that isn’t extensible or cohesive, all because they want to meet a specific requirement (and thus fail to look at the larger picture).
Adapt or die. Some of the most ineffective software engineers on the planet are those who refuse to embrace changing technologies, or even worse, those who refuse to unlearn fading ones. Furthermore, one must avoid being the cynical programmer that only likes the technologies they’re not using, and hates the technologies that they are (the reverse is also true). There are 50 ways to solve a problem with technology, and 50 tools for each of those ways, all of which come with strengths and weaknesses. As an industry, we’re moving away from a one-size-fits-all product to opinionated software with lots and lots of third-party tools in between to speed up development, so pick what works well most of the time, study it, and get with the program (pun intended).
Author: Quinn Heiner
Author: Brett Child
As a programmer, sometime or another you will be needed to dig into a legacy system. Whether you’re making changes or maybe trying to rewrite it, you’ll need to understand what’s going on. One of the biggest problems with legacy systems is that there are few to no people who truly understand that system anymore. The original creators have more than likely moved on leaving you to interpret what variable ‘x’ is supposed to mean. As you can imagine it can be very time consuming dissecting a system that doesn’t follow modern coding conventions, but we need to understand that the code we write will also someday be a legacy system. Someone is going to inherit the system you are writing right now. So, the question is, are they going to curse you for it or thank you for passing on your knowledge?
Self-Documenting Code
One of the biggest things we can do as programmers is make sure our code describes itself. We can do this by careful naming conventions that describe what our intent is. A variable named ‘x’ gives no context or meaning, but variable ‘numberOfSandwhiches’ describes pretty well what is being stored. Self-documenting code, while verbose, is the best way to have your code describe what it is doing. It also goes hand in hand with refactoring, or rewriting a piece of logic without changing the contract. For example, lets say we have a code block like this:
sandwhich = new Sandwhich(bread, meat, lettuce, tomatoes);
numberOfSandwhiches++;
}
At first glance it may not be perfectly clear what’s going on with the large list of ingredients in the if statement. But, the idea of refactoring is to make the code easier to understand so we can make it a little clearer by writing it like this.
if(hunger > 0 && ingredientsAvailable()) {
sandwhich = new Sandwhich(bread, meat, lettuce, tomatoes);
numberOfSandwhiches++;
}
Hopefully the refactored code is easier to understand at a glance so that whenever future me, or whoever else is going to be looking at this in the future, can quickly understand the intent.
Comments
There is always a big debate about how many comments are appropriate. Some purists will say that if you need comments your code is not self-documenting enough and needs to be refactored. I prefer the practical approach. Leave comments if you need to, but make sure they actually communicate meaning and context. People in the future might not have access to the bug tracking tools you use today so comments like ‘// Fixed bug 43453’ are less than useful. But having said comments are okay, I feel I should also give a warning. If you find yourself leaving a lot of comments that could be a code smell and maybe some refactoring would do your code some good. While comments are useful, most of the code should describe itself.
Conclusion
To close I want to reiterate on the importance of passing your knowledge in your code. You may not realize how much you time you’ll be saving some future programmer by writing good documented code. To help us remember to do this I recommend using fear-driven development: Always code as if the next person to maintain your code is a homicidal maniac who knows where you live.
Author: Brett Child
Originally Published at http://www.bmchild.com/2015/01/passing-knowledge-with-code.html
Author: Quinn Heiner We’ve all heard the well-rehearsed arguments of being a full-time employee for a company versus independent contracting. With technology careers, this debate becomes even more relevant given the large number of both contracting and full-time positions available. There simply aren’t enough people to fill the demands of the industry, which for most software engineers, gives them the opportunity to choose. In the end it comes down to personal preference and circumstance, as there is no silver-bullet formula for choosing; however, does it always have to be a choice of just one or the other? Do hybrid business models exist out there that combine elements of both contracting and full-time employment? In this article, we will attempt to re-define the context of the debate by examining not only the pros and cons of the two schools of thought, but by also helping to clarify the various alternatives that combine elements of each. The 5 Pros of Independent Contracting
Compensation. Independent contractors usually enjoy a higher pay than their full-time counterparts, including straight-time overtime since you often bill hourly.
Skillset Growth. A huge plus with contracting is the ability to gain a more diverse skillset across different industries and experience a change of scenery often.
Office Politics (as in, less). With contracting, you’re almost always one-step removed from the daily woes of office politics and bureaucracy.
Flexibility. You often get to decide your hours and locations of work.
Being your own boss. This can be a big plus for self-motivated individuals who struggle with authority or feel that having a boss holds them back.
The 5 Cons of Independent Contracting
Benefits (as in, there are none). Not only do you not receive benefits, but no pay between contracts, and certainly no access to employee fringe benefits. Add that to other expenses such as FICA, vacation & holiday pay, self-financed 401(k), health coverage, etc. and pretty soon that higher pay differential dwindles pretty quickly.
Stability (as in, there is none). There’s always a sense of instability when you’re always having to look for your next gig after a contract ends. In addition, when a client needs to trim expenses, contractors are usually the first to go.
Corporate career growth (as in, there is none). Certainly going freelance means a less structured career development path. With little ability to climb the corporate ladder and take on new roles within an organization, you may find yourself stuck in a rut at times.
Camaraderie (as in, there is none). Independent contracting can get lonely at times with never being able to fully experience the sense of belonging to a team. Is your client’s full-time staff out of the office for that exciting offsite or end-of-project celebration? Chances are you won’t be celebrating with them. Who knows? Maybe you can go, assuming you don’t bill for the time, of course.
Domain Knowledge (as in, less). Especially in the case of short-term contracts, there just simply isn’t enough time to fully absorb business domain knowledge, since you’re always changing clients.
The 5 Pros of Full-Time Employment
Benefits. Full-time employment usually offers a full suite of great benefits, including group rates on health insurance, 401(k), fringe benefits, etc.
Stability. With the exception of start-ups, full-time employers offers much more stability than independent contracting.
Corporate career growth. With a more structured career development path within the organization, you have the ability to climb the corporate ladder and take on new roles.
Camaraderie: The value of associating with a great team cannot be overstated. Strong, genuine, relationships made at work certainly improve one’s overall well-being.
Domain Knowledge. With going full-time, you gain the ability to become very knowledgeable of the business domain for a particular company/industry.
The 5 Cons of Full-Time Employment
Compensation (as in, less). Although you can enjoy great benefits with a full-time employer, your pay is usually more fixed and is less that of an independent contractor.
Skillset growth (as in, less). You also have the potential to get pigeon-holed in your skillsets, with little ability to experience a change of scenery.
Office politics. Far too often, you can fall victim to the intricacies of office politics and bureaucracy.
Flexibility (as in, less). Most often you will be working a set schedule at a specific location.
Being your own boss (as in, you never are). With full-time employment, unless you’re at the top of the ladder, you will always have to report to somebody, whether you like it or not.
See a pattern yet? The pros of one type are the cons of the other. This simplified chart helps to summarize this concept:
Independent Contracting
Full-Time Employment
Compensation
Skillset Growth
Office Politics and Bureaucracy
Flexibility
Being Your Own Boss
Benefits
Stability
Corporate Career Growth
Camaraderie
Domain Knowledge
Introducing the Consulting Company Consulting companies (not to be confused with staffing companies) offer a hybrid model of the two types of employment by combining elements of each. Stable factors such as salary, benefits, etc. are guaranteed through them (similar to a full-time employee), but you actually perform your day-to-day work for the various clients that they do business with, similar to independent contracting. What makes this business model unique is that, in addition to having many of the pros of both independent contracting and full-time employment, consulting companies also possess an expert knowledge on the demands of the market and seek to mold their engineers into the type of people who can best meet that demand. Since their product and brand is people and not products, good consulting companies seek to offer a more structured career development path that can not only improve one’s marketability in the industry, but also accelerate it. Let’s examine the pros and cons listed above only in the context of a consulting company: Pros of the Hybrid Model
Compensation. Like independent contracting, you have the potential for higher pay, since clients are usually billed an hourly rate higher than their equivalent full-time salary.
Skillset growth. You also have the potential to quickly gain a more diverse skillset using marketable technologies across different industries, even more so at times than as an independent contractor.
Office politics (as in, less). Of course, having a consulting company sitting between you and the client removes you (one step, at least) from the politics and bureaucracy of a client.
Benefits. The consulting company provides you with stable benefits similar to that of a full-time employee.
Stability. With a consulting company, you never need to worry about where your next gig is going to be (since they do all the job hunting for you), plus you get stable employment with benefits and a guaranteed paycheck, just like a full-time employee would.
Camaraderie. With a decent sized, reputable consulting company, you will have access to a solid network of engineers with whom you can form meaningful relationships.
Flexibility. Although you are usually limited by the client’s needs, options such as telecommuting, flexible hours, etc. are usually available. Plus if you really aren’t enjoying your experience with a particular client, the consulting company can hopefully plan an exit strategy for you.
Additional Pros not Listed Above
Understanding of market trends. Consulting companies are best at understanding the needs of the market and how you can best fulfill those needs, since they deal with a large number of clients on a regular basis.
Forgetting all the logistics and paperwork. There’s no need to worry about all the logistics of actually starting work–you can just show up to a client and focus on what you do best – solving problems with technology. You don’t need to go through all the ceremony, hoops, and paperwork of actually getting hired or placed.
Structured career development. Since good consulting companies invest heavily in keeping their consultants marketable, they usually will offer a more structured and focused career development path. Most important, with how fast technology changes, they tend to be ahead of the pack in keeping everyone up-to-date.
Stronger contract negotiation. A consulting company usually has more bargaining power on billing rates and other contract details than an individual would, since this is the consulting company’s bread and butter.
An agent is on your team. Similar to the benefits of having an agent in other industries, you essentially have access to an individual who is willing to go to bat for you and do everything in their power to make sure you’re well taken care of. By balancing your needs with the needs of the client and the needs of the consulting company, your manager can help to ensure a win-win-win situation among the three parties.
Cons of the Hybrid Model Although consulting companies try and combine the benefits of both independent contracting and full-time employment, there are cons to this model:
Corporate career growth (as in, less). Since consulting fees are the main source of revenue for a consulting company, you will be less likely to climb the corporate ladder and take on new roles. Unless an activity is billable, you probably won’t be doing it often.
Domain Knowledge (as in, less). Like independent contracting, there’s usually not enough time to fully absorb business domain knowledge, since you will be changing clients often.
Being your own boss (as in, you never are). Not only will you be answering to your client, but you will also be regularly reporting to your manager in the consulting company. This can be a dent to the free-spirit nature that is a common attribute among independent contractors.
Additional Cons not Listed Above
Client Choice (as in, less). Although you can help to bring in new clients to a consulting company, you will often have less control over which clients you will actually end up contracting with. If the consulting company says yes to a higher bidder that isn’t your first choice, you may be out of luck.
Sharing the pie. Perhaps the most common argument against working for a consulting company is having to give up a piece of your billing rate to help cover overhead costs for the administrative staff, management, benefits, etc. that the organization incurs. This is a sacrifice you will have to make when working for a consulting company.
To help drive home these concepts, let’s look at a ranking chart (1-3 stars, with no ties allowed) among the three models:
Independent Contracting
Full-Time Employment
Hybrid Model (Consulting Company)
Compensation
Skillset Growth
Office Politics and Bureaucracy
Flexibility
Being Your Own Boss
Benefits
Stability
Corporate Career Growth
Camaraderie
Domain Knowledge
Of course, there is a disclaimer to all of this, and that is that not all companies are created equal. Some of the pros and cons listed above may be quite different depending on the overall strength and reputation of the company or clients you choose. Your best bet is to crunch the numbers (not just the salary, but the total compensation package), carefully weigh the pros and cons of each, do your own research on every company/client you can, and finally make an informed decision based on your own personal circumstances. Author: Quinn Heiner
Author: Eduardo Flores This is a simple example of how to achieve the same simple GET call with (the “old”) NSURLConnection and the new NSURLSession. This project is now on Swift! (so 50% less code, and 200% more “Why??”s) This blog post is almost identical to the previous one I made on objective-c (link) but obviously written on swift. The logic and approach are the same. The final result This a simple app with 2 buttons, 1 label and 1 UIImageView.
When you tap the “NSURLConnection” the app downloads a picture of a car using NSURLConnection. When you tap the “NSURLSession” the app downloads a picture of a car using NSURLSession. The label also updates to tell you which one you’re using. NSURLConnection Here’s the code to get this GET call using NSURLConnection: @IBAction func button_useNSURLConnection(sender:AnyObject) { let url = NSURL(string: URL_CAR_1) var request =NSMutableURLRequest(URL: url!) request.HTTPMethod=“GET” dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)) { var responseError:NSError? var data =NSURLConnection.sendSynchronousRequest(request, returningResponse:AutoreleasingUnsafeMutablePointer<NSURLResponse?>(), error:&responseError) dispatch_async(dispatch_get_main_queue(), { self.label_status.text =“Selected NSURLConnection” self.imageView.image =UIImage(data: data!) }) } }//end button_useNSURLConnection
I decided to make the NSURLConnection a Synchronous request so it can return a value (Asynchronous would just give me a value in a easier way, but that’s not fun), but this means it runs in the main thread.
We get a URL from a String (a constant I have defined in my class)
We make a MutableURLRequest with the url of step 1
Set the HTTP method of the request to GET, although this isn’t really needed but its good for the tutorial to show how to set the HTTPMethod
Created and used a new GCD queue to make the actual NSURLConnection in a different/background thread
Once the background thread is completed, I’m calling the main GCD queue (main/UI thread) to place the downloaded image into the imageView
NSURLSession NSURLSession is a bit different. An NSURLSession has be created with a NSURLSessionConfiguration first. Because of this I created a helper method that generates a NSURLSession with the configuration needed, and it returns the NSURLSession it creates: func getURLSession()->NSURLSession { var session:NSURLSession var configuration =NSURLSessionConfiguration.defaultSessionConfiguration() session =NSURLSession(configuration: configuration) return session; }//end getURLSession Since I don’t want slow down the main thread for this, I placed this code in a different thread. Then, here’s how to make the NSURLSession call: @IBAction func button_useNSURLSession(sender:AnyObject) { let url = NSURL(string: URL_CAR_2) var request =NSMutableURLRequest(URL: url!) request.HTTPMethod=“GET” var task = getURLSession().dataTaskWithRequest(request) {(data, response, error)->Voidin dispatch_async(dispatch_get_main_queue(), { self.label_status.text =“Selected NSURLSession” self.imageView.image =UIImage(data: data!) }) } task.resume() }//end button_useNSURLSession
Very similar to the NSURLConnection, so I’ll start at the NSURLSessionDataTask. Technically, NSURLSession does not replace NSURLConnection, but NSURLSessionDataTask is what replaces NSURLConnection.
NSURLSessionDataTask is an Asynchronous task, so we’re kind of forced to get the data from its completion handler
Call the main/UI thread and set the value of the imageView with the data from the completion handler
Author: Eduardo Flores In this post I’m going to outline how to get a list of available nearby bluetooth devices to show when scanned by an Adroid device. I’ll review how you can prompt the user to enable/turn on bluetooth in your Android device, how to show already paired bluetooth devices, and how to scan for new nearby bluetooth devices. For this tutorial, you’ll need a physical Android device (I haven’t found a way to make the emulator proxy the computer’s bluetooth signal), and I guess at least another bluetooth device in range for you to test things. The source code for this Android Studio project is linked at the bottom. Note: This tutorial DOES NOT explain how to pair, connect and send data to/from another Bluetooth device. I might make another post for those specific subjects. Also, this tutorial is based on regular Bluetooth and not Bluetooth Low Energy (LE)
Turn on Bluetooth
While a user can turn Bluetooth on from multiple places or ways in an Android device, one of the issue I had on a client’s project was the need for a unified way to show the user how to turn on Bluetooth in their android device. So instead of making X number of screenshots for “Getting started” guides depending on the OS level and the skin of the device, this approach is mainly universal (sure, the dialog might look slightly different on a different OS level) So, the plan is to have a button in the app that says something like “Enable Bluetooth” and prompts the user for permission to enable Bluetooth:
In here Bluetooth is disabled
After selecting the “Enable BT” in the app, the user gets prompt for permission to turn on Bluetooth. Now Bluetooth is enabled on this device This is super easy, so let’s get started. The first thing you need to do is get the permissions in the Manifest.xml file to access Bluetooth: <uses-permissionandroid:name=“android.permission.BLUETOOTH”/> <uses-permissionandroid:name=“android.permission.BLUETOOTH_ADMIN”/>
Then in our activity, which in my case will be the MainActivity.java, we need to create a few variables: import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.widget.Toast; publicclassMainActivity { privateString LOG_TAG;// Just for logging purposes. Could be anything. Set to app_name privateint REQUEST_ENABLE_BT =99;// Any positive integer should work. privateBluetoothAdapter mBluetoothAdapter; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); LOG_TAG = getResources().getString(R.string.app_name); mBluetoothAdapter =BluetoothAdapter.getDefaultAdapter(); } } What did I do here?
I create a constant String named LOG_TAG with just the name of the app to use it in LogCat
We will be starting the Bluetooth adapter with an intent and we will need a number for the request in the Intent. Because of this I created a variable named REQUEST_ENABLE_BT with a number of 99. Any positive integer (unsigned int) should work.
Create a new BluetoothAdapter variable, and instantiate it once the app starts to get the defaultAdapter() from the BluetoothAdapter.
With that, my “Enable BT” button calls a local method to enable Bluetooth on the device, like this: privatevoid enableBluetoothOnDevice() { if(mBluetoothAdapter ==null) { Log.e(LOG_TAG,“This device does not have a bluetooth adapter”); finish(); // If the android device does not have bluetooth, just return and get out. // There’s nothing the app can do in this case. Closing app. } // Check to see if bluetooth is enabled. Prompt to enable it if(!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent =newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } } In here:
I check to see if the varible from the BluetoothAdapter.getDefaultAdapter() (so the mBluetoothAdapter variable) is null. If it is, it means this Android device does not have Bluetooth. In my case I’m logging this as an error and I’m closing the app. There’s no point on doing a tutorial on Bluetooth using a device without Bluetooth.
If there is a Bluetooth adapter, I check if it’s not enabled (!mBluetoothAdapter.isEnabled()). If the device is not enabled, we need to turn it on.
Create a new Intent that calles the BluetoothAdapter.ACTION_REQUEST_ENABLE intent, start it with the arbitrary variable of 99 created in the previous step.
At this point you have successfully prompt the user to enable Bluetooth! But, umm…..how do we know if the user says no? Since we started the Intent to start turn on Bluetooth with the “startActivityForResult”, we can then get a result back using the “onActivityResult” method, like this: @Override protectedvoid onActivityResult(int requestCode,int resultCode,Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == REQUEST_ENABLE_BT) { if(resultCode ==0) { // If the resultCode is 0, the user selected “No” when prompt to // allow the app to enable bluetooth. // You may want to display a dialog explaining what would happen if // the user doesn’t enable bluetooth. Toast.makeText(this,“The user decided to deny bluetooth access”,Toast.LENGTH_LONG).show(); } else Log.i(LOG_TAG,“User allowed bluetooth access!”); } } Since this is a default Android method I’m overriding it. I then check if the requestCode that comes back is the same 99 I created, and if it is I know this answer is coming from the user prompt for Bluetooth I just created. If the resultCode of this request is 0, it means the user selected no. At this point its up to you what to do but in my case I’m giving a Toast dialog blaming the user for pushing the wrong button. Any other resultCode means the user accepted the promp. And…we’re done with the prompt to turn on Bluetooth! Moving on to the next portion of this tutorial.
Show list of already paired (bonded) Bluetooth devices
Pairing with a device is usually a one time thing, but connecting with already paired devices is a recurring thing. Luckily for us the OS keeps a list (a Set technically…) of all of the Bluetooth devices this Android device has already paired with, and some information out of them. In this portion we’re going to show a list of already paired devices and what information the OS is giving us: Note: different devices will show different information, so don’t worry much about null values at this point. What you see above is what my Note 4 device has been paired with. The first is a Nexus 7 tablet, and the second one is a music player. The information displayed here is whatever the OS already knows of the devices, which is not a lot. In my app I have a second button for displaying already paired devices, which calls a local method named “getArrayOfAlreadyPairedBluetoothDevices()”, which has this block of code: privateArrayList getArrayOfAlreadyPairedBluetoothDevices() { ArrayList<BluetoothObject> arrayOfAlreadyPairedBTDevices =null; // Query paired devices Set<BluetoothObject> pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are any paired devices if(pairedDevices.size()>0) { arrayOfAlreadyPairedBTDevices =newArrayList<BluetoothObject>(); // Loop through paired devices for(BluetoothDevice device : pairedDevices) { // Create the device object and add it to the arrayList of devices BluetoothObject bluetoothObject =newBluetoothObject(); bluetoothObject.setBluetooth_name(device.getName()); bluetoothObject.setBluetooth_address(device.getAddress()); bluetoothObject.setBluetooth_state(device.getBondState()); bluetoothObject.setBluetooth_type(device.getType());// requires API 18 or higher bluetoothObject.setBluetooth_uuids(device.getUuids()); arrayOfAlreadyPairedBTDevices.add(bluetoothObject); } } return arrayOfAlreadyPairedBTDevices; } Let’s break this down:
I created a new BluetoothObject class to create an object that I can pass around with data
I also know my final product is going to be a list of BluetoothObjects, so I need to make this method return an ArrayList of BluetoothObjects
I then ask the mBluetoothAdapter to give me the set of already bonded devices (mBluetoothAdapter.getBondedDevices())
I check to see if the set contains at least 1 element.
I then iterate the set of elements, extract each BluetoothDevice (OS provided type), and then set the values of my custom BluetoothObject with the values of the BluetoothDevice
Finally I add my custom BluetoothDevice to a new ArrayList I created, and I return the ArrayList
And that is also all we need to do to get the list of already bonded/paired devices. Again, this is super easy. Finally we will scan for new nearby Bluetooth devices in range.
Scan for nearby Bluetooth devices in range
Out of the whole project this is the most complicated section, but even then its super easy as well. There are a few things you need to know before we start this section:
You can only scan for other nearby Bluetooth devices that are already set to be discoverable.
Scanning for nearby Bluetooth devices is Asynchronous, which means the OS will do this in the background at its own speed and rate
We can only scan for X amount of time (currently 12 seconds) and then the discovery ends. Restarting the discovery usually works but if you restart it many times in a row without a break, the OS returns weird Bluetooth devices. This is the same on the OS’ settings app
You’re on charge of stopping/canceling the discovery of Bluetooth devices
So, when it’s all said and done, the app will display this: We click on the “Scan for Bluetooth devices” and in this case I decided to start a new Activity to do this process. We click on the “Scan for Bluetooth devices” and in this case I decided to start a new Activity to do this process. Here’s the code of this new “FoundBTDevices.java” class: privatevoid displayListOfFoundDevices() { arrayOfFoundBTDevices =newArrayList<BluetoothObject>(); // start looking for bluetooth devices mBluetoothAdapter.startDiscovery(); // Discover new devices // Create a BroadcastReceiver for ACTION_FOUND final BroadcastReceiver mReceiver =newBroadcastReceiver() { @Override publicvoid onReceive(Context context,Intent intent) { String action = intent.getAction(); // When discovery finds a device if(BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the bluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Get the “RSSI” to get the signal strength as integer, // but should be displayed in “dBm” units int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE); // Create the device object and add it to the arrayList of devices BluetoothObject bluetoothObject =newBluetoothObject(); bluetoothObject.setBluetooth_name(device.getName()); bluetoothObject.setBluetooth_address(device.getAddress()); bluetoothObject.setBluetooth_state(device.getBondState()); bluetoothObject.setBluetooth_type(device.getType());// requires API 18 or higher bluetoothObject.setBluetooth_uuids(device.getUuids()); bluetoothObject.setBluetooth_rssi(rssi); arrayOfFoundBTDevices.add(bluetoothObject); // 1. Pass context and data to the custom adapter FoundBTDevicesAdapter adapter =newFoundBTDevicesAdapter(getApplicationContext(), arrayOfFoundBTDevices); // 2. setListAdapter setListAdapter(adapter); } } }; // Register the BroadcastReceiver IntentFilter filter =newIntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); } This works by receiving data in a BroadcastReceiver, so let’s break it down:
Tell the BluetoothAdapter to start the discovery of new devices
Create a Broadcast receiver and override the “onReceive” method
The oddest part on this is the line of “BluetoothDevice.ACTION_FOUND.equals(Intent.getAction())” simply because this part you have to take it on faith as is “just do that and it’ll work”. Those kind of suck
Just like in the Set of already paired devices, we need to get a BluetoothDevice object, and in this case we’re getting it from the intent: “BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);”
Create a new object, put it on an ArrayList and start the list from here by setting the list adapter to the adapter just created
Finally, register the BroadcastReceiver
One thing you might notice different here is that I’m not returning an ArrayList and then passing that to the adapter. The reason for this is because this is an Asynchronous task. This means the discovery of the devices might take all 12 seconds (or more) so returning an ArrayList immediately won’t really work. Also, by passing this data directly this way the list can be updated automatically with new devices coming in. Alternately you could display a “wait while we look for devices” message and then return an ArrayList after X amount of seconds…it’s up to you. And finally, we’re on charge of canceling the discovery. This doesn’t get done automatically so if you start it and 2 seconds later you decide to close your app, the OS will continue searching for devices and eating up battery. So: @Override protectedvoid onPause() { super.onPause(); mBluetoothAdapter.cancelDiscovery(); } I hope this has helped. For more information regarding bluetooth permissions, mobile development, and other Android tutorials, check out our other blog posts. To learn how you can work with a STG Consultant for your software technology needs, contact us— we’d love to hear from you. The source code for this project can be found here.
Author: Eduardo Flores
Author: Andrew Turcsansk I was never really taught front end development. When I first started at the University in the early 2000’s, front end development was never truly a focus for Computer Science majors. Our focus was back end web development using languages such as Java and the up and coming C#. Of course we knew the basics of HTML, CSS, and JavaScript; however, web development per se seemed to fall within the area of ‘graphic design’. Today the front end landscape is completely different. Between then and now, I and many others like myself began to assume more of a front end development role. We were mostly self-taught, either at home, on our own or at work as we introduced through trial and error to newer technologies and techniques. Browsers and the systems they ran on became more powerful. Websites themselves became more prolific and eventually more mobile. This in turn shifted the development focus from powerful functionality accomplished on the back end to the actual usability of such features on the front end. The web has been moving toward a much more interactive and responsive experience. As I previously mentioned, I was never really taught front end development. But such is the nature of our industry. Sure, college courses lay down a solid foundation of development skills and know how. Yet, the true education is in the discovery, analysis, and implementation of new technologies to meet the current and future needs of the clients and companies we work with. After all of these years I still continue to teach myself front end development. As an example, only recently did I just come to know what the JavaScript prototype is and what it can be used for. It is true that developers care about relevance in a way as a matter of self-preservation. But if developers are not relevant, by the same argument, what they then develop is not relevant either. That is to say, the self interest in relevancy is not self-serving, but it is for the benefit of the world at large. We are concerned with becoming better at what we do, because in turn, the world becomes better at what it does. “If things don’t change, they stay the same” – Anon Author: Andrew Turcsansk
NSURLSession with Delegates
I have already created 2 tutorials (one for obj-c and one for swift) showing how to use NSURLSession in a very simple case scenario to download an image as NSData, and display it on the screen. That was fine and dandy, but NSURLSession can do sooo much more than that. In this post I’ll show how to use one of the delegates of NSURLSession to download a large image, while displaying how much data you have already downloaded. Since the image is larger now (5mb from some random website), the image gets automatically placed in a temporary file, which then gets converted to an image.
Final result
As usual, here’s the final result of what this will do: Gif created with “GifGrabber” from the Mac App Store (Free) So, let’s get started.
Declare the delegate
In the header file of your class, declare that you’ll implement the “NSURLSessionDownloadDelegate” @interfaceViewController:UIViewController<NSURLSessionDownloadDelegate> Setup your outlets, and you’re all done with the header file.
Setup Configuration, Session and Task
Since we’re going to get the data and status back from delegate methods, we’re going to do just some basic setup of the Session object. We’ll do this when the app starts, so the viewDidLoad method would work for this: –(void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. NSURLSessionConfiguration*configuration =[NSURLSessionConfiguration defaultSessionConfiguration]; configuration.allowsCellularAccess = NO; // Other options for configuration, if needed. I dont need them for this test // [configuration setHTTPAdditionalHeaders:some dictionary values]; // configuration.timeoutIntervalForRequest = 30.0; // configuration.timeoutIntervalForResource = 60.0; // configuration.HTTPMaximumConnectionsPerHost = 1; NSURLSession*session =[NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; NSURLSessionDownloadTask*task =[session downloadTaskWithURL:[NSURL URLWithString:URL_LARGE_IMAGE_1]]; [task resume]; self.label_downloadURL.text =[NSString stringWithFormat:@“URL = %@”, URL_LARGE_IMAGE_1]; }
In the configuration we can set additional settings or parameters. In this case I’m only using one option, but I have listed a few of the most common ones in case somebody needs them later.
Create and initialize the SessionConfiguration object
Since the image is “large” we’re going to limit this to WIFI only
Create the session object, and declare this class (self) as the delegate
Create the task
Start the task ([task resume])
Set the label with the URL we’re downloading, just for fun
Implement the required delegate method Since you’re volunteering to be the delegate of NSURLSessionDownloadDelegate, you need to implement (or technically just declare in some cases, but that’s a different story) the required methods. NSURLSessionDownloadDelegate has only 1 required delegate method URLSession:downloadTask:didFinishDownloadingToURL I implemented this method like this: –(void)URLSession: (NSURLSession*)session downloadTask: (NSURLSessionDownloadTask*)downloadTask didFinishDownloadingToURL: (NSURL *)location { NSData*imageData =[NSData dataWithContentsOfURL:location]; dispatch_async(dispatch_get_main_queue(), ^{ self.label_savedLocation.text =[NSString stringWithFormat:@“%@”, location];// too much text for 1 label self.imageView.image =[UIImage imageWithData:imageData]; }); }
This method gets called when the image, or whatever you’re downloading, has finished downloading, and it will place the downloaded image into a temporary file in your local system. However it does not return the temp file created, but it returns the location of where the temporary file gets saved (in the form of a URL)
I get the NSData from the temporary file location
This method runs on a different/background thread, so if I want to update the UI I have to do it from the main thread. Because of this I call GCD and ask to do something in the main queue
In the main queue, or main/UI thread, I update the status label with the location of the temp file, and I display the image that I downloaded
So that’s all for this!
However, NSURLSessionDownloadDelegate has several other methods you can use and play with. I decided to use the URLSession:downloadTask:didWriteDatatotalBytesWritten:totalBytesExpectedToWrite because this method can give me an updated status on how much data I’m supposed to download and how much I have downloaded so far. This makes for a nice “90% downloaded” user update. So let’s use that method.
Implementing the update method
With a super long name, the method URLSession:downloadTask:didWriteDatatotalBytesWritten:totalBytesExpectedToWrite is where we will be updating the labels with the status of how much data has been downloaded so far. I implemented this method like this:
There might be better ways to calculate the percentage, but this will do it for now
Again, this method runs in a different/background thread, so since I want to update the main/UI thread with data from this method, I need to get GCD to run it in the main queue
Update the labels
That is all! Remember, NSURLSession can do a lot more, like handle basic HTTP authentication in a more elegant way than NSURLConnection, so go and play with it. As usual, the source code can be found here.
Author: Brett Child Software developers, and IT in general, have a reputation for being over budget, being late, and not even meeting the needs of the customer. There are a million different reasons for that; such is the complex nature of software development. But, here are a few ways to reduce the risk that leads to a failed project.
Increase Communication
There can be a lot of people from many parts of an organization involved in a software project and it might really be impossible to get everyone together all the time. The risk is when ideas are communicated from the customer to one person who then has to translate those ideas to the people developing the software. Just like in the game telephone ideas get altered and assumptions lost. Learn how to pick the right consultant to avoid this problem. When the developers and customers don’t communicate you also lose the negotiation that might happen. This negotiation allows potential problems to be brought into the light before any code is actually written.
Reduce Complexity
With increased communication you can also negotiate reducing the complexity in the requirements. If you have a complex business process you’ll want to simplify it as much as possible. Complexity goes hand in hand with problems, and not simple problems. Problems as complex as the process itself so they’re hard to track down. One of my favorite phrases is ‘You ain’t gonna need it’ (YAGNI). Half of the software developed will never be used, so cut out as much of it as possible before actually building anything.
Get Feedback as Quickly as Possible
Once you have a good plan in place with the absolute minimum requirements needed, its time to start building something. This is where the assumptions that people have start to come out and things can go off course really quickly. This is why it is imperative to get feedback as quickly as possible from the customer. Let them see what you’re doing and have them validate that it is correct and do it while it’s still fresh on everyone’s mind. One way to measure this is your cycle time. How fast can you go from idea to a released feature. The quicker you can do that the easier it will be to change what isn’t going to work.
Plan to Change
When managing a complex project there is only 1 reliable truth: the plan is going to change. You’ll need to make sure that change is understood to be a good thing. It will allow the project to deliver real value and be useful. Change has a reputation for being bad. For some projects that might be justified, but for complex projects, like software, you need to assume that what you initially thought isn’t what will be released and you need to learn what is right along the way.
Build in Quality
And lastly, don’t compromise quality. It will be tempting with pressures building, but if you do compromise quality you run the risk of introducing dumb little bugs that have you face-palming yourself. You should be proud that you were part of a project and do everything you can in order for it to be the best you could possibly make it. Following these general principles will help wrangle the risk we all face whenever we start complex projects. We’ll never eliminate it all, but we can do our best to improve our chances to make it a successful project. Author: Brett Child Originally published at http://www.bmchild.com/2015/08/5-ways-to-reduce-risk-in-software.html
Author: Eduardo Flores On Android Studio version 1.1.0 for Mac (and maybe other versions) a brand new blank application throws an error dialog in the UI editor that says: Rendering problems. The following classes could not be found: – android.support.v7.internal.widget.ActionBarOverlayLayout The issue seems to be in the version of the UI editor Android Studio is using. On a blank default application Android studio is using level 22. Change the level in the UI editor to level 21 (or another other), and the error should go away: Author: Eduardo Flores
Author: Craig Golightly Whenever I meet someone new and they find out I am a Software Developer they often say, “I have this project…” I used to spend time listening in detail to what they wanted to do and I even embarked on a few “side” projects. These projects were filled with late night meetings in various basements, pizza, and a flurry of emails and phone calls but the excitement soon died off as the projects dragged on and completion seemed to elude us on every front. Why was it so hard? It was hard because I was trying to service all aspects of the project by myself on an already full schedule. A person can only do so much before burnout starts to set in. There are several perils to be aware of when you hire an individual “on the side” to do your project. First, if it is not their full time focus you won’t really get their full attention. I’m not talking about full time freelancers here who earn a living by doing projects, I’m talking about someone who is already putting in 40 hours/week at a day job then trying to fit in another 20 or 40 hours for your project. With that combination it won’t take long before things start to get out of balance. Another factor to consider is time to finish your project. Is your project time sensitive? Do you need it in a few months, or is a year ok? If you are working with a single individual “on the side” you will often not have your full functionality for a very long time. Then there is always the bus factor. If the person working on your project got hit by a bus tomorrow, what would happen? Now people usually don’t get hit by an actual bus but they can get hit with pressures at their day job, family situations, or just general disinterest in your project. Any of these things could cause them to bail. What happens to the investment you’ve made so far if the person is all of a sudden not there? What about maintenance – where will they be in 1-2 years when you need some updates, or there is some problem in the code? Now when I meet people who say, “I have a project…” I reply with a smile, “Great! Let me get you in touch with some IT Consultants I know. They can discuss your project, help you see what resources you will need to implement the project and give you an idea of cost and timeline.” Awesome! Everybody wins! They can get educated on their options and have the best support to implement a successful project and I can have time to go mountain biking. So what is so great about IT Consultants and how is it different from getting someone “on the side” to help you?
Experience – IT Consultants have seen many, many projects. The combined experience in some firms can add up to thousands of different projects. They have seen what works and what doesn’t. Why learn everything the hard way by yourself when you can benefit from the experience of someone who has already been there and knows what to avoid and how to overcome obstacles?
Resources – IT Consultants have a team to support them. This means getting the right people at the right time and ultimately getting your project done as soon as possible. The added benefit is that you don’t have to go find and hire all of these different specialists – you pay for what you need when you need it then go on your way with your completed project.
Support – IT Consultants are there to help you finish the job. When unexpected obstacles come up during implementation or individuals get hit by a bus, IT Consultants can draw from their team and network to fill in the gaps and move forward. They are also there for you long term when you need support and enhancements for your project.
Cost – You get what you pay for. You can generally get an individual “on the side” for a lower hourly rate than an IT Consultant. Even among IT Consultants there can be a wide range of prices for different services. The big thing to look at is results. Talk to some customers of the consulting firms you are considering, both customers with completed projects and customers who have projects in progress. In the end the most expensive thing to you is a project that is incomplete. Make sure you have the support to get your project past the finish line where it can add value to your organization and provide a return on your investment. It may look like more to hire IT Consultants initially, but in the end you will come out ahead.
IT Consultants enjoy the variety of projects they work on and the opportunity to help people solve problems. There is a wide range of consulting firms out there, each with their own specialty and way of doing business. Find a good fit for your situation and you will have much better success than when you try it with someone “on the side.”
Author: David Hales
For about 4 years now, I have been utilizing Nuget Packages as a way to reuse centralized code. What do I consider centralized code?
I’m going to go a bit more in depth into my DM.Core package, as it is the center of what I am describing of using a centralized or ‘Core’ code base.
I currently use my DM.Core as a place to store methods and functions that I want to and can use in any of my projects. Email settings, encryption settings, object extension methods, and various other things.
For example, my simple encryption handler has an Encrypt method, and a Decrypt method, which simply Encrypt and Decrypt a string using a base key. I have also created these as extension methods, so I can simply Encrypt and Decrypt a string like so:
Other examples I have are extension methods for object.ToBool, object.ToInt, object.IsNull, object.IsNotNull.
The extension methods are basically shortcuts to simplify code. For example, ToInt does an Int.TryParse and if it gets an Int, it returns that, if not it returns 0.
Object.IsNull is basically a shortcut of writing out object == null. Not a big thing, but a fun little shortcut. Other examples include string.ToFormattedPhone, which formats a string into a desired phone number format. Also, string.IsValidEmailAddress, which uses a regular expression to validate if the string is an email address format.
Methods like these can be used to simplify code in a lot of places, and would be tiresome to duplicate in more than one place. Usually these are kept in a single file inside a given project, so that that project can use them. What I do, is I have a separate project that I call DM.Core, and after compiling it, I package the dll into a Nuget Package.
So I’ll show you that now, which is really what this article is about.
Creating a package is easy. What you need to first, is decide where do you want your package to reside? There are a few options. You can host the file with nuget.org, which makes it available to the world. You can set-up a Nuget server inside your network that you can access using your local network, or you can set-up a nuget server that is accessible on the web. The last two options are essentially the same thing, the latter just requires you open the website up to be accessible through your firewall/DNS etc.
There are a lot of sites out there that cover how to set-up your own Nuget package feeds. No sense in me covering this. I used the following straight from nuget.org to set up mine: https://docs.nuget.org/create/hosting-your-own-nuget-feeds So how do you create your own Nuget packages?
There is a great bit of software out there someone has written that makes this so simple. Nuget Package Explorer
Note: If you set up a nuget feed that is secured and requires a password, the latest version of the Nuget Package Explorer does not work. You will need to download and run version 3.6 in order to be able to enter credentials to a secured Nuget feed. I learned this the hard way.
Open the Package Explorer:
Select Create New Package.
Click the Edit Metadata button
Fill out the details of the package. I version mine based off the date, example. If I built a new package on January 1st of 2015, my version becomes:
2015.0101.01 – This is 2015 January 1st version 01 for that day. Then if I need to make another version that day, I increment that end number by one. It becomes:
2015.0101.02 – This gives me an idea of when the package was last updated, etc. Just the way I like to do it, you can do it however you want. The key, is that you always need to increment the version up somehow, whenever you modify a package, or your applications don’t see it as a new version.
Once you have filled in your details as you want, click the check mark.
Next, you want to add the dll’s from your project that will be included in your package.
Select CONTENT -> Add -> Lib Folder
Next, you can right click on the Lib folder, and select Add Existing file, or you can drag and drop dll files to the folder as well. You want to make sure to put the files inside the Lib folder.
Select the dll files pertaining to your project you want included.
I always add the dll and the pdb file to my packages.
Next step depends on if you are using online feed or a local source. Local sources, you can save the file to the packages folder of your local nuget feed. If you do File -> Save As, it will default the file name to the ProjectName combined with the version, so that when it saves, the package will show as a newer version.
For an online feed, select Publish from the file menu
Enter your feed url and the publish key. You would have set this up when you set up the server.
Click publish, and the package will get published. Now you can add this location to your Nuget Package Source in Visual Studio. Then include the using at the top of the class you wish to use it in, and you are set.
To update a package, just open it from local, or online feed, and make your modifications to Metadata. (Remember to update the version), and add the new dll and pdb files, and re-save or publish the package.
This can be used for all sorts of applications. I use it as a way to populate my Entity Frameworks objects into various projects, so I can keep a centralized project that is outside of my Front End sites. It can be used anywhere you have reusable code that you could offload into a separate project and load into multiple projects using the Nuget packages. Author: David Hales
Author: Dan Bunker
Pick any software company and take a stroll through their cubicle farm. You’ll find developers white boarding out problems, coding and staring at 2 or 3 monitors at a time and occasionally having nerf gun wars. Most will simply view this environment as a standard software shop but if you take a closer look you’ll discover something deeper lurking in every developer writing code for a living. What is it that every developer hides from those around them?
A Secret
If you corner a developer in the break room and start prodding them about their project or what they’re working on, you might notice the nervous twitch in their eyes as they tell you everything about their work except for their one secret. This secret is rarely mentioned by college teachers or software books or online software tutorials. This secret isn’t a secret about being 5 minutes late to work in the morning or that the developer can fluently speak Klingon. This secret lives in just about every line of code that has ever been written and produced. So what is this secret?
Nobodies Code is Perfect
Yes, some developers write better code than others but no one writes 100% perfect code. This isn’t referring to how many bugs are in the code or not. Coding is part science, math and art. You may have 0 bugs in your code but it’s put together so badly that it’s impossible to maintain. Or your code might look like a thesis example out of an MIT computer science research paper but your buddy on your team can’t make heads or tails out of it because it’s so esoteric and complex.
Ask any developer after they finish up a project if there are things they would like to change or something they would do different and all of them will come up with a list. This is in part because the software libraries and practices change over time and the way we build software changes. It’s also due to the fact that hindsight is 20/20. Once you have tackled all of the problems and jumped all of the hurdles, you’ve learned from your experience. That experience then tells you there may have been a better way.
The best developers don’t lose sleep over this little secret. They realize that their code is a work in process that will never be done and build it in a way that allows them to meet their job responsibilities and allow for ease of understanding and future maintenance. Sometimes this means doing things using a simple if/else statement rather than a ternary or a for loop instead of a recursive function. Just because you can do something fancy and tricky doesn’t mean it’s the best solution for your software product. Especially if you’re working in a team environment.
Striving for Perfection
Even though writing perfect code 100% of the time is not a realistic goal, there are things that developers can do to get further down the road of perfection.
Gain experience. The more work you do and the more code you encounter will give you greater insights into building better code. If you are stuck working on an old project at work, take on some side jobs. Tackle projects that are really small to really large. When opportunities come up on the job, offer to take them on. Try working in a different programming language every now and then. All of the experience you gain will season you and give you an inside understanding of what good or bad code is.
Test your code. We all talk about writing unit tests and testing our code but very few of us actually do it. And those that do write unit tests are simply writing them to follow a team rule or to comply with company standards. This leads to tests that don’t really test. They fire up the code and do a few assertions and call it good. Testing code well takes time and effort. The effort you put into testing will easily be rewarded with experience points (which we saw in item #1 gives you insight into what better code looks like).
Care. Have you ever noticed the quality of work when you hire a teenage kid in your neighborhood to mow your lawn vs. how you mow your own lawn? The kid will probably leave grass clippings on the sidewalk. They might miss the portions of the perimeter. The same principle applies with the code you write. You should treat all code you write like it’s for your own personal project. Dot the I’s and cross the T’s. Don’t half heart the work you do because that ultimately produces less than desirable code in the long run.
Never stop learning. This industry is constantly changing. If you’ve found you’ve become complacent you are treading in dangerous waters. Best practices evolve. The concept of what perfect code is, is always changing. If you stop learning and keeping up your coding solutions will begin to show their age.
The next time you are talking about your code with others, don’t hide the fact that there are imperfections in your code. Tell them, “I know this could have been done better here but I was under a deadline to get this finished. If anyone has any suggestions on how to make this better I’d love to hear them”. Getting feedback from your team, doing code reviews and being willing to change and learn will make you a rockstar developer. Even rockstars miss notes from time to time. Author: Dan Bunker