Quite a few of the programmers I work with are in their 40s and 50s. A few of the senior software engineers are in their 60s. I sometimes find myself explaining things to them, but overall, they're quite smart people relative to many people I have met in the past. At least they don't make obvious mistakes and are good at following industry standards.
Getting the "correct" answer is not good enough, the answer needs to be correct for the right reasons. A lot of my job is cleaning up "correct" implementations. Quite a bit of my job is handling high profile cases that need quality, performance, reliability, debugability, and needs to be able to handle massive feature creep. You know how to handle feature creep in a way that doesn't involve lots of technical debt? You anticipate the features ahead of time, or at least the general direction.
Most work being done is "good enough" and "works", but I am back-logged with projects trying fix the inadequacies in other systems that I did not make. I have a back-log of projects to improve my daily work, but instead I constantly get drafted to fix other people's poor designs. They work great for the first year or two, but then go to crap once they need to start extending.
Before I got into my current position, we've had relay feature requests from high paying customers to engineering, only to get quotes like this poster-child of 1,000 man hours and 6 months. Then I wrote it myself in less than a week, deployed it to production, never had a bug, has been running for 3 years on hundreds of systems.
This is good for job security, but can be quite annoying, because it's a waste of my time cleaning up other people's messes. I have plenty of job security with my official job description duties.
First you have to find the top 20 Indian programmers. The same issue exists for finding good programmers anywhere, lots of noise from the not so good ones. You also have the issue of communications. They may speak English, but there are some large cultural differences when it comes to actually communicating ideas.
The level of interest someone has in a subject is generally a good indicator. When it comes to programming, it's not the answers that count so much as how one arrives at an answer. What we need is interactive dynamic analysis of logic. Generally it works best just to have another "great" programmer strike up a conversation with another.
Programming is a bit different than other fields, there are many technically correct answers, but few good answers. In hindsight, identifying a good programmer is much easier, because their creations are easy to debug and work well, even when beyond their design.
A great programmer understands enough stuff that they can debug their creations on a whiteboard without looking at the source code or using a debugger.
I know for myself, I have no background in the Go language. My co-worker came to me telling me he had an issue with an example program where it became slower and slower, very quickly, when it came to lots of channels and go-routines, and he couldn't figure out why. First I started asking basic questions about how the Go language is meant to work, then I asked him how he had his stuff setup, then asked him what he expected. I couldn't find any fault with his setup with my limited understanding of the Go language, but I do understand multi-threading and generally work with complex interacting systems. So my next question was what compiler he was using. Turned out he was using GNU. Then I asked him how they implemented it. After a bit of digging, turned out they used threads for go-routines because threads are much easier to implement quickly for a proof-of-concept compiler. Then I found out they limited how many threads could run at once. This meant that his go-routines, which were blocking each-other, normally would not have an issue in a correctly implemented compiler, but because the number of go-routines which could be processed at a given time was a fixed small number, it effectively created a pseudo-dead-lock, which fixed itself after some timeout that scaled poorly with the number of go-routines. A quick minor change to how the channels were configured, and it ran quickly.
Obviously, in my example, my co-worker is quite smart also, he was able to answer all of my questions or look them up quickly. He came to the same conclusion as I did at the same time. We work well together, which is why my boss paired us. We're great at asking questions. Good answers are hard to come by, good questions are rarer yet.
Having no background in a specific language, I was able to quickly, I think about 15 minutes, figure out a kind-of-deadlock issue in what technically should have worked, by understanding how the compiler implemented "go-routines". My only real-world experience in programming is C#, I don't do any at-home hobby programming, but I do a lot of reading.
FYI: You can snoop L2 cache, but not L1. Intel went with inclusive cache so snooping wouldn't be needed. AMD went with exclusive, which gives better cache usage, but went trying to sync threads, all of that cache snooping is a high latency operation. By having cache being inclusive, you no longer need to snoop, just look at cache normally.
AMD has higher overall throughput for many GPU type work loads, but Intel shines with work loads that require thread syncing.
Memory speed can technically still be the bottleneck
And taking a piss before you head to work can save you gas money. Your link shows an 80% increase in memory speed giving a 1.7% increase in performance. Congrats, you just doubled your memory's power consumption.
Taxing the 96% to cover the cost of hardware and man hours to maintain these filters, which just amounts to something similar to religion or out-sourcing parenting, seems to be an abuse of power. What's next, taxing people in health care to cover homeopathic "remedies"?
I also have the ability to look through people's wallets and purses when they're at my house, but it doesn't make it legal for me to start taking note or changing stuff in their belongings.
IOMMU can already control DMA access. Secure boot can restrict what images can boot, the images can restrict what devices have DMA access, and after granting DMA access, what memory ranges they have access to. We already have the tech to handle this situation, it's just a lack of implementation or a poor implementation.
Do you understand that using a single RSA style dongle for multiple places is a huge risk?
If you have an infinite number of systems to log into, how many dongles is optimal, and how do you keep track of which dongle to use with which system? Where do I keep these dongles? My pocket is already uncomfortably full with a keyring with 4 keys and a fob on it. My other pocket has a smart phone.
There's many chicken and egg issues going on in Africa. Send food, and the incoming food becomes like money and manages to help fund local war lords. This actually happens. Sending food causes people with guns to start to show up and find a way to exploit the situation.
You also can't send money or send technology. All of those things cause issues with exploitation. One of the few ways that have actually worked is making real demand for work in those areas.
Any artificial support creates exploitation, you need real demand for real work. This is hard to do in areas of under fed people with no education and no real government. Intel has started sourcing their rare minerals from some of these poor areas. They painstakingly make sure trace all of their mineral sources to make sure they're not "blood minerals". This makes it very hard to exploit. The gun men stay away because once they move it, the operation loses all value because Intel refuses to trade with them.
Stuff like this has helped a lot. I'm sure there are other ways, but throwing money/food/etc at an issue actually makes it worse. Temporary help is one thing, but for sustaining issues, it does not help.
But if the house was unable to be sold for $70mil in the future, there would be less chance of anyone building it in the first place. It's the people in the future that drive the demand for it being built in the first place.
As I understand it, only parts of.NET are open source at the moment.
The parts that are not dependent on Windows. They didn't opensource the Windows Secure Storage API, because the fundamental parts required for that API to work is in Windows. Pretty much all of the stuff that can work on any system, has been opened.
The "Windows" version of.Net is going to be based on the OpenSource version. MS is working on transitioning the Windows.Net stack to the exact same version as what they have on GIT. While there may be some forks of.Net, the official MS repo on GITHub will be the one Windows uses.
The fact that nginx's performance drops off after 600 connections indicates they're doing something wrong with their benchmark. Like I said, nginx doesn't drop performance even after 2mil+ connections. 1,000 connections is nothing for even a single core server, that benchmark is crap. They need to be testing more along 100k connections per core.
Just wait until you get someone who targets you with their cheaply hired DDOS and kills your web servers because it can only handle hundreds of requests per second because of poor design. A good app designs should at least allow your server to handle more requests than you have bandwidth. It's sad when you hear about servers getting DOS'd with 10mb/s of traffic over a 1gb/s pipe.
I mixed something up. That 70m message/s is not "requests", but messages getting passed around to other servers to send the messages to other users on other servers. The actual requests per second on the server was about 50k/s.
Whatsapp has load tested nginx in production with a max of 2.8m connections and 400k new connections per second and capable of handling about 50k requests per second on a single server. They had their server at 3m connections for a bit, but it started to backlog to the point where it had a 15sec backlog. 50k requests per second for 15 seconds is 750k outstanding requests, without crashing. Let me know how Apache would handle that.
A process has at least one thread and threads are bad for scaling. As a rule of thumb, you should not have more threads than 2x your CPU count. The more threads you have, the more pressure you put on the thread scheduler, plus you cause massive cache thrashing and context switching. Many programmers seem to assume threads are cheap and let the thread scheduler handle mutiplexing instead of doing it themselves. On every OS and CPU, this is bad.
There was a lot of talk about Linux's O(1) scheduler, but after it went live, it shortly got changed from the default because it didn't play well with enough common cases on modern system. Whatever the current scaling actually is, the system falls over after too many threads. It seems to be similar to O(n). Eventually your system spends more time scheduling threads than running them. You can have a lot of threads before it becomes an issue, but a modern server with 10gb+ connections, and this becomes an issue.
Whatsapp had an awesome write up on issues they ran into making their servers scale. They where able to run a server in production handling 400k+ connections per second and an average of 2.8m active connections. Their current servers are load balanced to 1/2 that load to give them breathing room. You try making Apache with "threads" handle those kinds of loads. With one thread per connection, you're talking about 2.8 million threads, and at 400k connections per second, you best be using a thread pool and not creating new threads. Then you include them averaging 6.4k requests per second per core, a 24 core server would be processing about 153,000 requests per second. (70m messages/sec over 11,000 cores in their datacenter in 600 servers)
Warning: My Java experience is a bit dated, and some of my issues may have been addressed in recent version, but based on my periodic reading, it seems to be working "as intended" and will never be "fixed".
One thing that I absolutely hate about Java is the whole, nearly everything is an object, even primitives, in many cases. I have some pretty high performance code in C# where even a single allocation of a small object can quickly turn into hundreds of megs per second. I can quickly get code working in C#, then slowly replace the code from allocating objects to using primitives and value passing or in-place value changes.
Java, on the other hand, decides that ints in generic arrays are immutable objects, meaning every time I change a value, it has to create a new object. There are many other times where Java does similar things where there is no way to cleanly make your code or can't make your code not have to work with objects.
The problem this creates is that high object creation causes lots of garbage collection, which stops world, which causes all of the threads to stop, and the more CPU cores you have, the quicker the GC kicks in. So instead of my.Net version running at 99% CPU, I have a Java version running at 70% CPU, and slower per %, because of all of the object work.
C# gives me the best of both worlds. Quick prototyping in a very clean and strict way, allowing me to define my code in very extendable generic ways but enforce strict usage, while allowing me to eventually micro-optimize without having to sacrifice clean code.
I have programs with thousands of lines of well factored code that has many layers of generic objects and functions, where I can run a 32 core server at a sustained average of 97%+ CPU for hours, crunching data, and use less than 50MB of object allocation.
Another thing C# allows me to do is have some degree of control over data locality. I've had performance gains of over 20% by tweaking classes/structures. Better control of how the data is laid out in memory allowed me to change up my algorithms, causing fewer cache-lines to have to be fetched from memory, reducing memory pressure in L1/L2 cache.
In the end, C#.Net allows me to write "Faster" code than C, because it allows me to quickly and easily make usage of modern multi-core CPUs, while giving me an easy to use and clean language. Java gives me a nice language, but I can't optimize it as well as C#.Net. It could e a limitation of my knowledge, but Java just seems to want to do many things as objects a lot more than C#.
Don't get me started about how awesome async in.Net is. Threads are the devil when it comes to scaling. I haven't gotten to use DataFlow yet because production is only.Net 4.0, but once we go 4.5, I'm jumping on that also.
The enemy of good is perfect. It's better to design your security around best practices and have recovery modes. My immune system doesn't stop me from getting sick all of the time, but it does a good job recovering. That should be the goal.
The beauty of intro CS classes is you don't need prior knowledge or experience. Anyone with a bit of logic should find it easy. I went into a 4 year, not much more than knowing computers work entirely on numbers. For my first experience in programming, I got dropped into a C/C++ class that dealt with datastructures and algorithms. I think I was the only one who got an A, I never studied, always finished my test 10-15 minutes before everyone else, and did my weekly programming assignments the night before.
A lot of people changed majors after that class. I found it non-challenging, with no prior programming experience, but some stuff was still important.
The 101 classes at my Uni was stuff like, this is a computer, this is Excel. The 106 classes were like, this is a race condition in multithreading. You can skip the intro class that shows you how to turn on a computer, but they're not going to let you skip the other "intro" classes.
Most of the intro classes will teach you stuff that is extremely important, and you'd rarely learn on your own via experience. Most programmers critiquing each other is like the blind leading the blind. Few people in the real world will point out these mistakes and few people in the real world realize that these are mistakes. Learn the basics.
I was a freshman when I learned about SQL injection attacks and how I should never trust the client. The teacher went over many historic examples of programmers making stupid mistakes that mostly involved not validating client input. A lot of the stuff I learned in many of these early 100 level classes, many many programmers don't know about or don't care. The later wouldn't surprise me.
Every time I read about some big security flaw at some big corp web service, I think to myself, they would have failed Programming 101. Don't underestimate intro classes, unless you think your college sucks, then by all means assume the classes are a waste of time.
I take the hybrid approach myself. I identify the issues, come up with some solutions, note the pros and cons, bounce my ideas off my cubical mate. He adds it some ideas and thoughts, then I go back to working on my own again.
Based on the design of many high profile opensource programs, or big projects in general, I assume most seasoned programmers with 10+ years of programming could not test out an intro Computer Science class. CS has little to do with programming and everything to do with theory.
Quite a few of the programmers I work with are in their 40s and 50s. A few of the senior software engineers are in their 60s. I sometimes find myself explaining things to them, but overall, they're quite smart people relative to many people I have met in the past. At least they don't make obvious mistakes and are good at following industry standards.
If you don't get the right answer, you fail,
Getting the "correct" answer is not good enough, the answer needs to be correct for the right reasons. A lot of my job is cleaning up "correct" implementations. Quite a bit of my job is handling high profile cases that need quality, performance, reliability, debugability, and needs to be able to handle massive feature creep. You know how to handle feature creep in a way that doesn't involve lots of technical debt? You anticipate the features ahead of time, or at least the general direction.
Most work being done is "good enough" and "works", but I am back-logged with projects trying fix the inadequacies in other systems that I did not make. I have a back-log of projects to improve my daily work, but instead I constantly get drafted to fix other people's poor designs. They work great for the first year or two, but then go to crap once they need to start extending.
Before I got into my current position, we've had relay feature requests from high paying customers to engineering, only to get quotes like this poster-child of 1,000 man hours and 6 months. Then I wrote it myself in less than a week, deployed it to production, never had a bug, has been running for 3 years on hundreds of systems.
This is good for job security, but can be quite annoying, because it's a waste of my time cleaning up other people's messes. I have plenty of job security with my official job description duties.
First you have to find the top 20 Indian programmers. The same issue exists for finding good programmers anywhere, lots of noise from the not so good ones. You also have the issue of communications. They may speak English, but there are some large cultural differences when it comes to actually communicating ideas.
The level of interest someone has in a subject is generally a good indicator. When it comes to programming, it's not the answers that count so much as how one arrives at an answer. What we need is interactive dynamic analysis of logic. Generally it works best just to have another "great" programmer strike up a conversation with another.
Programming is a bit different than other fields, there are many technically correct answers, but few good answers. In hindsight, identifying a good programmer is much easier, because their creations are easy to debug and work well, even when beyond their design.
A great programmer understands enough stuff that they can debug their creations on a whiteboard without looking at the source code or using a debugger.
I know for myself, I have no background in the Go language. My co-worker came to me telling me he had an issue with an example program where it became slower and slower, very quickly, when it came to lots of channels and go-routines, and he couldn't figure out why. First I started asking basic questions about how the Go language is meant to work, then I asked him how he had his stuff setup, then asked him what he expected. I couldn't find any fault with his setup with my limited understanding of the Go language, but I do understand multi-threading and generally work with complex interacting systems. So my next question was what compiler he was using. Turned out he was using GNU. Then I asked him how they implemented it. After a bit of digging, turned out they used threads for go-routines because threads are much easier to implement quickly for a proof-of-concept compiler. Then I found out they limited how many threads could run at once. This meant that his go-routines, which were blocking each-other, normally would not have an issue in a correctly implemented compiler, but because the number of go-routines which could be processed at a given time was a fixed small number, it effectively created a pseudo-dead-lock, which fixed itself after some timeout that scaled poorly with the number of go-routines. A quick minor change to how the channels were configured, and it ran quickly.
Obviously, in my example, my co-worker is quite smart also, he was able to answer all of my questions or look them up quickly. He came to the same conclusion as I did at the same time. We work well together, which is why my boss paired us. We're great at asking questions. Good answers are hard to come by, good questions are rarer yet.
Having no background in a specific language, I was able to quickly, I think about 15 minutes, figure out a kind-of-deadlock issue in what technically should have worked, by understanding how the compiler implemented "go-routines". My only real-world experience in programming is C#, I don't do any at-home hobby programming, but I do a lot of reading.
FYI: You can snoop L2 cache, but not L1. Intel went with inclusive cache so snooping wouldn't be needed. AMD went with exclusive, which gives better cache usage, but went trying to sync threads, all of that cache snooping is a high latency operation. By having cache being inclusive, you no longer need to snoop, just look at cache normally.
AMD has higher overall throughput for many GPU type work loads, but Intel shines with work loads that require thread syncing.
Memory speed can technically still be the bottleneck
And taking a piss before you head to work can save you gas money. Your link shows an 80% increase in memory speed giving a 1.7% increase in performance. Congrats, you just doubled your memory's power consumption.
Taxing the 96% to cover the cost of hardware and man hours to maintain these filters, which just amounts to something similar to religion or out-sourcing parenting, seems to be an abuse of power. What's next, taxing people in health care to cover homeopathic "remedies"?
I also have the ability to look through people's wallets and purses when they're at my house, but it doesn't make it legal for me to start taking note or changing stuff in their belongings.
IOMMU can already control DMA access. Secure boot can restrict what images can boot, the images can restrict what devices have DMA access, and after granting DMA access, what memory ranges they have access to. We already have the tech to handle this situation, it's just a lack of implementation or a poor implementation.
Do you understand that using a single RSA style dongle for multiple places is a huge risk?
If you have an infinite number of systems to log into, how many dongles is optimal, and how do you keep track of which dongle to use with which system? Where do I keep these dongles? My pocket is already uncomfortably full with a keyring with 4 keys and a fob on it. My other pocket has a smart phone.
There's many chicken and egg issues going on in Africa. Send food, and the incoming food becomes like money and manages to help fund local war lords. This actually happens. Sending food causes people with guns to start to show up and find a way to exploit the situation.
You also can't send money or send technology. All of those things cause issues with exploitation. One of the few ways that have actually worked is making real demand for work in those areas.
Any artificial support creates exploitation, you need real demand for real work. This is hard to do in areas of under fed people with no education and no real government. Intel has started sourcing their rare minerals from some of these poor areas. They painstakingly make sure trace all of their mineral sources to make sure they're not "blood minerals". This makes it very hard to exploit. The gun men stay away because once they move it, the operation loses all value because Intel refuses to trade with them.
Stuff like this has helped a lot. I'm sure there are other ways, but throwing money/food/etc at an issue actually makes it worse. Temporary help is one thing, but for sustaining issues, it does not help.
But if the house was unable to be sold for $70mil in the future, there would be less chance of anyone building it in the first place. It's the people in the future that drive the demand for it being built in the first place.
As I understand it, only parts of .NET are open source at the moment.
The parts that are not dependent on Windows. They didn't opensource the Windows Secure Storage API, because the fundamental parts required for that API to work is in Windows. Pretty much all of the stuff that can work on any system, has been opened.
.Net is going to be based on the OpenSource version. MS is working on transitioning the Windows .Net stack to the exact same version as what they have on GIT. While there may be some forks of .Net, the official MS repo on GITHub will be the one Windows uses.
The "Windows" version of
The fact that nginx's performance drops off after 600 connections indicates they're doing something wrong with their benchmark. Like I said, nginx doesn't drop performance even after 2mil+ connections. 1,000 connections is nothing for even a single core server, that benchmark is crap. They need to be testing more along 100k connections per core.
Just wait until you get someone who targets you with their cheaply hired DDOS and kills your web servers because it can only handle hundreds of requests per second because of poor design. A good app designs should at least allow your server to handle more requests than you have bandwidth. It's sad when you hear about servers getting DOS'd with 10mb/s of traffic over a 1gb/s pipe.
I mixed something up. That 70m message/s is not "requests", but messages getting passed around to other servers to send the messages to other users on other servers. The actual requests per second on the server was about 50k/s.
Whatsapp has load tested nginx in production with a max of 2.8m connections and 400k new connections per second and capable of handling about 50k requests per second on a single server. They had their server at 3m connections for a bit, but it started to backlog to the point where it had a 15sec backlog. 50k requests per second for 15 seconds is 750k outstanding requests, without crashing. Let me know how Apache would handle that.
A process has at least one thread and threads are bad for scaling. As a rule of thumb, you should not have more threads than 2x your CPU count. The more threads you have, the more pressure you put on the thread scheduler, plus you cause massive cache thrashing and context switching. Many programmers seem to assume threads are cheap and let the thread scheduler handle mutiplexing instead of doing it themselves. On every OS and CPU, this is bad.
There was a lot of talk about Linux's O(1) scheduler, but after it went live, it shortly got changed from the default because it didn't play well with enough common cases on modern system. Whatever the current scaling actually is, the system falls over after too many threads. It seems to be similar to O(n). Eventually your system spends more time scheduling threads than running them. You can have a lot of threads before it becomes an issue, but a modern server with 10gb+ connections, and this becomes an issue.
Whatsapp had an awesome write up on issues they ran into making their servers scale. They where able to run a server in production handling 400k+ connections per second and an average of 2.8m active connections. Their current servers are load balanced to 1/2 that load to give them breathing room. You try making Apache with "threads" handle those kinds of loads. With one thread per connection, you're talking about 2.8 million threads, and at 400k connections per second, you best be using a thread pool and not creating new threads. Then you include them averaging 6.4k requests per second per core, a 24 core server would be processing about 153,000 requests per second. (70m messages/sec over 11,000 cores in their datacenter in 600 servers)
5 MSDN subscriptions ($6000)
Ouch, we only pay $400 per seat for a 2 year license. $200/year/seat
Warning: My Java experience is a bit dated, and some of my issues may have been addressed in recent version, but based on my periodic reading, it seems to be working "as intended" and will never be "fixed".
.Net version running at 99% CPU, I have a Java version running at 70% CPU, and slower per %, because of all of the object work.
.Net is. Threads are the devil when it comes to scaling. I haven't gotten to use DataFlow yet because production is only .Net 4.0, but once we go 4.5, I'm jumping on that also.
One thing that I absolutely hate about Java is the whole, nearly everything is an object, even primitives, in many cases. I have some pretty high performance code in C# where even a single allocation of a small object can quickly turn into hundreds of megs per second. I can quickly get code working in C#, then slowly replace the code from allocating objects to using primitives and value passing or in-place value changes.
Java, on the other hand, decides that ints in generic arrays are immutable objects, meaning every time I change a value, it has to create a new object. There are many other times where Java does similar things where there is no way to cleanly make your code or can't make your code not have to work with objects.
The problem this creates is that high object creation causes lots of garbage collection, which stops world, which causes all of the threads to stop, and the more CPU cores you have, the quicker the GC kicks in. So instead of my
C# gives me the best of both worlds. Quick prototyping in a very clean and strict way, allowing me to define my code in very extendable generic ways but enforce strict usage, while allowing me to eventually micro-optimize without having to sacrifice clean code.
I have programs with thousands of lines of well factored code that has many layers of generic objects and functions, where I can run a 32 core server at a sustained average of 97%+ CPU for hours, crunching data, and use less than 50MB of object allocation.
Another thing C# allows me to do is have some degree of control over data locality. I've had performance gains of over 20% by tweaking classes/structures. Better control of how the data is laid out in memory allowed me to change up my algorithms, causing fewer cache-lines to have to be fetched from memory, reducing memory pressure in L1/L2 cache.
In the end, C#.Net allows me to write "Faster" code than C, because it allows me to quickly and easily make usage of modern multi-core CPUs, while giving me an easy to use and clean language. Java gives me a nice language, but I can't optimize it as well as C#.Net. It could e a limitation of my knowledge, but Java just seems to want to do many things as objects a lot more than C#.
Don't get me started about how awesome async in
The enemy of good is perfect. It's better to design your security around best practices and have recovery modes. My immune system doesn't stop me from getting sick all of the time, but it does a good job recovering. That should be the goal.
The beauty of intro CS classes is you don't need prior knowledge or experience. Anyone with a bit of logic should find it easy. I went into a 4 year, not much more than knowing computers work entirely on numbers. For my first experience in programming, I got dropped into a C/C++ class that dealt with datastructures and algorithms. I think I was the only one who got an A, I never studied, always finished my test 10-15 minutes before everyone else, and did my weekly programming assignments the night before.
A lot of people changed majors after that class. I found it non-challenging, with no prior programming experience, but some stuff was still important.
The 101 classes at my Uni was stuff like, this is a computer, this is Excel. The 106 classes were like, this is a race condition in multithreading. You can skip the intro class that shows you how to turn on a computer, but they're not going to let you skip the other "intro" classes.
Most of the intro classes will teach you stuff that is extremely important, and you'd rarely learn on your own via experience. Most programmers critiquing each other is like the blind leading the blind. Few people in the real world will point out these mistakes and few people in the real world realize that these are mistakes. Learn the basics.
I was a freshman when I learned about SQL injection attacks and how I should never trust the client. The teacher went over many historic examples of programmers making stupid mistakes that mostly involved not validating client input. A lot of the stuff I learned in many of these early 100 level classes, many many programmers don't know about or don't care. The later wouldn't surprise me.
Every time I read about some big security flaw at some big corp web service, I think to myself, they would have failed Programming 101. Don't underestimate intro classes, unless you think your college sucks, then by all means assume the classes are a waste of time.
I take the hybrid approach myself. I identify the issues, come up with some solutions, note the pros and cons, bounce my ideas off my cubical mate. He adds it some ideas and thoughts, then I go back to working on my own again.
Based on the design of many high profile opensource programs, or big projects in general, I assume most seasoned programmers with 10+ years of programming could not test out an intro Computer Science class. CS has little to do with programming and everything to do with theory.