问:
What is the value in hiding the details through abstractions? Isn't there value in transparency?

Background

I am not a big fan of abstraction. I will admit that one can benefit from adaptability, portability and re-usability of interfaces etc. There is real benefit there, and I don't wish to question that, so let's ignore it.

There is the other major "benefit" of abstraction, which is to hide implementation logic and details from users of this abstraction. The argument is that you don't need to know the details, and that one should concentrate on their own logic at this point. Makes sense in theory.

However, whenever I've been maintaining large enterprise applications, I always need to know more details. It becomes a huge hassle digging deeper and deeper into the abstraction at every turn just to find out exactly what something does; i.e. having to do "open declaration" about 12 times before finding the stored procedure used.

This 'hide the details' mentality seems to just get in the way. I'm always wishing for more transparent interfaces and less abstraction. I can read high level source code and know what it does, but I'll never know how it does it, when how it does it, is what I really need to know.

What's going on here? Has every system I've ever worked on just been badly designed (from this perspective at least)?

My philosophy

When I develop software, I feel like I try to follow a philosophy I feel is closely related to the ArchLinux philosophy:

Arch Linux retains the inherent complexities of a GNU/Linux system, while keeping them well organized and transparent. Arch Linux developers and users believe that trying to hide the complexities of a system actually results in an even more complex system, and is therefore to be avoided.

And therefore, I never try to hide complexity of my software behind abstraction layers. I try to abuse abstraction, not become a slave to it.

Question at heart

Is there real value in hiding the details?

Aren't we sacrificing transparency?

Isn't this transparency valuable?

答:
Abstractions are mostly for the benefit of their consumers (e.g., application programmers). The system (designer) programmers have more work to do to make them beautiful and useful, which is why good design is not usually done by beginners.

Maybe you don't like abstractions because they always add complexity? Maybe the systems you've worked on had abstractionitis (over use of abstractions)? They're not a panacea.

The extra work and complexity of a useful abstraction should pay off, but it's hard to know for sure. If you think of an abstraction as a pivot point, then the software design can flex on either side: implementations of the abstraction can be modified without breaking client code, and/or new clients can easily re-use the abstraction to make new things.

You could almost measure the return-on-investment of abstractions by showing that they've been "flexed" over time in one or both of these directions: relatively painless implementation changes and additional new clients.

For example: Using the abstraction of the Socket class in Java, I'm sure my application code from Java 1.2 still works fine under Java 7 (although their may be some performance changes). Since Java 1.2, there have definitely been a lot of new clients that used this abstraction, too.

As for unhappiness with abstractions, if I talked to the developers who maintained the code behind the Socket class, then maybe their lives are not as peachy and rosy as the clients who used Socket to write fun applications. Working on the implementation of an abstraction surely is more work than using it. But that doesn't make it bad.

As for transparency, in a top-down design strategy, total transparency makes for bad design. Smart programmers tend to make the most out of the information they have at their disposal, and the system then becomes tightly coupled. The smallest change of detail (e.g., changing the order of bytes in a data structure) in a module might break some code somewhere else, because a smart programmer used that information to do something useful. David Parnas pointed it out this problem in articles as old as 1971 where he proposed hiding information in designs.

Your reference to ArchLinux makes sense to me if you consider the "inside" of the operating system as being the complex implementation of the abstraction that are the OS to the applications that run on it. Keep it simple in the guts of the abstraction.


问:
Best way of accessing data on different pages
I'm looking for a way to load data into properties/variables etc and have this information accessible to all the pages of my app.
I want the information to be loaded via a background thread to keep UI thread free. Some of the pages will have various properties of their controls binding to these global properties.

Here is what I tried.

Created a static class. All pages could access the data but can't bind.

Changed the static class to a Singleton and used DependencyProperty's. All pages could access data and binding worked fine but cross-threading issues when accessing via background threads.

I have read in various places on this subject but haven't really come up with the best method yet for my situation.

答:
You can't update the UI directly with a background thread in Xaml-based applications.  All UI updates need to be done via the Dispatcher on the UI thread.

To ensure that you are using the Dispatcher thread in a WP7 application (which is really just Silverlight) you would do something like:

```<code>Deployment.Current.Dispatcher.BeginInvoke( () => this.Detail = _staticObject.Detail);
</code>```

ContentLicense: CC BY-SA 3.0

Body:
You can't update the UI directly with a background thread in Xaml-based applications.  All UI updates need to be done via the Dispatcher on the UI thread.

To ensure that you are using the Dispatcher thread in a WP7 application (which is really just Silverlight) you would do something like:

Deployment.Current.Dispatcher.BeginInvoke( () => this.Detail = _staticObject.Detail);


问:
What encryption algorithm/package should I use in a betting game?
I have a betting type site where I publish a number (between 0-100) that is encrypted. Then after a period of time, I would review what the number is and prove it with a key to decrypt the encrypted number to prove that I'm not cheating. I also want it to be easily verifiable by an average user.

What encryption algorithm/technique/package should I use?

I'm no expert on cryptography. There seems to be so many options out there and I'm not sure what to use.

python friendly is a plus.

答:
Use AES.. see Comparison of DES, Triple DES, AES, blowfish encryption for data for details..

As for ease of use.. refer you users to a Site Like: http://www.everpassword.com/aes-encryptor


问:
How to train yourself to avoid writing “clever” code?
Do you know that feeling when you just need to show off that new trick with Expressions or generalize three different procedures? This does not have to be on Architecture Astronaut scale and in fact may be helpful but I can't help but notice someone else would implement the same class or package in a more clear, straightforward (and sometimes boring) manner.

I noticed I often design programs by oversolving the problem, sometimes deliberately and sometimes out of boredom. In either case, I usually honestly believe my solution is crystal clear and elegant, until I see evidence to the contrary but it's usually too late. There is also a part of me that prefers undocumented assumptions to code duplication, and cleverness to simplicity.

What can I do to resist the urge to write “cleverish” code and when should the bell ring that I am Doing It Wrong?

The problem is getting even more pushing as I'm now working with a team of experienced developers, and sometimes my attempts at writing smart code seem foolish even to myself after time dispels the illusion of elegance.

答:
For me, overly-clever code often strives to solve imaginary future requirements instead of focusing on today's requirements.  Big trap!

0% over-complicated code is not an achievable goal.  Maybe not even the best goal to strive for.  Over-complicated code is bad, but you have to try new things in order to grow as a programmer.  You should not try them out on production code if you can avoid it.  Unlike machines, humans make mistakes.

Code reviews help.  Spending years fixing other people's "clever" code helps.  Staying focused on what the client really needs today helps.

Schools and business have crews of clean-up and maintenance people on staff.  Code needs cleanup and maintenance too!  When possible, clean up the messes (your own especially)!  I think that's the best one can do.


问:
How do you name your personal libraries?
I'm pretty bad with naming things.

The only name I can every generically come up with is 'helper'. Say, if I have a header file that contains helping functions for manipulating paths, I tend to put it inside my "helper" directory and call it "path-helper.hpp" or something like that.

Obviouslly, that's a bad naming convention. :)

I want to have a consistent naming scheme for my folder (and namespace) which I can use to always refer to my own headers and libraries, but I have trouble finding names that are easy to type or remember (like boost)... so I end up calling some of them "helper" or "stdext" or whatnot, which isn't a great idea.

How do you find names for your libraries that are easy to remember and easy to type, and which aren't too generic (like "helper" or "std" or "stdext" or the like)?

Any suggestions on how to go about doing this?

答: If it were me, I would just have a path library(well more likely it would be a filesystem library that contained a path component). It would provide the exact interface I need to get the job done.  Sure 90% of it would be a thin wrapper around boost.filesystem or whatever language filesystem lib there was, but my code would only ever see this nice consistent library.  No trying to remember if that function was in X, X-helper, X-utils, or X-ext. If X needs help then it is time to go fix X, not invent new random locations for code. </p>


答:
You shouldn't use a cipher at all, but rather a cryptographic hash. If you state that the string hashed is a random 45-character alphanumeric string (with case), followed by a colon, followed by the number: e.g.

```<code>cxsFiEUK93Pl3e6bR1i40u7EyJgXQXf0JSejsuIQDcoGL:70
</code>```

and that the hash is SHA-256, that's enough for people who know what SHA-256 is to verify it. It's long enough that no-one will realistically be able to brute force it.

You also need to ensure that your random number source is good, and that's harder.

Title: What encryption algorithm/package should I use in a betting game?

Body:
I have a betting type site where I publish a number (between 0-100) that is encrypted. Then after a period of time, I would review what the number is and prove it with a key to decrypt the encrypted number to prove that I'm not cheating. I also want it to be easily verifiable by an average user.

What encryption algorithm/technique/package should I use?

I'm no expert on cryptography. There seems to be so many options out there and I'm not sure what to use.

python friendly is a plus.

Body:
You shouldn't use a cipher at all, but rather a cryptographic hash. If you state that the string hashed is a random 45-character alphanumeric string (with case), followed by a colon, followed by the number: e.g.

cxsFiEUK93Pl3e6bR1i40u7EyJgXQXf0JSejsuIQDcoGL:70

and that the hash is SHA-256, that's enough for people who know what SHA-256 is to verify it. It's long enough that no-one will realistically be able to brute force it.

You also need to ensure that your random number source is good, and that's harder.


问:
Compilable modern alternatives to C/C++
I am considering writing a new software product. Performance will be critical, so I am wary of using an interpreted or language or one that uses a emulation layer (read java).

