问:
How to unit test with lots of IO
I write Linux embedded software which closely integrates with hardware.

My modules are such as :

-CMOS video input with kernel driver (v4l2)

-Hardware h264/mpeg4 encoders (texas instuments)

-Audio Capture/Playback (alsa)

-Network IO

I'd like to have automated testing for those functionalities, such as integration testing. I am not sure how I can automate this process since most of the top level functionalities I face are IO bound. Sure, it is easy to test functions individually, but whole process checking means depending on tons of external dependencies only available at runtime.

答:
Sounds like a job for loop back testing.  Strictly speaking, loop back testing might feel as much like integration testing as it does like unit testing, even if the primary goal is to test just one particular device's support of configuration, input, and output.

For the audio device, perhaps you can do the following:

Wire a physical loop back of output to input.

Configure gains, sample rates, etc. as needed to insure functional and code coverage.

Playback a data file A and capture it back as B.

Compare A and B in some suitable way to determine pass/fail.

Repeat with multiple data sets to cover valid and invalid test cases.

Similar approaches are possible with video and network loop backs.

A few additional suggestions:

Use of lossy compression or noise may limit your ability to compare capture files.

Use of simplified inputs like tones from frequency generators or and video from generated color bars might work better than a track from your favorite rock band and a clip from an action movie.

You may want to play with the gain or run the samples through an FFT and compare the outputs of the FFT.

If comparing content gets too hard, checking duration, or verifying by ear or eye might be a way to get 'er done without making test code that is more complicated that the production code.

Good luck.  Hope this answer helps.

Title: How to unit test with lots of IO


问:
How to force evaluation in Haskell?
I am relatively new to Haskell and I am trying to learn how different actions can be executed in sequence using the do notation.
In particular, I am writing a program to benchmark an algorithm (a function)

```<code>foo :: [String] -> [String]
</code>```

To this purpose I would like to write a function like

```<code>import System.CPUTime

benchmark :: [String] -> IO Integer
benchmark inputList = do
                         start <- getCPUTime
                         let r = foo inputList
                         end <- getCPUTime
                         return (end - start) -- Possible conversion needed.
</code>```

The last line might need a conversion (e.g. to milliseconds) but this is not the topic of this question.

Is this the correct way to measure the time needed to compute function foo on some argument inputList?

In other words, will the expression foo inputList be completely reduced before the action end <- getCPUTime is executed? Or will r only be bound to the thunk foo inputList?

More in general, how can I ensure that an expression is completely evaluated before some action is executed?

答:
Indeed you version will not benchmark your algorithm. As r is not used it will not be evaluated at all.

You should be able to do it with DeepSeq[1]:

```<code>benchmark :: [String] -> IO Integer
benchmark inputList = do
                     start <- getCPUTime
                     let r = foo inputList
                     end <- r `deepseq` getCPUTime
                     return (end - start)
</code>```

(a deepseq b) is some "magic" expression which forces the complete/recursive evaluation of 'a' before retuning 'b'.

[1] http://www.haskell.org/ghc/docs/7.4.1/html/libraries/deepseq-1.3.0.0/Control-DeepSeq.html

ContentLicense: CC BY-SA 3.0

Title: How to force evaluation in Haskell?

Body:
Indeed you version will not benchmark your algorithm. As r is not used it will not be evaluated at all.

You should be able to do it with DeepSeq[1]:

benchmark :: [String] -> IO Integer
benchmark inputList = do
                     start <- getCPUTime
                     let r = foo inputList
                     end <- r `deepseq` getCPUTime
                     return (end - start)

(a deepseq b) is some "magic" expression which forces the complete/recursive evaluation of 'a' before retuning 'b'.

[1] http://www.haskell.org/ghc/docs/7.4.1/html/libraries/deepseq-1.3.0.0/Control-DeepSeq.html


问:
Order of subject and modifiers in variable names
I'm looking for experiences regarding the ordering of the subject and modifiers in variable names.

A simple object Shape would have just a subject for the variable name, such as Area.

A slightly more complex case Sphere which has a wall will have an inner volume and an outer volume, which is where my question comes into play.

What's preferred between Modifier-Subject or Subject-Modifier?

As an example set:

```
class Containers_Modifier_Subject
{
  AreaAdjustmentFactor
  WallThickness
  Height
  Length
  Width
  AdjustedArea
  SurfaceAreaInner
  SurfaceAreaOuter
  LongWallArea
  ShortWallArea
  TopArea
  InnerVolume
  OuterVolume
}

class Containers_Subject_Modifier
{
  AreaAdjustmentFactor
  WallThickness
  Height
  Length
  Width
  AreaAdjusted
  AreaInnerSurface
  AreaOuterSurface
  AreaLongWall
  AreaShortWall
  AreaTop
  VolumeInner
  VolumeOuter
}
```

The trigger for my question comes from an object that is similar to the examples.  There were enough variables in the object that only a portion displays in the code ahead / lookup window from the IDE.  I want to make sure that any future developer is quickly led to the correct variable that they'll be looking for without having to scroll up and down through the lookup window.

In my case, I was looking for the total area, but the area factor and adjusted area values had popped up first.

Consistency in naming as a code standard is a given.

Which naming approach has been:

most maintainable?

more easily understood?

semantically correct?

i.e. how well does the variable name match the business object and how well does the variable name flow into conversations about the problem being solved?

conducive to being used with code lookup functionality like Intellisense or the various Eclipse based constructs?

答:
I don't think there is a single right answer to this question.  In fact, it borders on a religious issue ;).

Both subject-modifier and modiier-subject have merit and disadvantages. Some of these are not inherent in the variable names themselves, but in the tools used to create and maintain the code (such a name assist using only starts-with).

Sometimes, the only difference between the two can be your point of reference.  For example wallThickness, if I am working with various thicknesses, wall is the modifier.  If I am looking at walls, thickness is the modifier.

Probably the best answer is to fit in with your existing code base.  To do otherwise would mean that other team members would be surprised by your name choices.  This will lead to duplication of computation and a general degradation of coding and maintanence speed.

In a coding standard, I might express a recommendation to prefer one over the other, but I would not make it a hard and fast rule. I would trust the programmers to make the best choice in each particular circumstance.


问:
Why put a simple query into a stored procedure in a web service?
I'm working as a junior programmer, and the senior programmer above me has instructed me to follow a certain unofficial policy for constructing new queries on our web development projects. Generally, we are developing an intranet site for some client, and they always have databases. He wants me to have a class containing a method for each query that the website will perform. This class calls web methods in a web service, hosted on the same machine. Those web methods use ADO to run stored procedures that perform simple queries. Sometimes the queries need parameters and sometimes they don't. When I say simple queries, I mean simple...select * from table where column=@parameter

I feel like there are several extra steps here, and I'm hoping someone can explain why he might want this as our standard procedure for using databases in web apps. He says each step adds a layer of security. I'm genuinely interested in how all this provides security. Is all this necessary? Why or why not?

答:
I was talking to a DBA about this a few weeks ago. Essentially, it gives them an added layer of security against you making a mistake. If you don't parameterise that query properly, there is a chance that someone malicious can inject SQL into your database that can do serious harm.

And this is where the conflict arises. You think you're always going to do your job properly, so there's no need for that layer of security. And you might well be right. But I've seen senior developers write ad-hoc queries that are vulnerable to SQL Injection, so I can understand a DBA insisting on that policy.

It's his neck on the line (or at least him who is going to get a call at 4am) if you make a mistake that destroys the database.


问:
How to find a programming mentor?
I decided to learn programming. I've been reading SO for few days, and I think I will start with C++, as I read some articles. I am aware of loops, arrays, program logic and objects a little and I need someone to look me over and help me with small questions I get when doing my first projects.

So here is the question - where do I find such guy? I don't got any friends who program and all.

EDIT: 2 years later, I am still looking for mentor. I did not actively code just started 3 months again. I work on Objective-C and iOS programming and game programming with Cocos2d. If you want to become my mentor, drop me a or comment.

答:
Given you are signed up on Stack Exchange, you already have many informal mentors available to you.  You can easily ask questions or have your code reviewed by many people who are motivated to help.

More locally, if you would like face-to-face mentoring or teaching, great options include:

Users groups - Pros: free or cheap, open to all.  Cons: Infrequent, not systematic, may not be available in your community.

Cooperatives - Pros: open, free/cheap.  Cons: less common, ad-hoc, more likely for web than C++.

University/college degree - Pros: systematic, high quality, respected, opens doors, generally provides access to at least some high quality faculty.  Cons: Competitive admission, major commitment, expensive, high wash-out rate so it is an expensive way to find out if you want to make software your profession, program of study can be flexible but may require topics you don't like or will find difficult.

Community college classes or degree programs.  Pros: Inexpensive, good value, more individual attention from instructors, easy to be admitted.  Cons: Less prestige than university but a good student is a good student where ever they go.

Professional organizations - Pros: can be good networking and continuing education.  Cons: you may need a degree or job in the field to qualify for membership.  Monthly meetings may be ad-hoc topics about innovations rather than systematic coverage of career enabling topics.

At work from peers, senior staff, or managers - Pros: frequent, targeted, appreciation/enthusiasm/follow-through will build your career like nothing else can.  Cons: can go wrong if your work mentor goes into judgement mode and you have been letting it all hang-out, this kind of mentor might not be available until you have a job which may mean after earning a degree due to global competition.

Coworking - Pros: nice resources, great people, generally a cross between a commune and a roomful of future CEOs.  Cons: may not be available where you live, can involve a cash commitment to help pay rent on shared space, many in the space will be self-employed so you must respect their time and find creative ways to make benefits reciprocal.

Title: How to find a programming mentor?


问:
What do employers look for in self-taught applicants?
I'm a self-taught programmer about to enter the job market. What I want to know is what is the best way to show my experience to employers?

