Well Mostly Self Taught
Those in the software development world who freelance, work on a team or even do it as a side hustle building sites, and who've not had much in the way of educational experience in the field of Computer Science will face a certain set of challenges. I'm not here to say that one way or the other is better when getting into the arena of software development. Both backgrounds of being self-taught or coming from a traditional CS background bring something different to the table and I've seen such developers be a valuable part of any team. It is important to understand that there are differences and some hurdles along the way that a non-CS developer will face along the way. I took two 10 week courses related to development while getting a Certificate in Geographic Information Systems, so I feel like I qualify in not having all of the formal education that a Computer Science degree will get you.
Programming on a Team
This experience was an eye-opener for me the first time I had the opportunity to work with other developers on a team (all of whom had many years of experience on me) in an agile/scrum environment. We didn't necessarily have code review, but I was definitely critiqued and having my errors or code picked apart and pointed out to me was difficult at times. I was motivated though, and I think anyone that makes it into their first development gig being self-taught has to be. At this point, I was still relatively new to programming and I had to view this as another way to improve. I actually think this was one of the most accelerating parts of my career. It forced me to explain the reason why I approached a problem the way I did, and also be open to the idea that there was a better way. Another aspect of being part of a team was the planning process surrounding development projects. We worked using agile/scrum methodology so this included story creation, features, and task identification. Also, architectural design and using a whiteboard for discussions to show ideas and explain how things could be implemented was different than how I'd been used to working on projects. I'd been working through different problems on my own and finding solutions (mostly applied to my field of study at the time in Geographic Information Systems), but never had I worked on a team to help develop a solution, nor provide input of my own in a group setting. Solutions after all, is what programming is trying to provide, and this was where I needed to apply my own ideas, even if they might be wrong. Sometimes though it was the right solution too.
Finding Solutions When There is No Direct Answer
This is what can set apart great developers from the ordinary. It's one thing to be able to find a solution to a problem on Stack Exchange and implement a copy-pasta version of your own after modifying a few lines. But it's entirely different to identify and implement a solution when one isn't directly implementing itself. There are no tutorials or examples for real life problem that we are solving. Keep an open mind and reach out to those around you. I will admit that I've wasted time looking for an answer to a problem on various sources other than my team because I didn't want to appear to not know what I was doing. Asking another team member for some help, even if they didn't have a direct answer, they could at least act as a sounding board and offer up some of their direct experience and insight with whatever application we were working on.
This is a trap. I hadn't personally written a single line of code until I was 33 years of age. I've now been doing this professionally for four years. I've had two 10 week courses and those were a kind of fly by the seat of your pants experience. I did not know what I was getting into. I remember going to a job fair and talking to someone there at a recruiting company for software and IT, and I realized pretty quickly that I was lacking a lot of the necessary skills needed for software development. It felt daunting to give this person my resume and have him start asking me questions that I had no clue what the answer was. He was nice though and told me to keep at it. I think most developers have felt this way at least a few times, and if you haven't you probably are not pushing yourself. At this point, I'd been coding for about 6 months and this conversation left me feeling out of my league. Even talking to another classmate who'd been in the same python course with me seemed to have a better understanding of certain subjects. This is where perseverance is required. I kept at it. It wasn't shortly thereafter I took an internship in a department that could use my GIS skills (my field of study). I was able to use some of my python skills and apply them to the work I was doing and it felt great. I also gained some experience working with a relational database (something I'd no knowledge about). After there for 6 months, I landed another internship which was more of the same plus some additional web development. Also during this time, I'd completed my certificate program and was taking time outside of my internship to learn as much as I could and trying to hone some of my new found skills. Mind you I had an educational background that helped with the role, but I'd get around some of the CS folks and just felt like an imposter. This is honestly where the magic is. It doesn't always matter what your background is. Sure you may not have the same knowledge or skill set. You may not understand exactly how an indexed field in a database table works, but if you ask questions and then apply it, you've done the job. You may not understand how class inheritance works the first time you see it, but if you ask for examples or research it and try it out, you can see for yourself. If you work on a team, ask questions. Just about any good developer worth their salt will spend the time to help someone understand a topic which is going to help better a fellow dev. It's the interdependence of being on a team.
Understanding Basic Computer Science
This is one area where you ought to spend time learning outside of just writing code. It'll pay dividends. Learn your fundamental data structures and algorithms that are commonly used. You'll find they are implemented across almost all languages in one way or another. A lot of languages will have built-in implementations such as linked lists, and hash tables, but you should understand why these exist and why an array is not always optimal, and also why sometimes it doesn't matter.
Grokking Algorithms is a great book to start with and the author does a great job explaining some concepts that can otherwise be somewhat abstract and difficult to understand. Project Euler is another great place to go for problem-solving and understanding why certain implementations to solving a problem are better than others and get a firmer grasp on why Big O notation is important and what to look for when writing code. I avoided this subject for a while. But it kept coming up. I interviewed at a company where some basic questions around memory allocation came up. I didn't know the answers, I just hadn't thought about it before really. I just didn't know. And that was ok. I know now the way most garbage collection works, and what a reference pointer is now. I just had to use it as an opportunity to grow and understand things more in-depth.
Keep At It
Seriously. Keep at it. This applies to any developer, but I think those that come from the non-CS background need to hear this. Just keep at it. You'll get better if you try. Join a Meetup group in your area. Help share your knowledge and you'll be amazed, as is with most circumstances in life, you'll mostly be defeated by your own attitude.