Which leads me to thinking of using C (or C++) however these are both rather long in the tooth. I haven't used either for a long time. I figured in the last 20 years someone has probably created something which is reasonably popular, nice to code in and compiled.

What more modern alternatives are there to C for writing high performance compiled code?

If C++ is a different beast than it was 15 years ago, I would consider it, I guess I had an assumption that it had some inherent problems.

Parallelisation would be important, but probably not across multiple machines.

答: Vala is similar to Java and C#, compiles to native code (or C source code if you prefer), and is very fast. It does require GLib for its object-oriented bits, and it's written by Linux hackers for Linux hackers, so if your domain is Windows it may not be very good.</p>

ContentLicense: CC BY-SA 4.0

Title: Compilable modern alternatives to C/C++


答:
I'll answer your question with a question; when you drove to work this morning (I'll assume you did in fact do so), did you care exactly how the engine opened valves to let in fuel-air mixtures, and then ignited them? No. You don't care how your car's engine works when you're driving down the road. You care that it does work.

Suppose, one day, your car fails to work. Doesn't start, throws a rod, breaks a belt, inexplicably plows into that concrete barrier through no fault of your own while you were busy texting. Now, you need a new car (at least temporarily). Do you care exactly how this new car works? No. What you care about is first that it does work, and second that you can use the same knowledge and skills that you used to drive your old car to drive the new one. Ideally, it should appear to you that there has been no change in the car you are driving. Realistically, the way this new car works should give you as few "surprises" as possible.

These basic tenets are the core principle behind encapsulation and abstraction. Knowledge of how an object does what it does should not be a requisite to using it to do what it does. Even in computer programming, the details of electrical paths within the CPU running your program are abstracted behind at least half a dozen layers of I/O instructions, drivers, OS software and runtime. Many very successful software engineers write perfectly good code without once worrying about the exact hardware architecture, or even OS build, that will run it. Including me.

Encapsulation/information hiding allows the "don't care how it does, just care that it does" mentality. Your object should expose what is useful to the consumer, in a way that the consumer can easily consume. Now, back in the real world, this doesn't mean that a car shouldn't give the user any information about the inner workings, or that the car should only allow the user the most basic of functionality like the ignition, steering wheel, and pedals. All cars have speedometers and fuel gauges, tachometers, idiot lights, and other feedback. Virtually all cars also have switches for various independent subsystems, like headlights, turn signals, the radio, seat adjustment, etc. Some cars allow for some pretty esoteric user input, like the sensitivity of the limited-slip center differential. In all cases, if you know enough, you can open it up and change things to make it work a slightly different way. But, in most cases, maybe, just maybe, the user shouldn't be able to directly and independently control the fuel pumps from inside the cabin? Maybe, just maybe, the user shouldn't be able to activate their brake lights without actually depressing the brake pedal?

Abstraction allows the "this isn't the same as that, but because they are both X I can use them as I would any X" mentality. If your object inherits or implements an abstraction, your consumers should expect your implementation to produce the same or similar result as other known implementations of the abstraction. A Toyota Camry and a Ford Fusion are both "cars". As such, they have a common set of expected functionality, such as a steering wheel. Turn it counterclockwise, car goes left. Turn it clockwise, car goes right. You can get in any car in the United States and expect the car to have a steering wheel and at least two pedals, the one on the right being the "car goes" pedal and the one in the center being the "car stops" pedal.

A corollary of abstraction is the "theory of least astonishment". If you got behind the wheel of a new car for a test drive, rotated the steering wheel clockwise and the car turned left, you'd be pretty astonished to say the least. You'd accuse the dealer of peddling a POS, and would be unlikely to listen to any of his reasons why the new behavior is "better" than what you're used to, or how well this behavior is "documented" or how "transparent" the control system is. Despite this new car and all the other ones you've driven still being "cars", when driving this car you have to change some fundamental concepts of how a car is supposed to be driven in order to drive the new car successfully. That's typically a bad thing, and it only happens when there is an intuitive advantage to the new paradigm. Perhaps the addition of seat belts is a good example; 50 years ago you just got in and went, but now you have to buckle up, the intuitive advantage being that you don't go through the windshield or into the passenger seat if you get in an accident. Even then, drivers resisted; many car owners cut the seat belts out of the car until laws were passed mandating their use.

Title: What is the value in hiding the details through abstractions? Isn't there value in transparency?

Body:
Background

I am not a big fan of abstraction. I will admit that one can benefit from adaptability, portability and re-usability of interfaces etc. There is real benefit there, and I don't wish to question that, so let's ignore it.

There is the other major "benefit" of abstraction, which is to hide implementation logic and details from users of this abstraction. The argument is that you don't need to know the details, and that one should concentrate on their own logic at this point. Makes sense in theory.

However, whenever I've been maintaining large enterprise applications, I always need to know more details. It becomes a huge hassle digging deeper and deeper into the abstraction at every turn just to find out exactly what something does; i.e. having to do "open declaration" about 12 times before finding the stored procedure used.

This 'hide the details' mentality seems to just get in the way. I'm always wishing for more transparent interfaces and less abstraction. I can read high level source code and know what it does, but I'll never know how it does it, when how it does it, is what I really need to know.

What's going on here? Has every system I've ever worked on just been badly designed (from this perspective at least)?

My philosophy

When I develop software, I feel like I try to follow a philosophy I feel is closely related to the ArchLinux philosophy:

Arch Linux retains the inherent complexities of a GNU/Linux system, while keeping them well organized and transparent. Arch Linux developers and users believe that trying to hide the complexities of a system actually results in an even more complex system, and is therefore to be avoided.

And therefore, I never try to hide complexity of my software behind abstraction layers. I try to abuse abstraction, not become a slave to it.

Question at heart

Is there real value in hiding the details?

Aren't we sacrificing transparency?

Isn't this transparency valuable?


问:
Proper Data Structure for Commentable Comments
Been struggling with this on an architectural level.

I have an object which can be commented on, let's call it a Post. Every post has a unique ID.

Now I want to comment on that Post, and I can use ID as a foreign key, and each PostComment has an ItemID field which correlates to the Post. Since each Post has a unique ID, it is very easy to assign "Top Level" comments.

When I comment on a comment however, I feel like I now need a PostCommentComment, which attaches to the ID of the PostComment. Since ID's are assigned sequentially, I can no longer simply use ItemID to differentiate where in the tree the comment is assigned. I.E. both a Post and a Post Comment might have an ID of '5', so my foreign key relationship is invalid.

This seems like it could go on infinitely, with PostCommentCommentComment's etc...

What's the best way to solve this? Should I have a field in the comment called "IsPostComment" or something of the like to know which collection to attach the ID to? This strikes me as the best solution I've seen so far, but now I feel like I need to make recursive DataBase calls which start to get expensive.

Meaning, I get a Post and get all PostComments where ItemID == Post.ID && where IsPostComment == true

Then I take that as a collection, gather all the ID's of the PostComments, and do another search where ItemID == PostComment[all].ID && where IsPostComment == false, then repeat infinitely.

This means I make a call for every layer, and if I'm calling 100 Posts, I might make 1000 DB calls to get 10 layers of comments each.

What is the right way to do this?

答:
All you need is a PostID for each thing that a user writes, and a ParentPostID that's nullable and points to a parent PostID.  If it's null, it's a Post, and if it's not null, it's a comment.  Comments can have comments.

Basic tree structure.


问:
Why is Clean Code suggesting avoiding protected variables?
Clean Code suggests avoiding protected variables in the "Vertical Distance" section of the "Formatting" chapter:

Concepts that are closely related should be kept vertically close to each other. Clearly this rule doesn't work for concepts that belong in separate files. But then closely related concepts should not be separated into different files unless you have a very good reason. Indeed, this is one of the reasons that protected variables should be avoided.

What is the reasoning?

答:
Yes, I agree that is somewhat strange given that (as I recall) the book also discusses all non-private variables as something to be avoided.

I think the issue with the protected modifier is that not only is the member exposed to subclasses it's also made visible to the entire package. I think it is this dual aspect that Uncle Bob is taking exception to here. Of course, one can't always get around having protected methods, and thus the protected variable qualification.

I think a more interesting approach is to make everything public, that'll force you to have small classes, which in turn renders the whole vertical distance metric somewhat moot.


答:
As it says there, this is only one of the reasons, that is, logically linked code should be placed inside physical linked entities (files, packages and others). On a smaller scale this is the same as the reason you do not put a class which makes DB queries inside the package with classes that displays the UI.

The main reason however that protected variables are not recommended is because they tend to break encapsulation. Variables and methods should have as limited visibility as possible; for further reference see Joshua Bloch's Effective Java, Item 13 - "Minimize the accessibility of classes and members".

However, you should not take all of this ad litteram, only as a guildline; if protected variables are very bad they would not have been placed inside the language in the first place. A reasonable place for protected fields imho is inside the base class from a testing framework (integration test classes extend it).

Title: Why is Clean Code suggesting avoiding protected variables?

Body:
Clean Code suggests avoiding protected variables in the "Vertical Distance" section of the "Formatting" chapter:

Concepts that are closely related should be kept vertically close to each other. Clearly this rule doesn't work for concepts that belong in separate files. But then closely related concepts should not be separated into different files unless you have a very good reason. Indeed, this is one of the reasons that protected variables should be avoided.

What is the reasoning?


答:
In addition to the good advices given until now (code review, debugging, TDD approach)  you should (re)read from time to time the (best books imho) on good coding practices:

Pragmatic programmer

Code Complete

Clean Code

and others, depending on the technology you use.