What do employers want to know about my programming experience? Do employers want to look at code I wrote or could they want to see the software in action? Or do they only care how much my software is being used/how much it has created revenue? Should I write about my design and programming style?

My background: I recently graduated from a university where I studied foreign languages, and it was during this time when I found out that programming is the thing I really want to do. Currently I'm a garage programmer, developing a software for a client for commercial use while continuing to self-teach myself, but my aim is to start a "proper" employment and career. As an added twist I live in Finland at the moment, but I'm looking for employment in China or Japan (I learned both languages while studying abroad).

答:
Self-learning skills

Yes, self-learning is your cutting edge competitive skill which you should emphasize and present with pride. In addition, you should show your passion for programming and desire for self-improvement.

What do employers want to know about my programming experience? Do employers want to look at code I wrote or could they want to see the software in action?

They want to see your accomplishments and analytically reasoning skills. They want to see - what you did that benefited the project, what role(s) you have played in carrying out a project if you worked in a team. How you troubleshoot the problems and overcome technical issues. How you worked with colleges, how you handled work pressure.

Some other points that might be very important for employers:

Good attitude

Passion for programming

Computer experience - to see that you understand basics of how computer and software work

Work ethic and soft skills

Ability to learn and self-improvement

Educational history

Previous job experience

Lack of preconceived notions

Ability to ask questions - Yes, ask questions rather than making assumptions.


问:
ASP.NET Dynamic Data
I'd like to know what people think of ASP.NET Dynamic Data.  I see the project type in visual studio and have found very little about it mention on blogs and in books.

I created a site using it and it is great the way it wires up the CRUD pages, but i don't understand how to modify the the pages without modifying the template that all the pages use.

Do you think it will be abandoned in future versions of visual studio?  I'm wondering if it's worth the effort of learning this type of application.

personally i think i'd like something simpler....create the CRUD for us, but make them on seperate pages, without the whole template system.

答:
I've always viewed Dynamic Data as an excellent way to create administrative pages...pages that can be thrown up quickly to edit metadata, but which a normal user will never see, so customization becomes less important.

If you are using ASP.NET MVC, Dynamic Data takes on far less importance, as the View builders do much of the scaffolding work for you already.

ContentLicense: CC BY-SA 2.5

Title: ASP.NET Dynamic Data


问:
Learning Django by example
When I first started learning Android, I found a fantastic series of YouTube videos by Marakana that stepped through building a Twitter clone. It walked me through all the steps and thus explained to me the basics, common libraries, best practices, resources, etc. Looking over an expert's shoulder while building a practical app was the absolute best learning method for me. More than anything else, it provided me with a skeleton I could build on. From there I could continue researching and know which questions to ask.

I'm now looking for something similar with Django. Of course I checked out the official tutorial, and The Django Book. The former flexes some Django muscles, but doesn't walk through a full app. The latter is certainly better, but the app it builds is very basic and by the time it reaches the more advanced subjects the tutorial breaks down and its back to short code snippets and documentation-like explanations.

Checking out Amazon isn't terribly encouraging. The latest general Django book was released almost two-and-half years ago and only covers v1.0. To be fair, I understand that this is probably because the online documentation is excellent, but again, I'm looking for a walk-through. I did experience a spark of excitement when I came across Practical Django Projects, which sounds like exactly what I was looking for. However, some of the reviews make claims of some egregious problems--no source code, many errors and no errata, totally apathetic author and unresponsive publisher, etc.

And so I'm left at square one and need your advice. Is there a place where I can sit on a giant's shoulder and be walked through a realistic Django project from start to finish? Preferably using a more recent version of the framework.

答:
I think a book that better goes over Django in depth is Beginning Django E-commerce .

However, I do suggest you look over the second addition of Practical Django Projects. I would also advise you to google django cheat sheet. It gives you a flow chart of the methods you will be accessing most when building your application. The Django documentation really is fantastic there are a couple of areas it lacks in though as you stated.

I only believe Django was so hard for me starting off as I had no OOP experience, and only prior programming was small amounts of VB. Html/css don't really count. Then I realized that depending on the project django really makes it so that the developer does not have to program a lot when it comes to basic projects.

Now it really gives me a creative spark when I can sift through the django documentation and understand it. HTML5 and its canvas element. There is a lot on the horizon. Django is absolutely wonderful for building informational sites, presenting information, reading material, blogs, photologues, etc . . Staying to python as much as I can though I must say that for something more along the lines of a real application, I would have to vote for flask or web.py. Django has tons of fluff.

You're requests per second can be greatly optimized with JS, caching, and other optimization techniques. However, what really hinders it is running each request through multiple context processors, long list iterations and complex queryset filtering.

I am sure you're saying well what's the problem? Nothing at all. The functionality that Django is able to offer a developer out of the box is second to none. The ORM is fantastic at creating the API and admin interfaces for you. To gain all this fluff, one must give up some control. Date-based generic views are a life saver, as are re-useable 3rd party applications. Django's popularity greatly helps and it has a wonderful community. But, as I stated depending on your aim, and level of programming skill, you may want to check out some other more rugged frameworks(web.py, flask).

Sorry to ramble, Django gives you the components to create content based management systems for content based sites, but isn't best suited(not necessarily lacking) if you are looking to create a web application in a more traditional sense of application. I'm not saying Django can't do it. It's just a matter of using a hammer to nail down a board or using the side of your wrench. I am pro-django fyi, and pro flask / web.py .

Title: Learning Django by example


答:
In addition to the other answers - list the tools you've learned while you were teaching yourself.

I've trained graduates from big-name schools with big name degrees that insisted on writing Java code in Windows notepad and using the command line compiler ('it's better that way' - for a one class program). Most workplaces use IDEs and other programming tools. And teaching them how to use Eclipse was easier than trying to teach them SVN.

By listing one or more IDE environments or (more importantly) one or more code repository tools you will show you are ready to work with a team.

Answer B: if you can get there try the CEBIT tradeshow in Hanover in Germany. We used to get people visiting our stand asking for jobs in our country. The probability is low that will you might meet the right person who can help you. Or ask them if they need a local/Europe person to help them.

Title: What do employers look for in self-taught applicants?

Body:
I'm a self-taught programmer about to enter the job market. What I want to know is what is the best way to show my experience to employers?

What do employers want to know about my programming experience? Do employers want to look at code I wrote or could they want to see the software in action? Or do they only care how much my software is being used/how much it has created revenue? Should I write about my design and programming style?

My background: I recently graduated from a university where I studied foreign languages, and it was during this time when I found out that programming is the thing I really want to do. Currently I'm a garage programmer, developing a software for a client for commercial use while continuing to self-teach myself, but my aim is to start a "proper" employment and career. As an added twist I live in Finland at the moment, but I'm looking for employment in China or Japan (I learned both languages while studying abroad).


问:
Why would more CPU cores on virtual machine slow compile times?
[edit#2] If anyone from VMWare can hit me up with a copy of VMWare Fusion, I'd be more than happy to do the same as a VirtualBox vs VMWare comparison. Somehow I suspect the VMWare hypervisor will be better tuned for hyperthreading (see my answer too)

I'm seeing something curious. As I increase the number of cores on my Windows 7 x64 virtual machine, the overall compile time increases instead of decreasing. Compiling is usually very well suited for parallel processing as in the middle part (post dependency mapping) you can simply call a compiler instance on each of your .c/.cpp/.cs/whatever file to build partial objects for the linker to take over. So I would have imagined that compiling would actually scale very well with # of cores.

But what I'm seeing is:

8 cores: 1.89 sec

4 cores: 1.33 sec

2 cores: 1.24 sec

1 core: 1.15 sec

Is this simply a design artifact due to a particular vendor's hypervisor implementation (type2:virtualbox in my case) or something more pervasive across more VMs to make hypervisor implementations more simpler? With so many factors, I seem to be able to make arguments both for and against this behavior - so if someone knows more about this than me, I'd be curious to read your answer.

Thanks
Sid

[edit:addressing comments]

@MartinBeckett: Cold compiles were discarded.

@MonsterTruck: Couldn't find an opensource project to compile directly. Would be great but can't screwup my dev env right now.

@Mr Lister, @philosodad: Have 8 hw threads, using VirtualBox, so should be 1:1 mapping without emulation

@Thorbjorn: I have 6.5GB for the VM and a smallish VS2012 project - it's quite unlikely that I'm swapping in/out trashing the page file.

@All: If someone can point to an open source VS2010/VS2012 project, that might be a better community reference than my (proprietary) VS2012 project. Orchard and DNN seem to need environment tweaking to compile in VS2012. I really would like to see if someone with VMWare Fusion also sees this (for VMWare vs VirtualBox compartmentalization)

Test details:

Hardware: Macbook Pro Retina

CPU : Core i7 @ 2.3Ghz (quad core, hyper threaded = 8 cores in windows task manager)

Memory : 16 GB

Disk : 256GB SSD

Host OS: Mac OS X 10.8

VM type: VirtualBox 4.1.18 (type 2 hypervisor)

Guest OS: Windows 7 x64 SP1

Compiler: VS2012 compiling a solution with 3 C# Azure projects

Compile times measure by VS2012 plugin called 'VSCommands'

All tests run 5 times, first 2 runs discarded, last 3 averaged

答:
Answer: It doesn't slow down, it does scale up with # of CPU cores. The project used in the original question was 'too small' (it's actually a ton of development but small/optimized for a compiler) to reap the benefits of multiple cores. Seems instead of planning how to spread the work, spawning multiple compiler processes etc, at this small scale it's best to hammer at the work serially right off the bat.

This is based off the new experiment I did based off the comments to the question (and my personal curiosity). I used a larger VS project - Umbraco CMS's source code since it's large, open sourced and one can directly load up the solution file and rebuild (hint: load up umbraco_675b272bb0a3\src\umbraco.sln in VS2010/VS2012).

NOW, what I see is what I expect, i.e. compiles scale up!! Well, to a certain point since I find:

Takeaways:

A new VM core results in a new OS X Thread within the VirtualBox process

Compile times scale up as expected (compiles are long enough)

At 8 VM cores, core emulation might be kicking in within VirtualBox as the penalty is massive (50% hit)

The above is likely because OS X is unable to present 4 hyper-threaded cores (8 h/w thread) as 8 cores to VirtualBox

That last point caused me to monitor the CPU history across all the cores via 'Activity Monitor' (CPU history) and what I found was

Takeaways:

At one VM core, the activity seems to be hopping across the 4 HW cores. Makes sense, to distribute heat evenly at core levels.

Even at 4 Virtual cores (and 27 VirtualBox OS X threads or ~800 OS X thread overall), only even HW threads (0,2,4,6) are almost saturated while odd HW threads (1,3,5,7) are almost at 0%. More likely the scheduler works in terms of HW cores and NOT HW threads so I speculate perhaps the OSX 64bit kernel/scheduler isn't optimized for hyper threaded CPU? Or looking at the 8VM core setup, perhaps it starts using them at a high % CPU utilization? Something funny is going one ... well, that's a separate question for some Darwin developers ...

[edit]: I'd love to try the same in VMWare Fusion. Chances are it won't be this bad. I wonder if they showcase this as a commercial product ...

Footer:

In case the images ever disappear, the compile time table is (text, ugly!)

```<code>Cores in    Avg compile      Host/OSX    Host/OSX CPU
   VM         times (sec)   Threads      consumption
    1           11.83            24        105-115%
    2           10.04            25        140-190%
    4            9.59            27        180-270%
    8           14.18            31        240-430%
</code>```

Body:
Answer: It doesn't slow down, it does scale up with # of CPU cores. The project used in the original question was 'too small' (it's actually a ton of development but small/optimized for a compiler) to reap the benefits of multiple cores. Seems instead of planning how to spread the work, spawning multiple compiler processes etc, at this small scale it's best to hammer at the work serially right off the bat.

This is based off the new experiment I did based off the comments to the question (and my personal curiosity). I used a larger VS project - Umbraco CMS's source code since it's large, open sourced and one can directly load up the solution file and rebuild (hint: load up umbraco_675b272bb0a3\src\umbraco.sln in VS2010/VS2012).

NOW, what I see is what I expect, i.e. compiles scale up!! Well, to a certain point since I find:

Takeaways:

A new VM core results in a new OS X Thread within the VirtualBox process

Compile times scale up as expected (compiles are long enough)

At 8 VM cores, core emulation might be kicking in within VirtualBox as the penalty is massive (50% hit)

The above is likely because OS X is unable to present 4 hyper-threaded cores (8 h/w thread) as 8 cores to VirtualBox

That last point caused me to monitor the CPU history across all the cores via 'Activity Monitor' (CPU history) and what I found was

Takeaways:

At one VM core, the activity seems to be hopping across the 4 HW cores. Makes sense, to distribute heat evenly at core levels.

Even at 4 Virtual cores (and 27 VirtualBox OS X threads or ~800 OS X thread overall), only even HW threads (0,2,4,6) are almost saturated while odd HW threads (1,3,5,7) are almost at 0%. More likely the scheduler works in terms of HW cores and NOT HW threads so I speculate perhaps the OSX 64bit kernel/scheduler isn't optimized for hyper threaded CPU? Or looking at the 8VM core setup, perhaps it starts using them at a high % CPU utilization? Something funny is going one ... well, that's a separate question for some Darwin developers ...

[edit]: I'd love to try the same in VMWare Fusion. Chances are it won't be this bad. I wonder if they showcase this as a commercial product ...

Footer:

In case the images ever disappear, the compile time table is (text, ugly!)

Cores in    Avg compile      Host/OSX    Host/OSX CPU
   VM         times (sec)   Threads      consumption
    1           11.83            24        105-115%
    2           10.04            25        140-190%
    4            9.59            27        180-270%
    8           14.18            31        240-430%


问:
Debugging: understanding details on why certain fixes worked?
When debugging, I sometimes find that I make some changes and I am not 100% sure why those changes correct some bug in the program. Is it essential to understand every single detail about why some bugs were occurring and why certain changes eliminated those bugs? Or is it common among developers to sometimes get the program working without really knowing the details about why the fix worked?</p>

答:
I would say that it is essential to understand every single detail about why some bugs were occurring and why certain changes eliminated those bugs, and it is also common among developers to sometimes get the program working without really knowing the details about why the fix worked!

The art of changing things until a bug disappears, without understanding what caused it or why the change fixed it, is often called "voodoo programming," and it's not a compliment. There is really no way you can possibly be confident that you have genuinely fixed a bug, as opposed to partially fixing it for the particular case you were investigating, if you don't understand what caused it.

In the worst case, you haven't done anything at all except move the bug: I remember from first year computing at uni, when many students were learning C and pointers for the first time, pointer bugs would often stop manifesting when they changed things randomly, because the changes would rearrange data structures in memory enough to make the pointer bug stomp over a different bit of memory. Obviously that hasn't helped at all.

But having said that, the commercial realities of programming are often such that satisfying the client that a bug is fixed is more important than satisfying yourself. I'd never recommend you declare something fixed if you had no idea what caused it, but if you can see that some code was problematic, and you reworked it, even if you're "not 100% sure" how that caused the specific bug to manifest, sometimes you just have to move on to the next bug before the client screams too loudly about your slow progress.


答:
Changing stuff until the bug is no longer there is generally bad practice, but unfortunately a reality for some people.

I'm of the strong opinion that you should never write code that you don't understand what it does or why it does it. How can you be sure that even though you've fixed the bug you've set out to fix - you haven't broken anything else?

Generally, before you fix a problem/bug - you should be doing an underlying cause assessment/analysis to determine why the issue is occurring and if it can be replicated. Then you should be reading the code and understanding why the code is causing the bug to happen. Once you have that understanding: then you can start to look at how the resolve the issue and determining other areas that your change(s) will impact. Unit tests can really help here!

I've seen a number of code changes that people have made to fix an issue (which is great), but it unfortunately introduced other issues because the developer was unaware of the full impact of what they changed. Many of these "fixes" just obscure the underlying cause of the original issue as well as introducing complexity and more bugs.

Having said that, I've fixed a number of issues in code purely by association. Where I've changed/reworked/refactored something and it fixed other outstanding bugs. So although I don't know what caused them originally, I found dodgy code and "fixed" it - which happened to fix those bugs too. I cover changes like this with unit and integration tests to ensure the integrity of the business and technical requirements of the function.

Title: Debugging: understanding details on why certain fixes worked?

Body: When debugging, I sometimes find that I make some changes and I am not 100% sure why those changes correct some bug in the program. Is it essential to understand every single detail about why some bugs were occurring and why certain changes eliminated those bugs? Or is it common among developers to sometimes get the program working without really knowing the details about why the fix worked?</p>


问:
Why would it take hours to decode transmissions from Curiosity rover via MRO?
This video clip by NASA says that data from Curiosity relayed by the Mars Reconnaissance Orbiter (MRO) would be stored for a few hours, then transmitted to Earth (apparently taking about 14 minutes), after which it would take hours for engineers to decode the data.

From what I've read, it seems that the MRO can be used as a backup communication device for Curiosity if needed.

In the case of Curiosity's landing, I figure the MRO would have store the data until it orbited around the red planet and had a direct line of sight with Earth before transmitting it (then again, I'm only speculating here), which I can understand.

But then why would it take NASA engineers hours to decode the signal relayed by MRO after it is received here on Earth?

(Bonus point: Does it normally take hours to decode MRO signals?)

答:
The video clip is slightly misleading, and presents a bit of a simplification of what would've actually happened. In reality, what the MRO would've received was a carrier signal, which would then be transmitted back to Earth and analyzed by scientists and engineers for clues about the success of the mission.

As explained by Michel Denis, Mars Express Spacecraft Operations Manager, and reported on the ESA website:

"Only Odyssey can receive, decode and then relay to Earth the actual telemetry data coded into the those signals. Conversely, MRO and MEX will save on board 'open-loop' recordings," says Denis.

Michael Khan, a mission analyst at ESOC, confirmed this for Mars Express, as reported on the Mars Express blog:

"All that Mars Express will receive is the UHF [radio] carrier signal. From apparent changes in the received frequency, one can deduce at which speed relative to the MEX the landing craft is moving. Or -- hopefully this will not be the case -- if suddenly the signal stops, then we have an indication of when things went awry," he points out.

"Mars Express can and does relay data for surface assets. But that is long after landing and requires MEX to pass very low over the landing site; not the situation we will have on Monday, 6 August."

And they went into a bit more detail into the open-loop recording process in a follow-up post, "What is Open Loop Recording?":

In open loop recording, we don't try to decode the bits and bytes being sent by the descending lander but instead try and listen to as much of the radio spectrum as we can, hopefully detecting the tone of the lander's transmissions within this spectrum. Think of it like listening to a crowd of people – you can either focus on the words one person is saying, or listen to the whole crowd to get a full picture of what's going on; that's what we'll do with open loop recording.

On Mars Express we'll use our UHF Melacom radio to listen in on the UHF part of the spectrum – usually used on Earth for radio and television transmissions; it's also used at Mars as the frequency that different orbiters and landers use to talk to each other.

[...]

By using this technique, we will see the trace of Curiosity's signal in the UHF and X-Band ranges and watch as it drifts and changes in response to Doppler, in this case not just because Mars Express is moving overhead but also because Curiosity will be changing velocity as it slows itself to a soft landing on Mars. This will give us a great insight into the progress and success of the landing.