Title: How to train yourself to avoid writing “clever” code?

Body:
Do you know that feeling when you just need to show off that new trick with Expressions or generalize three different procedures? This does not have to be on Architecture Astronaut scale and in fact may be helpful but I can't help but notice someone else would implement the same class or package in a more clear, straightforward (and sometimes boring) manner.

I noticed I often design programs by oversolving the problem, sometimes deliberately and sometimes out of boredom. In either case, I usually honestly believe my solution is crystal clear and elegant, until I see evidence to the contrary but it's usually too late. There is also a part of me that prefers undocumented assumptions to code duplication, and cleverness to simplicity.

What can I do to resist the urge to write “cleverish” code and when should the bell ring that I am Doing It Wrong?

The problem is getting even more pushing as I'm now working with a team of experienced developers, and sometimes my attempts at writing smart code seem foolish even to myself after time dispels the illusion of elegance.


答:
I am not a big expert of this language, but I think OCaml could be an interesting option to look at.

OCaml is a compiled, functional / object-oriented language.
For a performance comparison with C++ see C++ vs OCaml: Ray tracer comparison.
Of course, this is a very specific example and one should do more extensive testing to have a better feeling of OCaml's performance.

Title: Compilable modern alternatives to C/C++

Body:
I am considering writing a new software product. Performance will be critical, so I am wary of using an interpreted or language or one that uses a emulation layer (read java).

Which leads me to thinking of using C (or C++) however these are both rather long in the tooth. I haven't used either for a long time. I figured in the last 20 years someone has probably created something which is reasonably popular, nice to code in and compiled.

What more modern alternatives are there to C for writing high performance compiled code?

If C++ is a different beast than it was 15 years ago, I would consider it, I guess I had an assumption that it had some inherent problems.

Parallelisation would be important, but probably not across multiple machines.


答:
Uncle Bob's argument is primarily one of distance:  if you have a concept that is important to a class, bundle the concept together with the class in that file.  Not separated across two files on the disk.

Protected member variables are scattered in two places, and, kinda looks like magic.  You reference this variable, yet it isn't defined here... where is it defined?  And thus the hunt begins.  Better to avoid protected altogether, his argument.

Now I don't believe that rule needs to be obeyed to the letter all the time (like: thou shalt not use protected).  Look at the spirit of what he is getting at... bundle related things together into one file - use programming techniques and features to do that.  I would recommend that you don't over-analyze and get caught up in the details on this.


问:
Where does Java get its SOA reputation from?
I see lots of SOA books surrounding Java and have always had the subliminal notion that Java is the "right" language for robust/enterprisey SOA, even though I know what SOA involves and  that it is perfectly possible using other languages & frameworks.

What exclusive traits Java has that other languages/platforms don't, that makes it so popular for SOAs?

答:
What exclusive traits Java has that other languages/platforms don't, that makes it so popular for SOAs?

There's nothing much in Java itself that makes it especially suitable for SOAs. Sure, it offers garbage collection and dynamic code loading and the like, and they're all useful, but they're hardly unique features of Java.

What did make a difference though was the Enterprise Bean specification (which evolved into EJB and JEE). That was basically an adaptation of concepts that had been around for quite a long while in the big-iron space (transaction monitors, that sort of thing) to an OO model, together with the addition of statefulness so that certain types of models were a lot easier to express. The interesting thing is that EJB was a multi-vendor effort; yes, Sun promoted it a lot, but there were many commercial vendors that did implementations of it in their products quite early in the spec's lifecycle. That encouraged a lot of adoption; expertise in Java-based transaction monitors had suddenly become a nice transferrable skill.

Once that base had been established, it grew (e.g., with excellent SOAP tooling support, which superseded the use of CORBA in a lot of deployments) and that's really cemented Java in place. The thing that keeps Java as the king of the SOA space for now is the huge ecosystem of third-party libraries that make it easy to work in the area provided you use Java (or one of the other JVM-based languages, like Groovy or Scala). It's entirely possible to have such libraries in other languages, other environments — I'd expect C# and .NET to do fairly well on this metric — but you typically have to write a much larger fraction of the support layer yourself, and some of that is both tricky and boring to do well; leveraging Java makes a lot of sense if it is keeping you able to focus on the application's business logic and not the support framework.

In short, Java's good for SOA for you because it's good for SOA for many other people (and yes, that's self-reinforcing and sounds tautologous); it's the network effects.


问:
Boundary conditions for testing
Ok so in a programming test I was given the following question.

Question 1 (1 mark)

Spot the potential bug in this section of code:

```<code>void Class::Update( float dt )
{
    totalTime += dt;
    if( totalTime == 3.0f )
    {
        // Do state change
        m_State++;
    }
}
</code>```

The multiple choice answers for this question were.

a) It has a constant floating point number where it should have a named constant variable

b) It may not change state with only an equality test

c) You don't know what state you are changing to

d) The class is named poorly

I wrongly answered this with answer C.

I eventually received feedback on the answers and the feedback for this question was

Correct answer is a.  This is about understanding correct boundary conditions for tests.  The other answers are arguably valid points, but do not indicate a potential bug in the code.

My question here is, what does this have to do with boundary conditions? My understanding of boundary conditions is checking that a value is within a certain range, which isn't the case here. Upon looking over the question, in my opinion, B should be the correct answer when considering the accuracy issues of using floating point values.

答:
I think the test question is ambiguously vague.

The problem, of course, is that you're comparing a floating-point number with something (the type of what is being compared is not specified), whereas comparing within a given range (an epsilon) is more appropriate, because comparing floating point numbers with == is unreliable.

Whether the floating point number is being compared to a "named constant" or not is an irrelevant detail.

Another choice example of how test questions created by academics without field experience generally suck.

Title: Boundary conditions for testing


答:
3.0 is the boundary. that increments m_State when it its reached.

The Point is that 3.0f is hard coded. The Author of the question thinks it should have been a named constant variable.

My question here is, what does this have to do with boundary
  conditions? My understanding of boundary conditions is checking that a
  value is within a certain range, which isn't the case here

So yes, that is the case here.

Title: Boundary conditions for testing

Body:
Ok so in a programming test I was given the following question.

Question 1 (1 mark)

Spot the potential bug in this section of code:

```<code>void Class::Update( float dt )
{
    totalTime += dt;
    if( totalTime == 3.0f )
    {
        // Do state change
        m_State++;
    }
}
</code>```

The multiple choice answers for this question were.

a) It has a constant floating point number where it should have a named constant variable

b) It may not change state with only an equality test

c) You don't know what state you are changing to

d) The class is named poorly

I wrongly answered this with answer C.

I eventually received feedback on the answers and the feedback for this question was

Correct answer is a.  This is about understanding correct boundary conditions for tests.  The other answers are arguably valid points, but do not indicate a potential bug in the code.

My question here is, what does this have to do with boundary conditions? My understanding of boundary conditions is checking that a value is within a certain range, which isn't the case here. Upon looking over the question, in my opinion, B should be the correct answer when considering the accuracy issues of using floating point values.


问:
Why are cryptic short identifiers still so common in low-level programming?
There used to be very good reasons for keeping instruction / register names short. Those reasons no longer apply, but short cryptic names are still very common in low-level programming.

Why is this? Is it just because old habits are hard to break, or are there better reasons?

For example:

Atmel ATMEGA32U2 (2010?): TIFR1 (instead of TimerCounter1InterruptFlag), ICR1H (instead of InputCapture1High), DDRB (instead of DataDirectionPortB), etc.

.NET CLR instruction set (2002): bge.s (instead of branch-if-greater-or-equal.short), etc.

Aren't the longer, non-cryptic names easier to work with?

When answering and voting, please consider the following. Many of the possible explanations suggested here apply equally to high-level programming, and yet the consensus, by and large, is to use non-cryptic names consisting of a word or two (commonly understood acronyms excluded).

Also, if your main argument is about physical space on a paper diagram, please consider that this absolutely does not apply to assembly language or CIL, plus I would appreciate if you show me a diagram where terse names fit but readable ones make the diagram worse. From personal experience at a fabless semiconductor company, readable names fit just fine, and result in more readable diagrams.

What is the core thing that is different about low-level programming as opposed to high-level languages that makes the terse cryptic names desirable in low-level but not high-level programming?

答:
The reason the software uses those names is because the datasheets use those names.  Since code at that level is very difficult to understand without the datasheet anyway, making variable names you can't search is extremely unhelpful.

That brings up the question of why datasheets use short names.  That's probably because you often need to present the names in tables like this where you don't have room for 25-character identifiers:

Also, things like schematics, pin diagrams, and PCB silkscreens often are very cramped for space.


答:
The right answer should be b. All other points are somewhat valid1 as well, but comparing floating point values for equality is something that should be done with a lot of care.

For example, adding ten 0.2s and ten 0.1s makes a 3 that is not equal to 3.0 (link to ideone).

Using "magic numbers" and using non-descriptive class names are wrong things too, but they are not errors. Comparing a floating-point constant for equality, on the other hand, is nearly certainly an error.

1 Except c: it's a classic "nonsensical" answer.

Title: Boundary conditions for testing


答:
Apart from the "old habits" reasons,  Legacy code that was written 30 years ago and is still in use is very common. Despite what some less experienced people think, refactoring these systems so they look pretty comes at a very high cost for a small gain and is not commercially viable.

Embedded systems that are close to the hardware - and accessing registers, tend to use the same or similar labels to those used in the Hardware data sheets, for very good reasons. If the register is called XYZZY1 in the hardware data sheets, it makes sense the Variable representing it is likely XYZZY1, or if the programmer was having a good day, RegXYZZY1.