This process of analyzing the signal is what would've taken hours. Of course, it wasn't needed as Curiosity was able to transmit data to the Mars Odyssey orbiter, and it likely won't be needed again for the rest of the mission.


问:
Is it ok to replace optimized code with readable code?
Sometimes you run into a situation where you have to extend/improve some existing code. You see that the old code is very lean, but it's also difficult to extend, and takes time to read.

Is it a good idea to replace it with modern code?

Some time ago I liked the lean approach, but now, it seems to me that it's better to sacrifice a lot of optimizations in favor of higher abstractions, better interfaces and more readable, extendable code.

The compilers seem to be getting better as well, so things like struct abc = {} are silently turned into memsets, shared_ptrs are pretty much producing the same code as raw pointer twiddling, templates are working super good because they produce super lean code, and so on.

But still, sometimes you see stack based arrays and old C functions with some obscure logic, and usually they are not on the critical path.

Is it a good idea to change such code if you have to touch a small piece of it either way?

答:
The answer is, without loss of generality, yes. Always add modern code when you see hard to read code, and delete the bad code in most cases. I use the following process:

Look for the performance test and supporting profiling information. If there is no performance test, then what can be asserted without evidence can be dismissed without evidence. Assert that your modern code is faster and remove the old code. If anyone argues (even yourself) ask them to write the profiling code to prove which is faster.

If the profiling code exists, write the modern code anyway. Name it something like <function>_clean(). Then, "race" your code against the bad code. If your code is better, remove the old code.

If the old code is faster, leave your modern code in there anyway. It serves as good documentation for what the other code is meant to do, and since the "race" code is there, you can keep running it for documenting the performance characteristics and differences between the two paths. You can also unit test for differences in code behaviour. Importantly, the modern code will beat the "optimised" code one day, guaranteed. You can then remove the bad code.

QED.


问:
How would you test Google Maps "Get Directions" feature?
(I imagine this would be a good interview question, but in my case it's more pragmatic than that.)

We have a large & complex application that models an extremely long and sophisticated chemical reaction process between dozens of chemical components. We are at the stage of designing Acceptance Tests for the application, but we are somewhat daunted by the intractable number of possible paths to test. It occurred to me that our situation is very much like what the Google Maps dev team must have faced when it came time to test the route-planning algorithm in their "Get Directions" feature. Obviously they couldn't test (verify and validate) every possible route. So how did they get confidence that their application would work in every situation?

And since I don't expect to find out how they did it, let me ask you: How would you go about designing a test suite with adequate code coverage, to satisfy yourself that a given application is robust -- when it is literally impossible to probe every potential path through the system?

What I'm looking for are the principles that you would use to break down an intractable problem into smaller, tractable pieces, the sum of which provide a satisfactory estimate of the whole: "I can't test everything, but I can test this, this and this -- and that's enough." I'm not looking for an approach that is "provably correct", but rather one that is prudent, given real-world budget/time constraints.

(I'm using the Google maps example as something of a foil to solicit answers that are as specific as possible.)

答:
It's not like google writes separate code for every pair of addresses in the world.  With the exception of heuristics that kick in at a larger scale, the algorithm for a 3-leg journey is exactly the same as for a 3000-leg.  You thoroughly test the shorter paths and use induction to show the testing applies to longer paths as well.

You pick a healthy sample of real-world routes, and check it against what a human comes up with.  You pay a lot of attention to end user feedback in your first releases, and make it easy for them to provide it.  You test the boundary conditions, like if the best route actually requires traveling away from the destination for a while, or if the shortest route by distance has 18 turns compared to a more direct route that's slightly longer.  You do negative testing, like if you're trying to drive from California to Hawaii, and make sure clever easter eggs are in place.


答:
If you think a client is mad about it taking too long to fix a bug, imagine how mad they will be about a bug recurring that you claimed was fixed, or a fix for one thing making something else worse.  If your fix is only a workaround or mitigation, customers will usually still welcome it, but you must be honest about what it is, and you put as much logging as you need in order to fix it for real.

If you're pretty sure you fixed it, but don't know why the fix works, ask someone.  Most engineers I know love to get questions like that because of the mystery behind it.


答:
I worked in the car navigation field over a decade ago.

Step A)
Use a reference package and select a large sample set, run A/B tests. Not looking for exactness, looking for outliers - The reference set showed Reroute 1234 as 10.34km, and we calculated 123.5km.

Step B)
- Refine our software and the reference software
- Add more samples and reduce the tolerances.

Step C)
 - In house testing using local knowledge across global data sets.

Step D)
UAT... "User Acceptance Test"  As in "Sell this stuff and see what the customers complain about the most"

If you ever used mapping products circa Mid 1990's - 2000, you know what I mean, those of us that did still check the turn by turn directions every time.

Back to you example question. What you are being asked is how to prove that a piece of software is correct. If you want mathematical proof, it's been shown it can be done - for simple software at a price that exceeds any realistic budgets, for a complex software package, well, that is still research.... NASA has models for writing highly reliable software within economically manageable prices, as do DoD and the aviation industry - although still much higher than most are willing to pay.   In the end, it comes down to how much are you prepared to pay.....

Edit :
I just re-read you OP. It seems what you are looking for is a quick and cheap way to Test the quality of a complex piece of software. You cannot test in quality. You need to have a robust process so you know that what is built works correctly. If you have got to thinking about how to prove it's correct and you already have a the "large and complex application", you are too late.

Title: How would you test Google Maps "Get Directions" feature?