As far as the bge.s, it's similar to assembler - to the few people who need to know it longer names are less readable. If you cannot get you head around bge.s and think branch-if-greater-or-equal.short will make a difference - you are merely playing with the CLR and do not know it.

The other reason that you will see short variable names is due to wide spread us of abbreviations within the domain the software is targeting.

In summary - short abbreviated variable names that reflect an External influence such as industry norms and hardware data sheets are expected. Short abbreviated variable names that are internal to the software are normally less desirable.

Title: Why are cryptic short identifiers still so common in low-level programming?

Body:
There used to be very good reasons for keeping instruction / register names short. Those reasons no longer apply, but short cryptic names are still very common in low-level programming.

Why is this? Is it just because old habits are hard to break, or are there better reasons?

For example:

Atmel ATMEGA32U2 (2010?): TIFR1 (instead of TimerCounter1InterruptFlag), ICR1H (instead of InputCapture1High), DDRB (instead of DataDirectionPortB), etc.

.NET CLR instruction set (2002): bge.s (instead of branch-if-greater-or-equal.short), etc.

Aren't the longer, non-cryptic names easier to work with?

When answering and voting, please consider the following. Many of the possible explanations suggested here apply equally to high-level programming, and yet the consensus, by and large, is to use non-cryptic names consisting of a word or two (commonly understood acronyms excluded).

Also, if your main argument is about physical space on a paper diagram, please consider that this absolutely does not apply to assembly language or CIL, plus I would appreciate if you show me a diagram where terse names fit but readable ones make the diagram worse. From personal experience at a fabless semiconductor company, readable names fit just fine, and result in more readable diagrams.

What is the core thing that is different about low-level programming as opposed to high-level languages that makes the terse cryptic names desirable in low-level but not high-level programming?


答:
I think the real bug in the code resides in the fact that there's a possibility that the code adds the input together and expects it to reach a certain value. This may never happen.

Consider this case:

```<code>Update(0.1f);
Update(1.1f);
Update(0.2f);
Update(1.8f);
</code>```

After the last call to Update, the internal TotalTime variable has the value of (0.1+1.1+0.2+1.8) 3.2f (disregarding possible floating-point errors). As such, the test for TotalTime == 3.0f will fail from that point onwards, nothing will ever fix that problem during program's lifetime (except potential variable wrap-around).

This problem has nothing to do with the input being floating-point (although it too is a valid problem in this case), however. A similar problem may arise even if the input was integers. Consider the case where Update() takes the dt variable as milliseconds and as such it's integer. What if the comparison then was something like if(TotalTime == 3000) { (to test for a possibility that TotalTime has cumulated to 3000 millisecond). What if the function input never accumulates to exactly 3000? What if it is exactly 2999 at some point, and then the function is called with the value of 2? The TotalTime variable grows from 2999 to 3001, and as such never reaches 3000, and as such the test fails.

To fix this problem the test should use the >= operator instead which asserts that the "TotalTime is 3.0f or more". In such case no bug would occur regardless of the input to the function.

As such, I don't believe given answers are sufficient.

Title: Boundary conditions for testing

Body:
I think the real bug in the code resides in the fact that there's a possibility that the code adds the input together and expects it to reach a certain value. This may never happen.

Consider this case:

Update(0.1f);
Update(1.1f);
Update(0.2f);
Update(1.8f);

After the last call to Update, the internal TotalTime variable has the value of (0.1+1.1+0.2+1.8) 3.2f (disregarding possible floating-point errors). As such, the test for TotalTime == 3.0f will fail from that point onwards, nothing will ever fix that problem during program's lifetime (except potential variable wrap-around).

This problem has nothing to do with the input being floating-point (although it too is a valid problem in this case), however. A similar problem may arise even if the input was integers. Consider the case where Update() takes the dt variable as milliseconds and as such it's integer. What if the comparison then was something like if(TotalTime == 3000) { (to test for a possibility that TotalTime has cumulated to 3000 millisecond). What if the function input never accumulates to exactly 3000? What if it is exactly 2999 at some point, and then the function is called with the value of 2? The TotalTime variable grows from 2999 to 3001, and as such never reaches 3000, and as such the test fails.

To fix this problem the test should use the >= operator instead which asserts that the "TotalTime is 3.0f or more". In such case no bug would occur regardless of the input to the function.

As such, I don't believe given answers are sufficient.


问:
Five new junior developers and lots of complex tasks. What's now?
Our company has hired five new junior developers to help me to developer our product. Unfortunately the new features and incoming bug fixes usually require deeper knowledge than a recently graduated developer usually has (threading/concurrency, debugging performance bottlenecks in a complex system, etc.)

Delegating (and planning) tasks which they (probably) can solve, answering their questions, mentoring/managing them, reviewing their code use up all of my time and I often feel that I could solve the issues less time than the whole delegating process takes (counting only my time). In addition I don't have time to solve the tasks which require deeper system knowledge/more advanced skills and it does not seem that it will change in the near future.

So, what's now? What should I do to use their and my time effectively?

答:
Teach them. Assign them tasks which they can easily solve.

Simply put, the issue is that the said workforce is not skilled enough to be very productive with the task they have. As such, you can either 1) ease the task 2) try to increase the skill of the workforce.

Similar problem almost always happens(to some extent) whenever a new person joins a team and starts working on a codebase he/she has no experience of. This becomes more of a problem if the tools and methodologies are unknown. By training the person to become more familiar with the tools and methodologies the problem can be easened faster.

However, solving such a problem takes time - one can't just expect others to know everything or learn everything in a single moment. Perhaps introducing some books about concurrency, software optimization and general methodologies needed would be a good start.


问:
Is the .NET/Microsoft technology stack a financially viable option for a startup with limited finances?
I have an unpaid internship for a very new startup company with little tech experience that's trying to be a Groupon clone. They're currently using Wordpress and I've been trying to decide what web framework to push them towards, since I'll have to learn that language and implement it as well.

Is ASP.Net MVC a realistic option for a web based startup company with little financial backing? For example, I know in the Rails hosting is slightly cheaper because of the whole free OS thing and there are free "gems" available to do things like a mailers, but how much more expensive can it get if I go with ASP.Net MVC since such add-ons stop being open source?

How much does the cost of hosting for .NET applications add to the equation?

答:
If I can be quite honest here, I was in the same situation you're in. I wanted to host a Rails applications because I was under the impression that it was cheaper to host. After all, it's Open Source right?

Not the case.

In fact, almost every Rails project has to be run on a high-tier hosting such as Heroku (initial costs about 39$), because if you run it on a shared environment you are bound to find trouble with incompatibilities.

What is the .NET alternative? Well, it's the same price and some cases even cheaper. Take for example Softsys Hosting's Eco 1 Package - it costs 15$/month and you get all those specs. More than enough for starting and you receive a full on stack.

As you can see, empirically, cost is not that different.

Visual Studio? Free.

Entity Framework? Free.

SQL Server? Free (for starter needs)

I have launched three websites already using full on Microsoft .NET stacks and have not paid a dime for "licensing fees" just hosting fees.


问:
What exactly do I have to pay attention for when choosing Windows Hosting Provider?
This is my first time choosing a hosting company. It is for a web site made in asp.net mvc3.

So I was thinking choosing a provider would be easy since I found this page
http://www.microsoft.com/web/Hosting/Home which contains hosting offers.

Now hours later, I am still searching.

The reason is that as soon as I start investigating about particular company, something stands out that I do not like.

Here are some examples what I noticed when checking various companies in more detail:

Company "about us" page is lacking in information about their company.

Few of them had just general description what they do and nothing else, while some others had information like company name but had no address.

Checking company name in Business Registry Searches gave no results.

Two of the companies I checked had both company name and address but I was unable to find them in the registry.

Putting company domain into Google gave mostly results from that domain or web hosting review sites but not much else.

I am assuming that good companies should have search results from other sites too.

Low Alexa Traffic Rank.

There was one company which had a site that looked very professional but their alexa traffic ranking was like 2 million.

Are there any other factors I should pay attention to when choosing a hosting company?

Do I have legitimate concerns or am I just too paranoid?

答:
even though most companies say Medium trust - they wont give truely Medium - so some logging and etc will not work... please do plan before what all u want to use and get into choosing - or choose a comapny like Amazon - its relatively cheaper and have lot to offer !

Most of the small / medium sized hosting companies gives u monthly billing etc - use those to test -


答:
Why people always insist on looking for new languages?

C++:

Is the number 4 language by TIOBE, but stomps all competition if combined with C

Has lots of frameworks

Is very easy to code in

Is very easy to tune

Is very performant

Is very safe

Has a very good industry support

Is cross platform

Doesn't need extra VMs/Frameworks/deployment mess if done correctly

Will easily land you a job

Has all the necessary stuff to build .so/.dll to launch on very old systems

Easy to troubleshoot

Very expressive

Very dynamic

and bunch of other interesting stuff

The only downside of C++ is that you have to learn a bit. That's it.

Compare that to other languages which are one or more of:

Narrowly supported (OCML, Fortran, ...)

Slow (Java, Javascript)

Experimental (Silverlight)

A moving target (.NET 1/2/3/4/5? which one is the last one now?)

Platform locked (.NET)

Have poor framework support (Fortran)

Has small communities (anything outside top 10)

Are nightmare to troubleshoot (Anything with high-level fool-proof concepts and stuff)

Needs 500MB of preintallation on customers machine (JVM/.NETVM)

IMHO, the less languages we will use and support, the better the situation will be.

This causes automatic improvements in frameworks for the language, support, documentation, standardization committees work, better books, more knowledge, easier to support software, better patterns, longer language support cycles and more skilled code written in the language.

I know people will downvote this, but think about it, really.

Title: Compilable modern alternatives to C/C++


答:
It sounds that you were not part of the hiring decision. Make a fair assessment to their abilities to handle current tasks. Write down a report with a recommendation (external training and such tasks as long as it does not affect your delivery time), send the report to your manager whom may start talking to whomever hired those guys. One new person may be absorbed in a team but 5 new people at once, does not sound good unless you have a relaxed shop. Whatever you do don't try to teach them on your project time unless this is accounted for in the plan.

Edit:
It may be appropriate to mention Brook's Law in this situation.

Title: Five new junior developers and lots of complex tasks. What's now?

Body:
Our company has hired five new junior developers to help me to developer our product. Unfortunately the new features and incoming bug fixes usually require deeper knowledge than a recently graduated developer usually has (threading/concurrency, debugging performance bottlenecks in a complex system, etc.)

Delegating (and planning) tasks which they (probably) can solve, answering their questions, mentoring/managing them, reviewing their code use up all of my time and I often feel that I could solve the issues less time than the whole delegating process takes (counting only my time). In addition I don't have time to solve the tasks which require deeper system knowledge/more advanced skills and it does not seem that it will change in the near future.

So, what's now? What should I do to use their and my time effectively?


问:
Arguments for development environment being the same as production
Intuitively it seems appropriate that the development environment (and all test environments) be as close to the production build as possible. Are there any documented arguments in support of this intuition?</p>

答:
It's one of the founding principles of continuous delivery that your integration tests and manual tests need to run in a "production-like" environment in order to have any assurance of a stable release. The more production-like your testing and staging environments are, the more confident you can be, up to and including the point of daytime fire-and-forget releases.