Body:
(I imagine this would be a good interview question, but in my case it's more pragmatic than that.)

We have a large & complex application that models an extremely long and sophisticated chemical reaction process between dozens of chemical components. We are at the stage of designing Acceptance Tests for the application, but we are somewhat daunted by the intractable number of possible paths to test. It occurred to me that our situation is very much like what the Google Maps dev team must have faced when it came time to test the route-planning algorithm in their "Get Directions" feature. Obviously they couldn't test (verify and validate) every possible route. So how did they get confidence that their application would work in every situation?

And since I don't expect to find out how they did it, let me ask you: How would you go about designing a test suite with adequate code coverage, to satisfy yourself that a given application is robust -- when it is literally impossible to probe every potential path through the system?

What I'm looking for are the principles that you would use to break down an intractable problem into smaller, tractable pieces, the sum of which provide a satisfactory estimate of the whole: "I can't test everything, but I can test this, this and this -- and that's enough." I'm not looking for an approach that is "provably correct", but rather one that is prudent, given real-world budget/time constraints.

(I'm using the Google maps example as something of a foil to solicit answers that are as specific as possible.)


问:
Is it OK for a function to modify a parameter
We have a data layer that wraps Linq To SQL. In this datalayer we have this method (simplified)

```<code>int InsertReport(Report report)
{
    db.Reports.InsertOnSubmit(report);
    db.SubmitChanges();
    return report.ID;
}
</code>```

On submit changes, the report ID is updated with the value in the database which we then return.

From the calling side it looks like this (simplified)

```<code>var report = new Report();
DataLayer.InsertReport(report);
// Do something with report.ID
</code>```

Looking at the code, ID has been set inside the InsertReport function as a kind of side effect, and then we are ignoring the return value.

My question is, should I rely on the side effect and do something like this instead.

```<code>void InsertReport(Report report)
{
    db.Reports.InsertOnSubmit(report);
    db.SubmitChanges();
}
</code>```

or should we prevent it

```<code>int InsertReport(Report report)
{
    var newReport = report.Clone();
    db.Reports.InsertOnSubmit(newReport);
    db.SubmitChanges();
    return newReport.ID;
}
</code>```

maybe even

```<code>Report InsertReport(Report report)
{
    var newReport = report.Clone();
    db.Reports.InsertOnSubmit(newReport);
    db.SubmitChanges();
    return newReport;
}
</code>```

This question was raised when we created a unit test and found that its not really clear that the report parameters ID property gets updated and that to mock the side effect behavior felt wrong, a code smell if you will.

答:
Yes, it's OK, and fairly common. It can be non-obvious though, as you've discovered.

In general, I tend to have persistence-type methods return the updated instance of the object. That is:

```<code>Report InsertReport(Report report)
{
    db.Reports.InsertOnSubmit(report);
    db.SubmitChanges();
    return report;
}
</code>```

Yes, you're returning the same object as you passed in, but it makes the API clearer. There's no need for the clone - if anything that will cause confusion if, as in the your original code, the caller continues to use the object they passed in.

Another option is to use a DTO

```<code>Report InsertReport(ReportDTO dto)
{
    var newReport = Report.Create(dto);
    db.Reports.InsertOnSubmit(newReport);
    db.SubmitChanges();
    return newReport;
}
</code>```

That way the API is very obvious, and the caller can't accidentally try and use the passed in/modified object. Depending on what your code is doing, it can be a bit of a pain though.

Body:
Yes, it's OK, and fairly common. It can be non-obvious though, as you've discovered.

In general, I tend to have persistence-type methods return the updated instance of the object. That is:

Report InsertReport(Report report)
{
    db.Reports.InsertOnSubmit(report);
    db.SubmitChanges();
    return report;
}

Yes, you're returning the same object as you passed in, but it makes the API clearer. There's no need for the clone - if anything that will cause confusion if, as in the your original code, the caller continues to use the object they passed in.

Another option is to use a DTO

Report InsertReport(ReportDTO dto)
{
    var newReport = Report.Create(dto);
    db.Reports.InsertOnSubmit(newReport);
    db.SubmitChanges();
    return newReport;
}

That way the API is very obvious, and the caller can't accidentally try and use the passed in/modified object. Depending on what your code is doing, it can be a bit of a pain though.


答:
The idea behind this is probaby to keep a low degree of coupling. Your application talks to the web service only, and the web service talks to stored procedures only. There are no SQL statements in your front-end code, only web service calls; and there are no SQL statements other than stored procedure calls in the web service. There are several advantages to this:

It's more maintainable. All the SQL queries are in one place, so you never have to go hunt them down (and possibly overlook a crucial one).

Each component (web service, front-end, database) can be swapped out individually for testing and debugging.

Many types of errors remain contained within one module, e.g. there cannot be any SQL syntax error in the front-end, because it doesn't contain any SQL at all.

If at some point you need to migrate to newer versions of your platform components, you can migrate each component individually, mitigating risks. For example, you may choose to move the front-end to a newer .NET, while the database server still runs the old version.

It's more scalable. If at some point you decide to split database and front-end over different servers, you can - just configure the front-end to talk to a different host for the web service, or configure the web service to connect to a different database host, or even both (which would create a physically separated three-tier structure). Additionally, you can implement caching and load balancing at several levels, including the intermediate web service. And if at some point you decide you need to shard your database, you can probably implement the required logic in the web service, without affecting the front-end at all.

And there's the responsibility thing: By moving your actual queries to the database, they become part of the DBA's realm. If you have a decent DBA, he's probably much better at SQL than you are (especially when it comes to obscure yet business-critical edge cases that can have dramatic effects on performance), and it's a good thing to have him at least check your SQL before it goes into production.

Title: Why put a simple query into a stored procedure in a web service?

Body:
I'm working as a junior programmer, and the senior programmer above me has instructed me to follow a certain unofficial policy for constructing new queries on our web development projects. Generally, we are developing an intranet site for some client, and they always have databases. He wants me to have a class containing a method for each query that the website will perform. This class calls web methods in a web service, hosted on the same machine. Those web methods use ADO to run stored procedures that perform simple queries. Sometimes the queries need parameters and sometimes they don't. When I say simple queries, I mean simple...select * from table where column=@parameter

I feel like there are several extra steps here, and I'm hoping someone can explain why he might want this as our standard procedure for using databases in web apps. He says each step adds a layer of security. I'm genuinely interested in how all this provides security. Is all this necessary? Why or why not?


答:
I see two scenarios: you worked on something else and the bug stopped happening, as long as the something else hasn't broken anything else, you pretty much have to let that go in--you did what was needed/wanted and it had an unforeseen and inexplicable positive side effect.

The other is that you are working on this bug and a random change made things work, that's unacceptable.  If you have no idea what the old code was doing wrong, you probably have no idea what the new code is doing wrong.

I can’t really think of a good reason to checkin the second case -- if it's a critical bug, then it's critical to get it right.  If it's a non-critical bug, at least you can be sure that you are not introducing a critical bug with your "fix".


答: IMO this is a rare instance where the side effect of change is desirable - because your Report entity HAS an ID it could already be assumed to have the concerns of a DTO, and arguably there is the ORM obligation to ensure that the in-memory Report entity is kept in synch with the database representation object.

Title: Is it OK for a function to modify a parameter

Body:
We have a data layer that wraps Linq To SQL. In this datalayer we have this method (simplified)

```<code>int InsertReport(Report report)
{
    db.Reports.InsertOnSubmit(report);
    db.SubmitChanges();
    return report.ID;
}
</code>```

On submit changes, the report ID is updated with the value in the database which we then return.

From the calling side it looks like this (simplified)

```<code>var report = new Report();
DataLayer.InsertReport(report);
// Do something with report.ID
</code>```

Looking at the code, ID has been set inside the InsertReport function as a kind of side effect, and then we are ignoring the return value.

My question is, should I rely on the side effect and do something like this instead.

```<code>void InsertReport(Report report)
{
    db.Reports.InsertOnSubmit(report);
    db.SubmitChanges();
}
</code>```

or should we prevent it

```<code>int InsertReport(Report report)
{
    var newReport = report.Clone();
    db.Reports.InsertOnSubmit(newReport);
    db.SubmitChanges();
    return newReport.ID;
}
</code>```

maybe even

```<code>Report InsertReport(Report report)
{
    var newReport = report.Clone();
    db.Reports.InsertOnSubmit(newReport);
    db.SubmitChanges();
    return newReport;
}
</code>```

This question was raised when we created a unit test and found that its not really clear that the report parameters ID property gets updated and that to mock the side effect behavior felt wrong, a code smell if you will.


问:
Should I put newlines before or after binary operators?
When you're in Python or Javascript, you should always put binary operators at the end of the previous line, in order to prevent newlines from terminating your code prematurely; it helps you catch errors.

But in C or C++, this isn't an issue, so I'm wondering:

Is there any reason for me to prefer the second version to the first?

```<code>return lots_of_text
       + 1;
</code>```

versus

```<code>return lots_of_text +
       1;
</code>```

(For example, does one of them help prevent other kinds of errors? Or is one of them considered more readable?)

答:
I almost always break lines before binary operators in order to make clear to readers of the code that this is the continuation of an expression and not the next statement. This is important if the next statement would normally be indented. For example, consider an if statement that has a complex conditional expression:

```<code>if (first_part_of_condition &&
    second_part_of_condition) {
    statement_within_then_part;
}
</code>```

The second part of the conditional expression is easily confused with the first statement of the then-part. This can be quite confusing if the first part of the condition is long and the && ends up way off to the right. Compare this with the alternative:

```<code>if (first_part_of_condition
    && second_part_of_condition) {
    statement_within_then_part;
}
</code>```

This looks a bit odd but it makes it quite clear that the second part of the condition is not the beginning of a statement.

I do this in others contexts too but the if-statement is the most important, as the indentation is ambiguous. Of course, one could change the indentation or brace placement, but this looks odd too.

tl;dr the left end of the line is more significant to quick reading comprehension, so putting the operator on the left end is a more prominent marker that this is a continued expression, not a statement.

Body:
I almost always break lines before binary operators in order to make clear to readers of the code that this is the continuation of an expression and not the next statement. This is important if the next statement would normally be indented. For example, consider an if statement that has a complex conditional expression:

if (first_part_of_condition &&
    second_part_of_condition) {
    statement_within_then_part;
}

The second part of the conditional expression is easily confused with the first statement of the then-part. This can be quite confusing if the first part of the condition is long and the && ends up way off to the right. Compare this with the alternative:

if (first_part_of_condition
    && second_part_of_condition) {
    statement_within_then_part;
}

This looks a bit odd but it makes it quite clear that the second part of the condition is not the beginning of a statement.

I do this in others contexts too but the if-statement is the most important, as the indentation is ambiguous. Of course, one could change the indentation or brace placement, but this looks odd too.

tl;dr the left end of the line is more significant to quick reading comprehension, so putting the operator on the left end is a more prominent marker that this is a continued expression, not a statement.


问:
Is it bad to use Unicode characters in variable names?
I recently tried to implement a ranking algorithm, AllegSkill, to Python 3.

Here's what the maths looks like:

No, really.

This is then what I wrote:

```<code>t = (µw-µl)/c  # those are used in
e = ε/c        # multiple places.
σw_new = (σw**2 * (1 - (σw**2)/(c**2)*Wwin(t, e)) + γ**2)**.5
</code>```

I actually thought it is unfortunate of Python 3 to not accept √ or ² as variable names.

```<code>>>> √ = lambda x: x**.5
  File "<stdin>", line 1
    √ = lambda x: x**.5
      ^
SyntaxError: invalid character in identifier
</code>```

Am I out of my mind? Should I have resorted for a ASCII only version? Why? Wouldn't an ASCII only version of the above be harder to validate for equivalence with the formulas?

Mind you, I understand some Unicode glyphs look very much like each other and some like     ▄ (or is that ▗▖ ) or ╦  just can't make any sense in written code. However, this is hardly the case for Maths or arrow glyphs.

Per request, the ASCII only version would be something along the lines of:

```<code>winner_sigma_new = ( winner_sigma ** 2 *
                    ( 1 -
                     ( winner_sigma ** 2 -
                       general_uncertainty ** 2
                     ) * Wwin(t,e)
                    ) + dynamics ** 2
                   )**.5
</code>```

...per each step of the algorithm.

答:
I feel that just replacing σ with s or sigma doesn’t make sense and is counter-productive.

What’s the potential gain of such a replacement?

Does it improve readability? Nope, not in the slightest. If that were so, the original formula would have undoubtedly used Latin letters also.

Does it improve writability? At first glance, yes. But not really: because this formula is never going to change (well, “never”). There will normally be no need to change the code, nor to extend it using these variables. So writability is really not an issue.

But programming languages have one advantage over conventional mathematical notation: you can use meaningful, expressive identifiers. In mathematics, this isn’t normally the case, so we resort to one-letter variables, occasionally making them Greek.

But Greek isn’t the problem. Non-descriptive, one-letter identifiers are.

So either keep the original notation … after all, if the programming language does support Unicode in identifiers, there’s no technical barrier. Or use meaningful identifiers. Don’t just replace Greek glyphs with Latin glyphs. Or Arabic ones, or Hindi ones.

ContentLicense: CC BY-SA 4.0


答:
What I want to know is what is the best way to show my experience to
  employers?

If degrees aren't available, known certifications are a plus. Some certification don't require a course, you could only take the exam.

What do employers want to know about my programming experience?

Your programming experience consists in projects. In your CV you write your skills. AT the interview you will be asked about projects you have worked on. Then you will speak about what you did, what problems you encountered, the solutions you found, etc.

Do employers want to look at code I wrote or could they want to see
  the software in action?

Maybe. Personally I didn't hear about employers asking to see code (besides the code you write during the technical interview, as a test). If you are a web-designer or a user interface designer, in most cases they will want to see some websites you made or designed.

Or do they only care how much my software is being used/how much it
  has created revenue? Should I write about my design and programming
  style?

Most employers will be interested in the programming languages you code fluently in, the knowledge you have and the skills you acquired. How much the software is used and revenue created is marketing stuff, not programming stuff.
Most companies have their own design and programming style. They would expect that a employee should be familiar with techniques like Agile, Scrum, Extreme depending on what they use.


答:
The problem is that without documentation, it's not clear at all what the method is doing and especially why is it returning an integer.

The easiest solution would be to use a different name for your method. Something like:

```<code>int GenerateIdAndInsert(Report report)
</code>```

Still, this is not unambiguous enough: if, like in C#, the instance of the report object is passed by reference, it would be difficult to know if the original report object was modified, or if the method cloned it and modified only the clone. If you choose to modify the original object, it would be better to name the method:

```<code>void ChangeIdAndInsert(Report report)
</code>```

A more complicated (and maybe less optimal) solution is to heavily refactor the code. What about:

```<code>using (var transaction = new TransactionScope())
{
    var id = this.Data.GenerateReportId(); // We need to find an available ID...
    this.Data.AddReportWithId(id, report); // ... and use this ID to insert a report.
    transaction.Complete();
}
</code>```

Body:
The problem is that without documentation, it's not clear at all what the method is doing and especially why is it returning an integer.

The easiest solution would be to use a different name for your method. Something like:

int GenerateIdAndInsert(Report report)

Still, this is not unambiguous enough: if, like in C#, the instance of the report object is passed by reference, it would be difficult to know if the original report object was modified, or if the method cloned it and modified only the clone. If you choose to modify the original object, it would be better to name the method:

void ChangeIdAndInsert(Report report)

A more complicated (and maybe less optimal) solution is to heavily refactor the code. What about:

using (var transaction = new TransactionScope())
{
    var id = this.Data.GenerateReportId(); // We need to find an available ID...
    this.Data.AddReportWithId(id, report); // ... and use this ID to insert a report.
    transaction.Complete();
}


问:
version control security
We are looking for a version control tool. I personally think it's pretty cool to use Git. However, my boss recommends TFS. He told me it's much more secure to use an SQL Sever based tool, such as TFS and SourceAnywhere.

In addition, my boss also sent me a link.

My question is: Is it secure/strong enough to use Git or SVN for business usage?

答:
He told me it's much more secure to use an SQL Sever based tool

Define (or get your boss to) "secure": security from data loss or access control?

The latter certainly is easier in TFS (and I suspect that's what he/she wants). So the question is who would you block from access?

Using multiple Git repositories with limited users performing pulls from others into the designated "master" (from where releases will be taken) would offer much of the same control while helping to ensure code reviews are carried out.

(I have used TFS security to block some developers1 from checking in. This was a reaction to the dire2 quality of their code. Using TFS security allowed them to get the code, modify it but not to check in. Rather they had to submit a shelve set for me or another to review and check in (on their behalf via the command line). Most, especially initially, submissions were rejected.)

Update There might be a third way. TFS on the server and Git on the client. Depends on TFS2012 (just about to RTM). See Brian Harry's Announcing Git Integration with TFS.

1Outsourcing anti-pattern: here are 6 great developers, lots of claims on their CVs, so they must be good, no need to interview/validate; they will now do most of the development.

2 Think http://thedailywtf.com/ submission candidates...

Title: version control security


问:
Flexible cloud file storage for a web.py app?
I'm creating a web app using web.py (although I may later rewrite it for Tornado) which involves a lot of file manipulation. One example, the app will have a git-style 'commit' operation, in which some files are sent to the server and placed in a new folder along with the unchanged files from the last version. This will involve copying the old folder to the new folder, replacing/adding/deleting the files in the commit to the new folder, then deleting all unchanged files in the old folder (as they are now in the new folder).

I've decided on Heroku for the app hosting environment, and I am currently looking at cloud storage options that are built with these kinds of operations in mind. I was thinking of Amazon S3, however I'm not sure if that lets you carry out these kinds of file operations in-place. I was thinking I may have to load these files into the server's RAM and then re-insert them into the bucket, costing me a fortune. I was also thinking of Progstr Filer (http://filer.progstr.com/index.html) but that seems to only integrate with Rails apps.

Can anyone help with this? Basically I want file operations to be as cheap as possible.

答:
I don't see any diff'ing or comparing between the files, so there's no need to copy them around or even load them into RAM.

My suggestion is: deal with the files individually. And if you want it to be really flexible, consider storing then in a database. If that's not feasible, at least only write the changed file to your storage. Store where's the newest version (and former versions) of that single file (not the folder) in your database.

Imagine one file is changed in a folder that contains 2k files. Just write the new file somewhere (or even better, most files are text and you can just write the delta), don't touch the entire folder.


答:
don't go with Git just because its "pretty cool", use it because it solves your problem in a way that fits with your workflow.

As for TFS... Martin Fowler had a little survey.

Anyway, you have to define "security" - do you want to protect the source from unauthorised users, or to put a read-only flag on some areas, or even prevent some people from looking at some areas. You can do this in SVN easily, use VisualSvn Server and you can apply r/rw security controls on any folder in the tree. TFS is the same. Git, on the other hand.. is not designed for this. Git works on the principle that all the source is 'copied' to each developer's workstation, so they get everything all the time. Its part of what makes git special - in that once you have all the source locally, you can merge and branch quickly and easily, but it means you do not get to put the corporate restrictions on it either.

The choice of back-end is meaningless. Use a file-based system, or a SQLServer based system.. its all the same, the level of security access depends on what the tool allows (and your admin policies on the back-end data, a SQLServer with a sa password of 'sa' or even unrestricted Windows auth would allow anyone access to the database).

Title: version control security

Body:
We are looking for a version control tool. I personally think it's pretty cool to use Git. However, my boss recommends TFS. He told me it's much more secure to use an SQL Sever based tool, such as TFS and SourceAnywhere.

In addition, my boss also sent me a link.

My question is: Is it secure/strong enough to use Git or SVN for business usage?


答:
No it is not OK! It is suitable for a procedure to modify a parameter only in procedural languages, where there is no other way; in OOP languages call the changing method on the object, in this case on the report (something like report.generateNewId()).

In this case your method does 2 things, hence breaks SRP: it inserts a record in the db and it generates a new id. The caller is not able to know that your method also generates a new id since it is simply called insertRecord().


答:
I feel that it helps reading comprehension tremendously when a line indicates that the statement continues in the next line by having the binary operator at the end, and thus rendering the statement incomplete. The missing semicolon isn’t enough for me to immediately understand that.

This may simply be a question of habit but unless you work exclusively in languages which require the semicolon (which I find pretty unrealistic given the pervasiveness of shell scripts, makefiles and languages such as Python) you probably won’t have that habit either.

EDIT: Giorgio makes an excellent point in the comments: this usage echoes common punctuation, both in mathematics and natural languages. You’d write

I sink,

  therefore I swam

You would not write

I sink

  , therefore I swam

Title: Should I put newlines before or after binary operators?

Body:
When you're in Python or Javascript, you should always put binary operators at the end of the previous line, in order to prevent newlines from terminating your code prematurely; it helps you catch errors.

But in C or C++, this isn't an issue, so I'm wondering:

Is there any reason for me to prefer the second version to the first?

```<code>return lots_of_text
       + 1;
</code>```

versus

```<code>return lots_of_text +
       1;
</code>```

(For example, does one of them help prevent other kinds of errors? Or is one of them considered more readable?)


答:
Or is it common among developers to sometimes get the program working
  without really knowing the details about why the fix worked?

There are at least three big problems with that:

It leads to a black magic mindset where you give up on the idea that you can understand the code and instead just start moving parts around hoping that problems will go away. This is the programming equivalent of pushing food around on your plate, hoping to make your dinner look sufficiently eaten that your parents won't make you eat more of your vegetables.

You can't know that the bug is actually fixed or just masked by your change unless you understand a) what the problem was, and b) how your change solves the problem.

The bug is probably not fixed, and it's going to bite you again in the near future.


问:
Is it good/safe OOP practice to have a method whose only purpose is to send/retrieve data from another class?
I have a class that performs basic MySQL operations. This is all in PHP.

class dbTables {
    public $name;
    protected $fields = array(); // array of dbTableField objects
    public $result_sets = array();
    protected $primary_key; // filled using getFields() from __construct()

    public function __construct($table_name) {
        $this->name = $table_name;
        $this->getFields();
    }
    public function removeWhitespace($table_name) {
        $this->name = $table_name;
        $this->getFields();
    }
    // etc...
}
```

<p>So all you need is the table name to create the object, and construct automatically gets a bunch of field data from <code>INFORMATION_SCHEMA</code> (names, data types, etc).</p>

<p>I also have a method for removing whitespace from a column  It's currently located in another class, but I'm thinking of moving into the above <code>dbTables</code> class. You can see the method below. I don't think it's really necessary to read the method to answer my question, but it could be helpful.</p>

<pre class="lang-php prettyprint-override"><code>protected function removeWhiteSpace($target_field,$abbrev_field,$from_size,$to_size,$options) {
    // optional conditions based on original character length and resulting character length.
    /* options: from_size = all/longer_than/shorter_than
    *   to_size = all/longer_than/shorter_than
    */
    $temp_table = $this->table_name;
    $sql = "UPDATE `$temp_table`
        SET `undo_sku` = `$target_field`, `$target_field` = REPLACE(`$target_field`,' ',''), `$abbrev_field` = 'w'";
    $where = array();
        if($options['from_size'] == 'longer_than') {
            $where[] = "`$target_field` > $from_size";
        } else if($options['from_size'] == 'shorter_than') {
            $where[] = "`$target_field` < $from_size";
        }
        if($options['to_size'] == 'longer_than') {
            $where[] = "LENGTH(REPLACE(`$target_field`,' ','')) > $to_size";
        } else if($options['from_size'] == 'shorter_than') {
            $where[] = "LENGTH(REPLACE(`$target_field`,' ','')) < $to_size";
        }
        //WHERE `$target_field` = '' AND LENGTH(REPLACE(`vnd_sku`,' ','')) <= $string_length";
    $result = mysql_query($sql);
}
</code>```

Now, if I do move it into dbTables, I will still want to use the functionality in the other class. Should I just instantiate a dbTables object whenever I need to use removeWhitespace? Or, could I give dbTables its own removeWhitespace method like this:

protected function removeWhiteSpace($target_field,$abbrev_field,$from_size,$to_size,$options) {
  /* options: from_size = all/longer_than/shorter_than
  * to_size = all/longer_than/shorter_than
  */
  $dbtable = new dbTables($this->table_name);
  $temp_table = $this->table_name;

  $result = $dbtable->removeWhiteSpace($target_field,$abbrev_field,$from_size,$to_size,$options);
  return $result;
}
```

The advantage I see is that now I have a way to limit instantiation of the dbTables object in various other classes. Methods that need to use removeWhiteSpace can use $this->removeWhiteSpace instead of instantiating a dbTables object. The class's own removeWhiteSpace method takes care of that.

I'm kind of new to OOP, though, so I'm just wondering if that is good practice or bad.

I also hope I'm asking this question in the right place. I'm pretty sure it's not a StackOverflow question.

答:
If you find yourself wanting to instantiate an object (e.g. dbTables) just to access one bit of very specific functionality in it, without actually using that object for what it is, then it's usually a code smell and a sign you need to portion up your code a little differently.

Why not factor out your removal of whitespace functionality, in a reusable and context-free a way as possible, into some sort of utility class? Then this can be accessed from all the places needing the functionality.

Alternatively, leave the function where it is, but make it static (class level), so that it can be called without using an instance of the class it's in.


答:
I think the code smell here is that you have multiple classes that hold table names.

Good object-oriented design calls for a class that wraps a table (which itself holds reference to class that wraps database connection) and using that to refer to tables in all the other classes.

I suspect that's what you are aiming at with the dbTables class. So yes, move the method there, but replace the table_name field in the other class with reference to dbTables instance, so the wrapper just says $this->table->removeWhitespace(...).

Title: Is it good/safe OOP practice to have a method whose only purpose is to send/retrieve data from another class?

Body:
I have a class that performs basic MySQL operations. This is all in PHP.

class dbTables {
    public $name;
    protected $fields = array(); // array of dbTableField objects
    public $result_sets = array();
    protected $primary_key; // filled using getFields() from __construct()

    public function __construct($table_name) {
        $this->name = $table_name;
        $this->getFields();
    }
    public function removeWhitespace($table_name) {
        $this->name = $table_name;
        $this->getFields();
    }
    // etc...
}
```

<p>So all you need is the table name to create the object, and construct automatically gets a bunch of field data from <code>INFORMATION_SCHEMA</code> (names, data types, etc).</p>

<p>I also have a method for removing whitespace from a column  It's currently located in another class, but I'm thinking of moving into the above <code>dbTables</code> class. You can see the method below. I don't think it's really necessary to read the method to answer my question, but it could be helpful.</p>

<pre class="lang-php prettyprint-override"><code>protected function removeWhiteSpace($target_field,$abbrev_field,$from_size,$to_size,$options) {
    // optional conditions based on original character length and resulting character length.
    /* options: from_size = all/longer_than/shorter_than
    *   to_size = all/longer_than/shorter_than
    */
    $temp_table = $this->table_name;
    $sql = "UPDATE `$temp_table`
        SET `undo_sku` = `$target_field`, `$target_field` = REPLACE(`$target_field`,' ',''), `$abbrev_field` = 'w'";
    $where = array();
        if($options['from_size'] == 'longer_than') {
            $where[] = "`$target_field` > $from_size";
        } else if($options['from_size'] == 'shorter_than') {
            $where[] = "`$target_field` < $from_size";
        }
        if($options['to_size'] == 'longer_than') {
            $where[] = "LENGTH(REPLACE(`$target_field`,' ','')) > $to_size";
        } else if($options['from_size'] == 'shorter_than') {
            $where[] = "LENGTH(REPLACE(`$target_field`,' ','')) < $to_size";
        }
        //WHERE `$target_field` = '' AND LENGTH(REPLACE(`vnd_sku`,' ','')) <= $string_length";
    $result = mysql_query($sql);
}
</code>```

Now, if I do move it into dbTables, I will still want to use the functionality in the other class. Should I just instantiate a dbTables object whenever I need to use removeWhitespace? Or, could I give dbTables its own removeWhitespace method like this:

protected function removeWhiteSpace($target_field,$abbrev_field,$from_size,$to_size,$options) {
  /* options: from_size = all/longer_than/shorter_than
  * to_size = all/longer_than/shorter_than
  */
  $dbtable = new dbTables($this->table_name);
  $temp_table = $this->table_name;

  $result = $dbtable->removeWhiteSpace($target_field,$abbrev_field,$from_size,$to_size,$options);
  return $result;
}
```

The advantage I see is that now I have a way to limit instantiation of the dbTables object in various other classes. Methods that need to use removeWhiteSpace can use $this->removeWhiteSpace instead of instantiating a dbTables object. The class's own removeWhiteSpace method takes care of that.

I'm kind of new to OOP, though, so I'm just wondering if that is good practice or bad.

I also hope I'm asking this question in the right place. I'm pretty sure it's not a StackOverflow question.


答:
As you can see from the answers, there is no consensus on this matter. Unless you work in a team, use what you are more comfortable with.

I prefer inserting a newline before operators.

Whenever I have to break lines, I usually put at most one term of the same "level" on a line:

Newton's law of gravitation in Python:

```<code>force = (
    gravitational_constant
    * mass_1
    * mass_2
    / (distance * distance)
)
</code>```

Compare this to:

```<code>force = (
    gravitational_constant *
    mass_1 *
    mass_2 /
    (distance * distance)
)
</code>```

I want to know, that I "divide by distance squared", I don't want to know, that "mass_2 gets divided", because that's not how I think of mathematical expressions.

Further, I usually want to know first, what I am doing (operator), before I care about what I do things with (operands).

Or consider this convoluted SQL statement:

```<code>WHERE
  a = 1
  AND b = 2
  AND c = 3
  AND ( -- or put the OR on one line together with the AND
    d = 3
    OR e = 1)
  AND x = 5
</code>```

This allows me to see how the individual conditions are connected very easily, just by skimming from top to bottom without having to read every line until the end to find the operator as opposed to:

```<code>WHERE
  a = 1 AND
  b = 2 AND
  c = 3 AND
  (
    d = 3 OR
    e = 1) AND
  x = 5
</code>```

I think about the former in terms of "X is true", then I amend that by saying: "AND this is also true" which feels more natural to me than the other way around. Further, I find the first much easier to parse visually.

Or a PHP example:

```<code>$text = "lorem ipsum"
      . "dolor sit amet, "
      . "consectetur adipisicing elit, "
      . "sed do eiusmod tempor";
</code>```

Again, I can just skim read vertically to see I'm simply concatenating text, because most of the time I feel that I do not actually care what is inside the strings/conditions.

Of course, I would not apply this style unconditionally. If putting the newline after an operator seems to make more sense to me, I would do so, but I can't think of an example at the moment.

Body:
As you can see from the answers, there is no consensus on this matter. Unless you work in a team, use what you are more comfortable with.

I prefer inserting a newline before operators.

Whenever I have to break lines, I usually put at most one term of the same "level" on a line:

Newton's law of gravitation in Python:

force = (
    gravitational_constant
    * mass_1
    * mass_2
    / (distance * distance)
)

Compare this to:

force = (
    gravitational_constant *
    mass_1 *
    mass_2 /
    (distance * distance)
)

I want to know, that I "divide by distance squared", I don't want to know, that "mass_2 gets divided", because that's not how I think of mathematical expressions.

Further, I usually want to know first, what I am doing (operator), before I care about what I do things with (operands).

Or consider this convoluted SQL statement:

WHERE
  a = 1
  AND b = 2
  AND c = 3
  AND ( -- or put the OR on one line together with the AND
    d = 3
    OR e = 1)
  AND x = 5

This allows me to see how the individual conditions are connected very easily, just by skimming from top to bottom without having to read every line until the end to find the operator as opposed to:

WHERE
  a = 1 AND
  b = 2 AND
  c = 3 AND
  (
    d = 3 OR
    e = 1) AND
  x = 5

I think about the former in terms of "X is true", then I amend that by saying: "AND this is also true" which feels more natural to me than the other way around. Further, I find the first much easier to parse visually.

Or a PHP example:

$text = "lorem ipsum"
      . "dolor sit amet, "
      . "consectetur adipisicing elit, "
      . "sed do eiusmod tempor";

Again, I can just skim read vertically to see I'm simply concatenating text, because most of the time I feel that I do not actually care what is inside the strings/conditions.

Of course, I would not apply this style unconditionally. If putting the newline after an operator seems to make more sense to me, I would do so, but I can't think of an example at the moment.


答:
We're one of Google's competitors. Our answer? Basically two.

First, we do calculate the complete address-to-address solution. Yup, that's a big matrix. Even worse, we do so for all times of day, all days of the week. There's sufficient similarity in the input domain to cache intermediate results, which makes the problem tractable. Still, try to get a bulk rate on harddisks.

Note that this offline calculation is done using a different algorithm. It uses far more memory than the algorithm we intend to test, but not linearly more (i.e. it uses less than 1000 times more memory when calulating a thousand routes).

Secondly, participating users provide us with real-world results. We validate millions of routes driven. Are the actual routes as fast as predicted?

And sure, you do find bugs that way. All the times. E.g. a stretch of road that's bounded on both sides by a "local traffic only zone" *. There's only one way ;) that you're going to find that in testing, and that's when you plan a route to that particular road.

* A "local traffic only zone" may only be used when you're starting or ending a route in such a zone. The stretch in the middle is therefore disconnected from the main roadnetwork. This is either a zoning or a map fault.


问:
Do you start migrating your Swing project to JavaFX
I have a 4 years old project which is written in Swing + SwingX. Currently, it is still alive and still kicking.

However, as more GUI related feature requests coming in (For instance, a sortable tree table), I start to feel the difficulty in fulling the requests. This is true especially since there isn't any active development going around SwingX project.

Also, I can hardly find any good, yet actively maintained/ developed/ evolving GUI Java framework.

I was wondering, do any of the Swing developers feel the same thing? Have you start to migrate your Swing project to a much more active developed GUI framework, like JavaFX?

答:
I've had great experience using RCP in large, desktop-based applications. It basically started as an abstraction of Eclipse's GUI layer and has come a long way since then. Instead of Swing, which is based on AWT, RCP builds on JFace, which in turn is based on SWT. It allows you to develop applications and use the GUI concepts that Eclipse itself uses (views, editors, perspectives, wizards, etc.). It's very scalable and, like Eclipse itself, is constantly being improved.

However, I've never migrated an existing project from Swing to RCP; I'd imagine that it would take quite a while to wrap your head around the different paradigms and if you haven't separated your model and view layers well, you're bound to have a hard time. But since you asked about things like sortable tree tables, RCP is great at that.

If you'd like to reserach this further, you may want to try out Lars Vogel's tutorial or have a look at some examples of open source projects or commercial projects that use RCP.


答:
Open source projects use git to accept thousands of contributions from completely untrusted developers.  Does no one in management ever stop to wonder how they accomplish that without constantly introducing malware?  Or why the people with the most untrusted contributors actually prefer git?

If you can't trust your own developers with read access, you have a whole other set of problems.  However, that's easy with git too.  Just put limited access code on its own server.  That's even easier to secure than permissions on a single server.

The next argument people make is, "Yeah, but with git you copy the entire history, not just the latest version."  I have news for you.  If you have read access to any VCS, you have enough access to create a git repository no one knows about.  People do this all the time when management foists a subpar VCS on them.  You don't know about it because it doesn't actually create the nightmare problems you fear it will.

There are plenty of reasons an enterprise might choose another VCS over git.  Security isn't one of them. Probably the biggest reason is that git is more of one component of a VCS than an integrated system.  You have to add your own authentication and authorization, integration with CI and bug tracking, etc.  Also, git has a lot of power, but with that comes the need for locking down servers to prevent accidental use of that power, and more training.  If you don't know about, or don't want, more advanced workflows, git looks like an unnecessarily complicated version of svn.

Title: version control security


问:
Sporadic unittests or TDD?
I've read some basics about unit tests and TDD, but I find it hard to convince myself why TDD can have an advantage over only selected unittests.

I've read common arguments for TDD, but don't see the improvment compared to simple unittests. Maybe you can help to clarify:

TDD allows a loosely coupled, testable design -> I believe I can well imagine if a class is theoretically testable, without having to write tests; Loose coupling is a fundamental requirement that one can judge without refering to TDD?!

TDD gives confidence in refactoring -> Isn't it more efficient to add selected unittests as soon as you start refactoring? While you have to think what to cover by test, you still save writing a lot of tests.

TDD makes you define the interface first -> To me it seems some minor points are easier to decide while coding (which also agrees with agile?). It's even hard to predict a nested return data structure, but after coding I can often validate that I get what I expected. I made up the nested data while coding (a small unit) and see the behaviour. I'd save a lot of time writing the method first and using the validated result a posteriori to plug into a unittest.

from what I've read many (of course not all) sources state that TDD does require more development time even considering the benefit for debugging; merely the code quality improves -> Can it be that some programmers make different kinds of mistakes and for some TDD doesn't cover the type of mistakes they make anyway? So if my typical bugs are not approachable by predictable tests, it's not for me?

TDD aids changing teams, and larger interacting teams -> Is this a large issue? I can imagine it is, however as for the moment I program alone I cannot judge. How does TDD help teams in ways that... and here is the important point: other ways don't? It can force some discipline for less experienced team members, but apart from that any advantages?

答:
An important thing I've learned last week regarding TDD is that it is something different than writing your tests first only. The main advantage of TDD as a design principle is that it makes you think about what you need when you need it (the YAGNI principle).

Interesting reads:

Microsoft Takes it on the Chin Over Test-Driven Development (Scott
Bellware)

The various meanings of TDD (Roy Osherove)

Does Test-Driven Development Really Improve Software Design Quality? (David S. Janzen, Hossein Saiedian)

Red-Green-Refactor (James Shore)

Title: Sporadic unittests or TDD?


问:
How to split large, tightly coupled classes?
I have some huge classes of more than 2k lines of code (and growing) that I would like to refactor if possible, to have some more light and clean design.

The reason it is so big is mainly because these classes handle a set of maps that most methods need to access, and methods are very connected to each other.

I will give a very concrete example: I have a class called Server that handles incoming messages.
It has methods like joinChatroom, searchUsers, sendPrivateMessage, etc.
All of these methods manipulate the maps such as users, chatrooms, servers, ...

Maybe it would be nice if I could have a class handling messages concerning Chatrooms, another handling all about Users, etc.
but the main problem here is that I need to use all of the maps in most of the methods.
That's why for now they are all sticked in the Server class as they all rely on these common maps and the methods are very connected to each other.

I would need to create a class Chatrooms, but with a reference to each of the other objects.
A class users again with a reference to all the other objects,
etc.

I feel like I would be doing something wrong.

答: You should be able to create a class which hold each collection.  While Server will need a reference to each of these collections it only need the minimal amount of logic which won't involve accessing or maintain the underlying collections.  This will make more obvious exactly what the Server is doing, and separate out how it does it.

OwnerDisplayName: Matthew

OwnerDisplayName: Peter Lawrey


答:
When I have seen big classes like this I have found that there is often a class (or more) in there trying to get out. If you know of a method that you think might not be related to this class then make it static. The compiler will then tell you of other methods that this methd calls. Java will insist they are static too. You make them static. Again the compiler will tell you of any method that it calls. You keep doing this over and over again until you have no more compile failures. Then you have a load of static methods in your big class. You can now pull these out into a new class and make the method non static. You can then call this new class from your original big class (which should now contain fewer lines)

You can then repeat the process until you are happy with the class design.

Martin Fowler's book is a really good read so I would recommend this too as there are times you cannot use this static trick.

Title: How to split large, tightly coupled classes?

Body:
I have some huge classes of more than 2k lines of code (and growing) that I would like to refactor if possible, to have some more light and clean design.

The reason it is so big is mainly because these classes handle a set of maps that most methods need to access, and methods are very connected to each other.

I will give a very concrete example: I have a class called Server that handles incoming messages.
It has methods like joinChatroom, searchUsers, sendPrivateMessage, etc.
All of these methods manipulate the maps such as users, chatrooms, servers, ...

Maybe it would be nice if I could have a class handling messages concerning Chatrooms, another handling all about Users, etc.
but the main problem here is that I need to use all of the maps in most of the methods.
That's why for now they are all sticked in the Server class as they all rely on these common maps and the methods are very connected to each other.

I would need to create a class Chatrooms, but with a reference to each of the other objects.
A class users again with a reference to all the other objects,
etc.

I feel like I would be doing something wrong.


答: In terms of software metric, big class is bag. There are unbounded papers proving this statement. Why is that ? because big classes are harder to understand than small classes and it's need more time to modified . Moreover, Big classes are so tough when you do testing . And big classes are very hard for you when you want to reuse it because it's very likely contain undesired stuff.</p>

OwnerDisplayName: Minh Cat VO


答:
Since most of your code is existing, i would suggest making use of helper classes to move out your methods. That will help easy refactoring. So, your server class will still contain the maps in it. But it makes use of an helper class say ChatroomHelper with methods like  join(Map chatrooms, String user), List getUsers(Map chatrooms), Map getChatrooms(String user).

Server class will hold an instance of ChatroomHelper, UserHelper etc thus moving the methods to its logical helper classes.
Wtih this you can leave the public methods in server intact, so any caller doesnt need to change.

OwnerDisplayName: javausersoma


问:
Why is OOP difficult?
When I started using an object-oriented language (Java), I pretty much just went "Cool" and started coding. I've never really thought about it until only recently after having read lots of questions about OOP. The general impression I get is that people struggle with it. Since I haven't thought of it as hard, and I wouldn't say I'm any genius, I'm thinking that I must have missed something or misunderstood it.

Why is OOP difficult to understand? Is it difficult to understand?

答:
I think the reason OOP is difficult for many is because the tools don't really facilitate it.

Computer languages today are an abstraction of what is going on in the computer.

OOP is an abstracted way to represent abstractions.

So we are using an abstraction to build abstractions with an abstraction. Add to this that what we are abstracting are usually very complex physical/social interactions and, well, no wonder.

Title: Why is OOP difficult?


答:
Look, I think your question is too generic to answer since we don't really have a full description of the problem so offering a good design with so little knowledge is impossible. I can, just as an example, address one of your concerns about the possible futility of better design.

You say that your Server class and your future Chatroom class share data about users, but this data should be different. Server probably has a set of users connected to it, while a Chatroom, which itself belongs to a Server, has a different set of users, a sub-set of the first set, of only the users currently logged into a specific Chatroom.

This is not the same information, even if the data types are identical.

There are many many advantages to a good design.

I have not read the aforementioned book by Fowler, yet, but I have read other stuff by Folwer and it was recommended to me by people I trust, so I feel comfortable enough to concur with the others.

OwnerDisplayName: Shrulik