That being said, your development environment does not need to be the same as production, and it definitely should not have production data - privacy leaks, ad-hoc updates, all sorts of problems there. Integration happens after your code leaves the development environment (specifically, in your CI environment, assuming you have one), and most teams don't run integration tests locally, so mirroring production in dev won't be that helpful since your code and unit tests are generally going to abstract away any environmental dependencies (assuming that you've designed them correctly).

It is, however, useful to use the same deployment scripts for both local/dev and test/staging/prod, because it adds another layer of testing to the deployment itself and helps you refine your process. But it doesn't need to be the same. It's not really cost-effective to buy an Oracle license for every single dev box, for example, so don't count on perfect consistency.


答:
Maybe you can spend some time creating a sandbox environment where you can throw them in to tackle some of the tough problems without doing harm.  Have them test their solutions as thoroughly as they can.  Put more than 1 on the same problem.

All of these things give them the possibility of getting skilled enough to be useful, plus they require less of your time.  Of course if you have them (mostly) sink or swim and they pretty much sink then you have to rethink things.

In the programming profession people who can't learn mostly on their own probably aren't really worth the effort it would take to teach them.  But I think they will probably mostly surprise you with how well they get on when you cut back on the help.


答:
Pair Programming sounds like a great possibility here.

Give four of them two of the simpler of these bugs, let them pair up and have each pair tackle one of them.

Phrase this request as, "Can you figure out what's causing this?".  Don't get them to start thinking about how to fix it yet.

Once they do have some level of an explanation, then ask them how it might be fixed.  This way they won't get as overwhelmed with a huge task all at once.  Let them go and experiment with the code if they haven't already, and once they have a plan - even a vague one - you can guide them towards a good solution.

The other one, you can pair with and start working on one of the harder ones with him.  This may be more difficult given his inexperience with the code, but he'll also have the benefit of someone with experience going through it with him.

I think a new feature might be a good way to do this, given your experience.  You can show him the existing API as the new feature gets developed.

For an anecdote/example of this suggestion working:  This was how I was introduced to the hairiest part of the codebase I work on - with the other relatively new developer I was paired with, we ended up doing something like this:

We were given a bug, and after about a 10 minute introduction, were told to try and figure out what was going on.

About an hour in, we split up and dug into two different trains of thought.

About two hours after that, I figured out in general how the code worked, but didn't know exactly where the bad output was being generated.  He figured out how it was being generated, by digging into the raw and the denormalized data, but couldn't figure out the code.

We paired back up and followed the code paths together, and got an exact answer.  From this, we brainstormed with our manager some possible solutions, and ended up implementing it later on.

I've since inherited maintenance of that entire part of the codebase, since I'm really the only one who understands how it works anymore (the original developers who are still around don't even fully recall).


答:
Similarly to GlenH7, I tend to have a "-misc" library, where org is a three or four letter abbreviation for whoever my current employer happens to be.

Any new random functions get put there until enough of them have accumulated for a pattern to emerge. At that point, I group them together and pull out related functions into more-sensibly-named libraries, refactoring client code as needed.

Sometimes a bit of discipline has been required to keep the size of the library manageable, but these days my *-misc libraries tend to stay pretty small.

(I also always have a "devauto" and a "testauto" library that contain "meta-level" functions intended to support development and test automation).

Title: How do you name your personal libraries?

Body:
I'm pretty bad with naming things.

The only name I can every generically come up with is 'helper'. Say, if I have a header file that contains helping functions for manipulating paths, I tend to put it inside my "helper" directory and call it "path-helper.hpp" or something like that.

Obviouslly, that's a bad naming convention. :)

I want to have a consistent naming scheme for my folder (and namespace) which I can use to always refer to my own headers and libraries, but I have trouble finding names that are easy to type or remember (like boost)... so I end up calling some of them "helper" or "stdext" or whatnot, which isn't a great idea.

How do you find names for your libraries that are easy to remember and easy to type, and which aren't too generic (like "helper" or "std" or "stdext" or the like)?

Any suggestions on how to go about doing this?


答:
The basic idea is that a "field" (instance-level variable) that is declared as protected is probably more visible than it has to be, and less "protected" than you might like. There is no access modifier in C/C++/Java/C# that is the equivalent of "accessible only by child classes within the same assembly", thus granting you the ability to define your own children that can access the field in your assembly, but not allowing children created in other assemblies the same access; C# has internal and protected modifiers, but combining them makes the access "internal or protected", not "internal and protected". So, a field that is protected is accessible by any child, whether you wrote that child or someone else did. Protected is thus an open door to a hacker.

Also, fields by their definition have pretty much no validation inherent in changing them. in C# you can make one readonly, which makes value types effectively constant and reference types  unable to be reinitialized (but still very mutable), but that's about it. As such, even protected, your children (which you cannot trust) have access to this field and can set it to something invalid, making the object's state inconsistent (something to be avoided).

The accepted way to work with fields is to make them private and access them with a property, and/or a getter and setter method. If all consumers of the class need the value, make the getter (at least) public. If only children need it, make the getter protected.

Another approach that answers the question is to ask yourself; why does code in a child method need the ability to modify my state data directly? What does that say about that code? That's the "vertical distance" argument on its face. If there is code in a child that must directly alter parent state, then maybe that code should belong to the parent in the first place?


问:
Why do we have to use break in switch?
Who decided (and based on what concepts) that switch construction (in many languages) has to use break in each statement?

Why do we have to write something like this:

```<code>switch(a)
{
    case 1:
        result = 'one';
        break;
    case 2:
        result = 'two';
        break;
    default:
        result = 'not determined';
        break;
}
</code>```

(noticed this in PHP and JS; there are probably many other languages using this)

If switch is an alternative of if, why we can't use the same construction as for if? I.e.:

```<code>switch(a)
{
    case 1:
    {
        result = 'one';
    }
    case 2:
    {
        result = 'two';
    }
    default:
    {
        result = 'not determined';
    }
}
</code>```

It is said that break prevents the execution of the block following the current one. But, does someone really run into the situation, where there was any need for execution of the current block and following ones? I didn't. For me, break is always there. In every block. In every code.

答:
Not forcing the break allows a number of things that could otherwise be difficult to do.  Others have noted grouping cases, for which there are a number of non-trivial cases.

One case where it is imperative that the break not be used is Duff's Device. This is used to "unroll" loops where it can speed up operations by limiting the number of comparisons required. I believe the initial use allowed functionality which had previously been too slow with a fully rolled up loop. It trades of code size for speed in some cases.

It is good practice to replace the break with an appropriate comment, if the case has any code. Otherwise, someone will fix the missing break, and introduce a bug.

Title: Why do we have to use break in switch?


问:
How much overhead is there in persistent connections?
Ok so I'm musing over a little side project I want to start. Essentially its a multi-session web based FTP client. Multi-session in that you can log into several FTP servers at the same time and perform operations like moving a file from one FTP server to another.

I'm doing this mainly to brush up on the new webdev technologies, particularly websockets. I'm using node.js + socket.io to keep a persistent bi-directional connection between the web browser and the web server. The web server will also have persistent connections to each FTP server the user has logged into. So if there are 100 concurrent users each logged into 5 ftp accounts, the web server will have 100 websocket connections + 500 ftp connections.

Is servicing 600 connections a lot? I know it depends on the hardware resources of the server but is something like this doable on a budget? Are there more efficient means of doing something like this? I know its unlikely that this project will really get popular but I want it to scale well regardless.

Thanks for any help, I've still got a lot to learn.

答:
600 persistent connections should not be an issue - in general connecting overhead is high compared to idle connection overhead(especially if using secure, handshake-based protocol such as TLS), so keeping connections open rather than closing and opening them upon actions definitely reduces the amount of load on the server(and the network, for that matter).

Of course, this is hardware and network dependent, but the numbers you're aiming for right now should very well be doable without considerable resource dedication.


问:
Is my DFD accurate?
This is my first ever DFD that I made after my fair share of learning but I have no way of verifying whether it is correct or not. Although I have taken utmost care to make sure it is right, I may be wrong.

Here is the scenario:

Bebop Records is a mail-order company that distributes CDs and tapes at discount prices to record club members.  When an order processing clerk receives an order form, he or she verifies that the sender is a club member by checking the Member file.  If the sender is not a member, the clerk returns the order along with a membership application form.  If the customer is a member, the clerk verifies the order item data by checking the Item file.

Then the clerk enters the order data and saves it to the Daily Order file. The clerk also prints an invoice and shipping list for each order, which are forwarded to Order Fulfilment.

And here is my diagram:

答:
Tom DeMarco invented Data Flow Diagrams, and described them in his book, "Structured Analysis and System Specification".  One of his key points was that they're either right or they're OBVIOUSLY wrong.

Your DFD appears, unfortunately, to fall in the latter category.

Your text spec says that the clerk RETURNS non-member order forms, presumably to the customer, along with a blank membership form.

Your DFD, however, shows a non-member order form as going to Order Fulfillment, having gone through all the stages, just like a member order form.

Title: Is my DFD accurate?


问:
ReSharper's effect on coding interviews
Anyone who has used R# or CodeRush knows how fast you can put together simple constructs (and refactor complex ones) with a simple keyboard shortcut.  However, do these productivity plugins cause a false evaluation of ability during interviews?

Part of being a productive code writer (and making a good first impression in an interview) is writing good code - fast.

If I had two candidates:

Doesn't use plugins.  She thinks about the problem, sits down at a stock IDE at the interview PC that looks exactly like hers and types out the code in a minute or two, as usual.  Done.  Pass.

Uses plugins.  He thinks about the problem, sits down at a stock IDE at the interview PC and realizes "fe + tab" no longer writes a foreach loop automatically, and all the shortcuts are gone.  He then bumbles around the keyboard hitting his normal hotkeys and popping up strange windows and getting flustered.  It takes him 3 minutes to write what normally would take 30 seconds.  Done.  Looked like they didn't know their way around the IDE at times.  Must be new to this IDE and thus not had much experience with it or maybe the language.  Pass, but a 'meh' mark beside their name.

In your experience, how do you handle plugins during interviews as the interviewer or interviewee?  What are the best practices to getting what the candidate really knows?  There can be candidates who don't understand code, and use R# as a crutch.  There can also be candidates who know the code in and out and use R# because it's just plain faster than the built in VS or Eclipse templates.  Is it best to just not use an IDE at all?  Let them bring their own PC?  Others?

答:
I was a candidate 2 in an interview very recently. I was given a vanilla install of the IDE on a PC with a non-standard keyboard and unfamiliar testing framework, and I was asked to write a simple Fizz-Buzz app with unit tests. I fluffed it. I must have looked like a complete noob, stumbling around in the dark trying to hack out code. Needless to say, I wasn't offered the position.

What I learned is that I rely very heavily on my plugins. They don't just get code typed faster - they actually shape the way I think about code and the way I go about coding. For example, I used to think very carefully about variable names because they could be a pain to change after the fact. Now, in contrast, I just make a half-baked guess about how I'll use the variable, hack out some code, let the variable tell me what it is for, and then hit Refactor->Rename to call it something more appropriate.

Does this make me the less capable candidate? In some ways, I think it does. Someone who can write code in Notepad and have it compile and run correctly has certain advantages over someone like me who needs all the IDE goodness he can get. From that point of view, I perfectly understand why any company would choose not to hire a toolhead like me.

On the other hand, I'm still a talented and capable Senior Developer. I've learned what works for me, and I practice the sort of laziness that makes me productive, given my own weaknesses and limitations. In short, I'm the kind of programmer that could really benefit a company like the one who turned me away.

Interestly, I had another interview a couple of weeks ago. Following my previous experience I made a point of asking about additional tools or budget for buying them. Discovering that there were neither gave me one more reason for turning down to the (rather generous) offer that they made to me.

So, to paraphrase Groucho, "I would not join any company that would have someone like me for an employee."

Not unless they let me use ReSharper, anyway.

ContentLicense: CC BY-SA 2.5

Title: ReSharper's effect on coding interviews


答:
In C, where the origin seems to be, the code block of the switch statement is not a special construct. It is a normal block of code, just as a block under an if statement.

```<code>switch ()
{
}

if ()
{
}
</code>```

case and default are jump labels inside this block, specifically related to switch. They are handled just as normal jump labels for goto. There is one specific rule that is important here: Jump labels can be nearly everywhere in the code, without interrupting the code flow.

As a normal code block, it doesn't need to be a compound statement. The labels are optional, too. These are valid switch statements in C:

```<code>switch (a)
    case 1: Foo();

switch (a)
    Foo();

switch (a)
{
    Foo();
}
</code>```

The C standard itself gives this as an example (6.8.4.2):

```<code>switch (expr)
{
    int i = 4;
    f(i);
  case 0:
    i=17;
    /*falls through into default code */
  default:
    printf("%d\n", i);
}
</code>```

In the artificial program fragment, the object whose identifier is i exists
  with automatic storage duration (within the block) but is never initialized,
  and thus if the controlling expression has a nonzero value, the call to the
  printf function will access an indeterminate value. Similarly, the call to the
  function f cannot be reached.

Furthermore, default is a jump label, too, and thus can be anywhere, without the need to be the last case.

This also explains Duff's Device:

```<code>switch (count % 8) {
    case 0: do {  *to = *from++;
    case 7:       *to = *from++;
    case 6:       *to = *from++;
    case 5:       *to = *from++;
    case 4:       *to = *from++;
    case 3:       *to = *from++;
    case 2:       *to = *from++;
    case 1:       *to = *from++;
            } while(--n > 0);
}
</code>```

Why the fall-through? Because in the normal code flow in a normal block of code, fall-through to the next statement is expected, just as you would expect it in an if code block.

```<code>if (a == b)
{
    Foo();
    /* "Fall-through" to Bar expected here. */
    Bar();
}

switch (a)
{
    case 1:
        Foo();
        /* Automatic break would violate expected code execution semantics. */
    case 2:
        Bar();
}
</code>```

My guess is that the reason for this was ease of implementation. You don't need special code for parsing and compiling a switch block, caring for special rules. You just parse it like any other code and only have to care for the labels and the jump selection.

An interesting follow-up question from all this is if the following nested statements print "Done." or not.

```<code>int a = 10;

switch (a)
{
    switch (a)
    {
        case 10: printf("Done.\n");
    }
}
</code>```

The C standard cares for this (6.8.4.2.4):

A case or default label is accessible only within the closest enclosing switch statement.

Title: Why do we have to use break in switch?

Body:
Who decided (and based on what concepts) that switch construction (in many languages) has to use break in each statement?

Why do we have to write something like this:

```<code>switch(a)
{
    case 1:
        result = 'one';
        break;
    case 2:
        result = 'two';
        break;
    default:
        result = 'not determined';
        break;
}
</code>```

(noticed this in PHP and JS; there are probably many other languages using this)

If switch is an alternative of if, why we can't use the same construction as for if? I.e.:

```<code>switch(a)
{
    case 1:
    {
        result = 'one';
    }
    case 2:
    {
        result = 'two';
    }
    default:
    {
        result = 'not determined';
    }
}
</code>```

It is said that break prevents the execution of the block following the current one. But, does someone really run into the situation, where there was any need for execution of the current block and following ones? I didn't. For me, break is always there. In every block. In every code.

Body:
In C, where the origin seems to be, the code block of the switch statement is not a special construct. It is a normal block of code, just as a block under an if statement.

switch ()
{
}

if ()
{
}

case and default are jump labels inside this block, specifically related to switch. They are handled just as normal jump labels for goto. There is one specific rule that is important here: Jump labels can be nearly everywhere in the code, without interrupting the code flow.

As a normal code block, it doesn't need to be a compound statement. The labels are optional, too. These are valid switch statements in C:

switch (a)
    case 1: Foo();

switch (a)
    Foo();

switch (a)
{
    Foo();
}

The C standard itself gives this as an example (6.8.4.2):

switch (expr)
{
    int i = 4;
    f(i);
  case 0:
    i=17;
    /*falls through into default code */
  default:
    printf("%d\n", i);
}

In the artificial program fragment, the object whose identifier is i exists
  with automatic storage duration (within the block) but is never initialized,
  and thus if the controlling expression has a nonzero value, the call to the
  printf function will access an indeterminate value. Similarly, the call to the
  function f cannot be reached.

Furthermore, default is a jump label, too, and thus can be anywhere, without the need to be the last case.

This also explains Duff's Device:

switch (count % 8) {
    case 0: do {  *to = *from++;
    case 7:       *to = *from++;
    case 6:       *to = *from++;
    case 5:       *to = *from++;
    case 4:       *to = *from++;
    case 3:       *to = *from++;
    case 2:       *to = *from++;
    case 1:       *to = *from++;
            } while(--n > 0);
}

Why the fall-through? Because in the normal code flow in a normal block of code, fall-through to the next statement is expected, just as you would expect it in an if code block.

if (a == b)
{
    Foo();
    /* "Fall-through" to Bar expected here. */
    Bar();
}

switch (a)
{
    case 1:
        Foo();
        /* Automatic break would violate expected code execution semantics. */
    case 2:
        Bar();
}

My guess is that the reason for this was ease of implementation. You don't need special code for parsing and compiling a switch block, caring for special rules. You just parse it like any other code and only have to care for the labels and the jump selection.

An interesting follow-up question from all this is if the following nested statements print "Done." or not.

int a = 10;

switch (a)
{
    switch (a)
    {
        case 10: printf("Done.\n");
    }
}

The C standard cares for this (6.8.4.2.4):

A case or default label is accessible only within the closest enclosing switch statement.


问:
Is it a common practice to minimize JavaScript usage when building a website?
I've been a web developer for almost 10 years and I've gotten into the habit of trying not to use JavaScript whenever possible. I'm not talking about building web apps here, but database driven websites.

Is this a good/respected approach?

答:
JavaScript usage can be limited in several cases:

Validation. It has to be done on server-side. Sometimes in web applications there is a quick client-side validation, but it alone isn't enough.

Extremely important tasks. Users can choose to disable their browsers' scripts, so the JS code will not work at all. If you want to be sure that something will work in any case on any browser, don't trust it to JS.

Speed. The JS code has to be sent to client, and the more code you write, the longer it takes. Though small amounts of code will have no practical effect.

JS has a huge bunch of features, which can't be replaced by server-side code. Other than those above, I don't think there would be any reasonable argument to limit JS usage.


答:
In times gone by, JavaScript was used and abused, and scripts were (perceived to be) full of vulnerabilities, and a source of malware.

Many corporate networks responded by disabling JS, a policy that (rightly or wrongly) still exists in many organisations today.

Quite simply, I suggest that no site should rely on JS to operate

Title: Is it a common practice to minimize JavaScript usage when building a website?

Body:
I've been a web developer for almost 10 years and I've gotten into the habit of trying not to use JavaScript whenever possible. I'm not talking about building web apps here, but database driven websites.

Is this a good/respected approach?


答:
I don't expect this answer will be highly upvoted or very popular as I know people love to develop on their platform of choice, but here it goes...

I once witnessed a developer spend 12 hours attempting to replicate a single dependencies installation on his Macbook Pro.  If you are doing enterprise development you will have many dependencies.  Often with inter-os dependencies someone other than the original author re-packages the content and releases it with a slightly modified code base.

I would be very wary of any developer attempting to develop long-term in an environment that was not production.  Not only would the time taken for him to manage his own environment be largely wasted when automated processes already exist to setup the production environment he's risking adding features and adding dependencies unknowingly that may not work altogether.

In my organization we go so far as to have bulk unit-tests to know everytime a python package changes version.  Sometimes it happens unintentionally and when it does we want to know.  A good exmaple of this is PyMssql and this bug -> http://code.google.com/p/pymssql/issues/detail?id=98

Lastly, I can't understand these claiming to be "agile" development teams that require everyone to continually commit their code.  "If it's not in Version Control it doesn't exist!" - and then they turn around and have a completely laxed attitude about the environments, modules, version, being developed in.  How about "if it's not developed within production environments it doesn't exist" ??

Title: Arguments for development environment being the same as production

Body: Intuitively it seems appropriate that the development environment (and all test environments) be as close to the production build as possible. Are there any documented arguments in support of this intuition?</p>


答:
10 years ago, it might have been a good idea. Nowadays most parts of the internet (- at least some very popular parts -) have become almost unusable, or provide only a very restricted functionality, when disabling Javascript in the browser. So IMHO today you can expect your users to have Javascript enabled.

And there are lots of frameworks like JQuery to get around browser incompatibilities. IMHO there is no real reason today why you should restrict yourself by not using Javascript for your Website - only reason may be that you don't have any use for it.

EDIT: a different question is: If you should provide some minimal functionality of your web site when your visitors don't have JS enabled - that's mostly a good idea, for the reasons some of the commenters have pointed out.

EDIT2: surely for every web site, one has to find a balance between user-friendlyness, search-engine-friendlyness and development effort. IMHO today Javascript can help to improve that balance - if used wisely. Said that, I think there is no need to generally minimize Javascript usage today any more to keep that balance. Use it with care, and don't demonize it.


答:
It's an interesting discussion.

To be frank, good tools can mitigate many of these "vertical" issues. In fact, in my opinion the notion of the "file" is actually something that hinders software development - something the Light Table project is working on (https://chris-granger.com/2012/04/12/light-table-a-new-ide-concept/).

Take files out of the picture, and the protected scope becomes a lot more appealing. The protected concept becomes most clear in langauges like SmallTalk - where any inheritance simply extends the original concept of a class. It should do everything, and have everything, that the parent class did.

In my opinion, class hierarchies should be as shallow as possible, with most extensions coming from composition. In such models, I don't see any reasons for private variables to not be made protected instead. If the extended class should represent an extension including all behaviour of the parent class (which I believe it should, and therefore believe private methods are inherently bad), why should the extended class not represent the storage of such data as well?

To put this another way - in any instance where I feel a private variable would suit better than a protected one, inheritence is not the solution to the problem in the first place.


答:
It's a good idea to avoid unnecessary functionality, period. Frameworks like jQuery make it incredibly easy to add frills that may make sense to add, but sometimes don't. For instance:

Do you really need to animate that?

... or ...

Is traversing the entire DOM really needed for such a trivial selector? Could you limit it using context, and do we need that in the first place?

I would not avoid using JS, but I do take care to not be obnoxious, while looking out for slower machines. The same holds true with some of the fancy new stuff we get in CSS3 - like drop shadows … if used excessively they can make someone on a lower powered machine have a really bad experience.

The exception to this might be writing front end controls for various kinds of appliances, where they must absolutely work with JS disabled (perhaps a strict security policy on a data center management network dictates no JS). So the above should be taken in context with whatever requirements you have.


答:
More precisely the Unit Test Environment should be as similar to production as possible.

In many cases the development environment may not be on the same platform as application will run on. (Think Android where the development is done on PC/eclipse but the code runs on your phone).

The main reason for not doing so in real life boils down to the cost of hardware or software licenses. Its hard to justify a multi-site, high availability cluster of multi-processor machines just for development.


答:
From my experiance there was a time when companies disables JavaScript by policy. But this time is far gone. Currently I have build some big intranet applications and webapplications for bigger global companies. For all applications, the usage of JavaScript and JQuery was part of the things that the customer expectets.

Building applications for customers is not only speed and security anymore. Customer want to focus on usability and the usage of AJAX technology. Without the usage of JavaScript it would not work such good. PostBacks all the time for some very small tasks like calculation or something like that is for most companies not an option.

When we think about the current situations in bigger companies there's a another indicator why JavaScript is currently a must have. Look at the CMS systems which are currently running in business. Most of them using Microsoft SharePoint or Adobe CQ, some of them Drupal or any other and so on. All this systems relies on JavaScript. Without javascript most of the application would not work, as the user expect it.


答:
It depends.

While desktop user agents can be expected to support and run your javascript in a meaningful way, not all user agents are graphical desktop browsers, and you need to decide whether you want to cater for them.

Examples include:

search engines (Google does run some javascript, but certainly not all of it, and if you rely on javascript for navigation, search bots might not find all of your content)

aggregators and scrapers

text-based browsers (not many people use those, though)

screen readers and other reading aids

(some) mobile browsers

My rule of thumb is that if it's a web application for regular users (in-house, community, that kind of thing), then relying on javascript is OK, but if you want to be publicly accessible and findable, then at least the vital functionality should work flawlessly without javascript, and you should fail gracefully when you need it, rather than exhibiting 'undefined' behavior.


答:
It's the instinct of most programmers to reduce all sorts of code. The less code, the fewer complexities, and the fewer points of possible error in said code. This rule applies to Javascript just as well as other languages. You're just upholding the tradition.

Use Javascript as needed/desired within HTML pages... but there's no reason to use it when its not actually needed.


答:
Having a site that can be used without JavaScript means that it is available to the widest possible audience. While it's true that the majority of browsers support JavaScript and the majority of users leave it on by default, you can't count on that for sure. Not everything that accesses your site is a browser after all; if you want your site properly indexed by search engines such as Google, then GoogleBot needs to be able to navigate your site without JavaScript.

There are also specialist pieces of web browsing software where JavaScript is unavailable or doesn't work as expected. Screen-reading or Braille software used by the visually impaired, for example. There are also environments where memory is constrained and having vast amounts of javascript may make the browsing experience unpleasant or even impractical, such as smartphone browsers.

You should look into the concept of "progressive enhancement", where you build a site to work without javascript, then add a javascript layer on top to improve the user experience.  That way you'll have a site that is at least usable to people without javascript.

You don't need to strive to provide every possible feature you're planning to implement with JavaScript to non-JavaScript browsers, but it's still important to at least leave the basic use cases available without JavaScript. Being able to browse the site is obviously top of the list, but if you're building an e-commerce site, making the checkout process JavaScript-dependant would be silly as it could cost you sales.


答:
In general

Quality of naming is not just about having descriptive names it also has to consider other aspects, and that leads to recommendations like:

the more global the scope, the more descriptive the name should be

the more often it is used, the shorter the name should be

the same name should be used in all contexts for the same thing

different things should have different names even if the context is different

variations should be easily detected

...

Note that these recommandations are conflicting.

Instruction mnemonics

As an assembly language programmer, using short-branch-if-greater-or-equal for bge.s gives me the same impression than when I see, as an Algol programmer doing computational geometry, SUBSTRACT THE-HORIZONTAL-COORDINATE-OF-THE-FIRST-POINT TO THE-HORIZONTAL-COORDINATE-OF-THE-SECOND-POINT GIVING THE-DIFFERENCES-OF-THE-COORDINATE-OF-THE-TWO-POINTS instead of dx := p2.x - p1.x. I just can't agree that the first are more readable in the contexts I care of.

Register names

You pick the official name from the documentation. The documentation picks the name from the design. The design uses a lot graphical formats where long names aren't adequate and the design team will life with those names for months, if not years. For both reasons, they won't use "Interrupt flag of the first timer counter", they will abbreviate it in their schema as well as when they speak. They know it and they use systematic abbreviations like TIFR1 so that there is less chance of confusion. One point here is that TIFR1 isn't a random abbreviation, it is the result of a naming scheme.


问:
What are use cases and advantages of pointers?
I often struggle to see the advantages of pointers (except for low level programming).

Why use of char* instead of a String or char[] or what advantages pointer arithmetic brings.

So what are the pros and use cases of pointers?

答:
Pointers can be faster and can incur less overhead, both in data structures and in keeping the program execution footprint down.  (Please note the word 'can'.)

In general the rule is, if you allocated a resource, either by performing your own allocation or having something do it on your behalf, then it's your job to release it when done.

The burden of doing the above is placing the responsiblity back on to the developer, rather than having the runtime do it.  This has some more advantages in that things can be longer lived, or cross boundaries, or be disposed of at more opportune times, or not need to carry the weight of a garbage collector around.

In exotic cases, usually involving exceptions and scope, there are some edge cases that require one to be a little more careful if the code the does cleanup gets avoided.  Realistically, these cases can be designed around.  We lived without managed code for many decades.

Often what makes pointers "hard" is merely not understanding what's going on at the hardware level.  It's nothing more than indirection.

Pointers give you much more raw access, and this can be very helpful, clever, or necessary.  You can point to anywhere and treat it pretty much as anything.  If you use your God-like powers for good, it's very, very good.

The con side is usually waste by forgetting to release something, or by releasing it more than once, or referencing something after it's released, or refencing something when you're not pointing anywhere.  These things often result in spectacular crashes, and to be honest are usually indicative that you've got a logic problem, rather than pointers are fragile.

If you're a solid developer, using pointers shouldn't be any more problematic than any other data structure.  Again, it's not rocket science, and people did it for decades without even blinking an eye.  It's just taught less throughly these days.

All that said, unless you have need for pointers, the conveinence and exoitic cases that a good garbage collection provides makes working in a managed environment that much nicer.  It's great to be able to grab some memory, use it, and abandon it, knowing that at some time later, it might be discarderd, if it makes sense to do so.  That's a bit less code on the coder's part, in exchange for a runtime that does some extra lifting.


问:
Should I pass an object into a constructor, or instantiate in class?
Consider these two examples:

Passing an object to a constructor

```<code>class ExampleA
{
  private $config;
  public function __construct($config)
  {
     $this->config = $config;
  }
}
$config = new Config;
$exampleA = new ExampleA($config);
</code>```

Instantiating a class

```<code>class ExampleB
{
  private $config;
  public function __construct()
  {
     $this->config = new Config;
  }
}
$exampleA = new ExampleA();
</code>```

Which is the correct way to handle adding an object as a property? When should I use one over the other? Does unit testing affect what I should use?

答:
Your first example is an example of the Dependency Injection pattern.  A class with an external dependency is handed the dependency by constructor, setter, etc.

This approach results in loosely-coupled code.  Most people think that loose coupling is a good thing, because you can easily substitute the config in the cases where one particular instance of an object needs to be configured differently from the others, you can pass in a mock config object for testing, and so on.

The second approach is closer to the GRASP creator pattern.  In this case, the object creates its own dependencies.  This results in tightly coupled code, this can limit the flexibility of the class and make it more difficult to test.  If you need one instance of a class to have a different dependency from the others, your only option is to subclass it.

It can be the appropriate pattern, however, in cases where the lifespan of the depended-on object is dictated by the lifetime of the dependant object, and where the depended-on object is not used anywhere outside of the object that depends on it.  Normally I'd advise DI to be the default position, but you don't have to rule out the other approach entirely as long as you're aware of its consequences.


答:
I find using protected variables for JUnit tests can be useful. If you make them private then you cannot access them during testing without reflection. This can be useful if you are testing a complex process through many state changes.

You could make them private, with protected getter methods, but if the variables are only going to be used externally during a JUnit test, I'm not sure that's a better solution.


答:
I believe that being a relatively new and young web developer ( about 4 years), I had to research a lot on this since javascript is everywhere.

What I try to do on my projects is to make sure that the site functions without javascript, then add javascript where it makes sense (client side validation, UI improvement, etc). It is a sort of progressive enhancement and it takes care of SEO, disabled javascript and older browser incompatiblities.

This same question has been asked on SO, but I cannot for the love of me remember where.


答:
As most of the answers here explain, using javascript is no harm. If you want to save your coding and messy looking source code, try coffee-script which will save a lot of effort typing javascript.

http://coffeescript.org/


问:
How much should I rely on Visual Studio's Auto Generated Code?
I'm reading about ASP.NET (VB.NET) and I want to built my professionally website. I'm wondering though; I'm still using the basics so I'm really just a novice, but how much should I rely on Visual Studio to create my elements?

Should I make my own text boxes and have my own login routine, or should I just use ASP.NET's login features?

I know eventually you have to use your own classes and such which is where the real coding comes in, but I'm not sure how relaible, flexible and secure the pre-wrote elements are?

Any help would be greatly appreciated.

答:
Short Answer: Start with analyzing generated HTML and solid fundamentals of HTML knowledge.

It is always a BIG back draw to rely on generated code without analyzing and understanding from where this magic comes from. You may end-up with hours of maintainability issues if you push such code to the production.

In another words, know your code and its behavior before relying on it, otherwise you will have a lot of gotcha!


问:
Is it safe to use LAST_INSERT_ID() in a system like Point of Sale
Is it safe to use LAST_INSERT_ID() in a system using MySQL like Point Of Sale when there are multiple users using the system at the same time?

答:
In the LAST_INSERT_ID() documentation it says:

The ID that was generated is maintained in the server on a
  per-connection basis. This means that the value returned by the
  function to a given client is the first AUTO_INCREMENT value generated
  for most recent statement affecting an AUTO_INCREMENT column by that
  client. This value cannot be affected by other clients, even if they
  generate AUTO_INCREMENT values of their own. This behavior ensures
  that each client can retrieve its own ID without concern for the
  activity of other clients, and without the need for locks or
  transactions.

So, if you call that function just after the insert to know the ID you inserted, it shouldn't be affeted by other concurrent users, as they are not using the same connection.

Anyway, there is not much detail in your question, so maybe your use case is a bit more complex than that.


问:
B.A Computer Science Vs B.S Inf Tech?
Would a recruiter prefer a B.A in Comp Science from a more prestigious university or a B.S in Inf Tech from just an average university? Would it matter for someone already established in the field with plenty of experience?

The only difference in the B.A and B.S is essentially the mathematics.  The B.S is geared for those going on to master's programs, although one isn't excluded from going on to a masters program with a BA, many do require more mathematics.

Just for those curious, the information tech degree is typically geared more to real-world problems then the computer science and the quality of it will vary widely. Some inf tech programs are as in-depth as an ABET C.S degree, the information tech from Drexel looks extremely strong. The Management Information Systems is generally provided via the business school and is more of a traditional business degree.

I'm not sure really how well versed the recruiters/g.p are in the actual differences in all of these programs. Some non ABET BS Comp Science may only require 1 or 2 Calculus versus the ABET certified programs.

答:
I graduated with what was considered a Computer Information Systems B.A. with an emphasis on Web Development, had a two-year Associates in Computer Engineering as an A.S.. What did Web Development entail? Two Java courses, two C++ courses, a SQL class, database diagramming and design, two COBOL courses, and a bunch of redundant coursework that I've never actually used in the real world.

The real work I did was during my senior year when internships were hard to find. I was able to land a job creating a website for an employment agency and use that as a credit toward an independent study course. What did I learn out of that? The .NET framework and C#/VB.net along with a few other server side technologies.

The point... degrees aren't everything. Sure, they do show a commitment to your education, and they do certainly set a precedence for some sort of work ethic that an employer can use to gauge how you MAY or MAY NOT do in a real world job.

If you can actually prove to an employer that you have the skills, and you, yourself, are confident in the skills that you currently have to do a good job, you should have no problems finding work... regardless of the degree.

Just for those curious, the
  information tech degree is typically
  geared more to real-world problems
  then the computer science and the
  quality of it will vary widely. Some
  inf tech programs are as in-depth as
  an ABET C.S degree, the information
  tech from Drexel looks extremely
  strong. The Management Information
  Systems is generally provided via the
  business school and is more of a
  traditional business degree.

Honestly, I'm not sure there is a huge difference here. If the information tech degree is more geared to real world applications than the C.S. degree, it probably isn't by much. My entire collegiate programming load was based on real world examples from e-Commerce sites to eBay clones, and I was basically in a degree that was within Information Technology, but on the Web Development path. It was the best of both worlds.

I'd get more details on some of the specifics of these degrees. Management Information Systems degree could be more of a project planning type of degree versus actually developing the guts of a system. If that's what you'd want to do, okay, but if not... specifics would be nice to get laid out so you don't enter something that you find out later isn't something you want.

Title: B.A Computer Science Vs B.S Inf Tech?