问:
Single-developer GIT workflow (moving from straightforward FTP)
I'm trying to decide whether moving to VCS is sensible for me. I am a single web developer in a small organisation (5 people). I'm thinking of VCS (Git) for these reasons: version control, offsite backup, centralised code repository (can access from home).

At the moment I work on a live server generally. I FTP in, make my edits and save them, then reupload and refresh. The edits are usually to theme/plugin files for CMSes (e.g. concrete5 or Wordpress). This works well but provides no backup and no version control.

I'm wondering how best to integrate VCS into this procedure. I would envisage setting up a Git server on the company's web server, but I'm not clear how to push changes out to client accounts (usually VPSes on the same server) - at the moment I simply log into SFTP with their details and make the changes directly.

I'm also not sure what would sensibly represent a repository - would each client's website get their own one?

Any insights or experience would be really helpful. I don't think I need the full power of Git by any means, but basic version control and de facto cloud access would be really useful.

EDIT: I've narrowed it down to the two options that seem most sensible. The first is based on ZweiBlumen's answer, whereby edits are made on the live server and committed from there to the (external) Git server. This has the advantage that my workflow won't change much (there's the extra step of making the commits, but otherwise it's identical).

The second option is to work locally using XAMPP, then to commit changes from the local machine. Only when the site goes live do I upload the finished article to the web server from the local machine (immediately after the final commit to Git). This seems okay in theory, but if the site thereafter requires amends and I make them on the live server (as I usually do) then I'll need to manually copy over the changed files in my local repo, then commit those changes to the Git server. This seems unduly complex and is perhaps too much of a departure from my current workflow.

I think on balance I'll give option #1 a go, and see how I get on.

答:
What I do (with Subversion, but will work with Git as well) is commit everything to one Subversion repository, but obviously split into projects, branches, tags as necessary. I then checkout these repositories to the live server. Thus when I make a change on my dev machine and commit this to the repository, it is often simply a case of updating the checked out copy on the live server to make the changes live. The added bonus is that if I do need to make a quick fix on the live server I commit this to the repository from the server and update the working copy on my dev machine.

I am sure there are other ways of managing this, but I find this quite straightforward and I am in exactly the same situation as you: single developer in a small organisation (4 people).


问:
How do you share your craft with non programmers?
Sometimes I feel like a musician who can't play live shows. Programming is a pretty cool skill, and a very broad world, but a lot of it happens "off camera"- in your head, in your office, away from spectators.

You can of course talk about programming with other programmers, and there is peer programming, and you do get to create something that you can show to people, but when it comes to explaining to non programmers what is it that you do, or how was your day at work, it's sort of tricky.

How do you get the non programmers in your life to understand what is it that you do?

NOTE: this is not a repeat of Getting non-programmers to understand the development process, because that question was about managing client expectations.

答:
You kinda can't really share your craft - just headlines about your job with others

However, what you can do is instead of sharing your craft , is share your life with people who are in the same craft as you  (:

ContentLicense: CC BY-SA 2.5


问:
Does giving a developer a slower development machine result in faster/more efficient code?
Suppose I give my developers a screaming fast machine.  WPF-based VS2010 loads very quickly.  The developer then creates a WPF or WPF/e application that runs fine on his box, but much slower in the real world.

This question has two parts...

1) If I give a developer a slower machine, does that mean that the resulting code may be faster or more efficient?

2) What can I do to give my developers a fast IDE experience, while giving 'typical' runtime experiences?

Update:

For the record, I'm preparing my even-handed response to management. This isn't my idea, and you folks are helping me correct the misguided requests of my client.  Thanks for giving me more ammunition, and references to where and when to approach this.  I've +1'ed valid use cases such as:

- specific server side programming optimizations

- test labs

- the possibly buying a better server instead of top of the line graphics cards

答:
This theory is simple-minded and outdated. It was true back in the days.

I remember spending more time microoptimizing my Turbo Pascal stuff on my pre-Pentium computer. It just made sense before Y2K, much less ever since. Nowadays you don't optimize for 10 year old hardware. It's sufficient to testrun software to find bottlenecks. But as everyone here agress, this doesn't mean developer (and thus optimization) productivy correlates to giving them outdated hardware for development.


问:
Version control and personal configuration file
Our project uses a user-specific configuration file. This file is currently not in version control, since it is different for each user. The problem is, whenever a developer adds a new module that requires configuration, or changes the name of an existing modules, the other developers get errors because their private configuration files are not updated.

To solve the problem, we thought of working with two configuration files: a default/global configuration file that will be in version control and will be updated regularly by each developer that adds a new module, and a private configuration file that will be kept out of version control and will contain only the user-specific changes.

However, this still seems like an ad-hoc solution.

Can you propose a better solution?

What do the professionals do?

答:
Typically how I've seen it done is to have a configuration file with default values checked into the repository. These could be, as an example, the values needed on the testing server. Then, when a developer checks out the file, they will have all of the values. If a new field is added or a field is removed, this is handled in a merge. A developer will check in the needed value for the target server and not check in any other changes to fields that are for his personal development environment.

It takes care to ensure that the merge is done right, but it seems pretty safe to me.

ContentLicense: CC BY-SA 3.0


答:
It's a reasonable solution.

You need a way of specifying the initial value(s) of any new configuration element(s). These have to be stored somewhere and a global, read-only, configuration file is the obvious choice.

Then when each user changes their personal configuration you write these changes to their local copy.

Your code will need to read the global configuration first and the the user specific one to overwrite any changed values. This will be far simpler than reading the local one and then trying to work out which ones haven't been set and hence need reading from the global settings file.

If you use something like XML for the storage then you don't have to worry about handling the case where you remove settings. They won't get requested from the users copy of the file and if you recreate the file on save they'll get removed the first time the application is used after the change.

Title: Version control and personal configuration file

Body:
Our project uses a user-specific configuration file. This file is currently not in version control, since it is different for each user. The problem is, whenever a developer adds a new module that requires configuration, or changes the name of an existing modules, the other developers get errors because their private configuration files are not updated.

To solve the problem, we thought of working with two configuration files: a default/global configuration file that will be in version control and will be updated regularly by each developer that adds a new module, and a private configuration file that will be kept out of version control and will contain only the user-specific changes.

However, this still seems like an ad-hoc solution.

Can you propose a better solution?

What do the professionals do?


答:
What we do here is create blocks of settings. This can be done in Zend like this:

```<code>[production]
key1: parameter1
key2: parameter2

[testing: production]
key1: parameter2
key3: parameter4
</code>```

This means that testing inherits production and extends it with key3.
All each developer then needs to do is set his environment (testing or production in this case)

Body:
What we do here is create blocks of settings. This can be done in Zend like this:

[production]
key1: parameter1
key2: parameter2

[testing: production]
key1: parameter2
key3: parameter4

This means that testing inherits production and extends it with key3.
All each developer then needs to do is set his environment (testing or production in this case)


答:
It's rather easy to create a post-update hook, that automatically updates (exporting with git archive is preferred for security reasons) the web server data directory when you push to a specific branch.

So have a git repository set up somewhere (for security reasons I'd put it on different server than the web) with such hook. You will of course need test server to test larger changes, which may be either on your local machine or updated by pushing to different branch. In either case you can bypass it for trivial spelling and CSS fixes by simply doing commit and push.

Title: Single-developer GIT workflow (moving from straightforward FTP)

Body:
I'm trying to decide whether moving to VCS is sensible for me. I am a single web developer in a small organisation (5 people). I'm thinking of VCS (Git) for these reasons: version control, offsite backup, centralised code repository (can access from home).

At the moment I work on a live server generally. I FTP in, make my edits and save them, then reupload and refresh. The edits are usually to theme/plugin files for CMSes (e.g. concrete5 or Wordpress). This works well but provides no backup and no version control.

I'm wondering how best to integrate VCS into this procedure. I would envisage setting up a Git server on the company's web server, but I'm not clear how to push changes out to client accounts (usually VPSes on the same server) - at the moment I simply log into SFTP with their details and make the changes directly.

I'm also not sure what would sensibly represent a repository - would each client's website get their own one?

Any insights or experience would be really helpful. I don't think I need the full power of Git by any means, but basic version control and de facto cloud access would be really useful.

EDIT: I've narrowed it down to the two options that seem most sensible. The first is based on ZweiBlumen's answer, whereby edits are made on the live server and committed from there to the (external) Git server. This has the advantage that my workflow won't change much (there's the extra step of making the commits, but otherwise it's identical).

The second option is to work locally using XAMPP, then to commit changes from the local machine. Only when the site goes live do I upload the finished article to the web server from the local machine (immediately after the final commit to Git). This seems okay in theory, but if the site thereafter requires amends and I make them on the live server (as I usually do) then I'll need to manually copy over the changed files in my local repo, then commit those changes to the Git server. This seems unduly complex and is perhaps too much of a departure from my current workflow.

I think on balance I'll give option #1 a go, and see how I get on.


答:
The program should have a default setting in code for when the value is not found in the configuration file.  This way as new things are added it won't break,  your upgrade path would be smoother, and your users will have fallback for when they mess up the configuration file as well.

Another more complex example would be at program startup or some other key point, open the configuration file using an initialization module and add any defaults that are missing, but this seems pretty heavy.


答:
Though you already got some good answers here, most of them miss the root cause of your problem: your user config files seem to contain more than just user-specific information, they also contain (perhaps redundant) information which is under version control  somewhere else, probably in different files, like module names.

I can think of two possible solutions here:

try to separate that information rigorously. For example, don't use any module names in your user config. Use id numbers (for example, GUIDs) to refer to modules, and let those id numbers never change after they have been assigned to a module. Of course, that probably has the drawback that your user config files lose some of their simplicity they might have now. You will perhaps need to create a GUI tool to edit your config files instead of using a plain text editor.

give your config file format a version number, and whenever something like a module name is changed, assign them a new version number. Then you can provide an upgrade script which checks the version numbers, and if the config file is not up-to-date, it changes all module names it finds within the file and increases the version number afterwards. This can be automated, so the process of upgrading won't disturb your team mates in their daily work.

EDIT: after reading your posting again, I think your supposed solution is reasonable, as long as new modules are just added, but not renamed. What I wrote above will allow to change module names or the structure of the configuration of existing modules afterwards. But if you don't need that, I would stick to the most simple solution.


问:
What arguments can I use to "sell" the BDD concept to a team reluctant to adopt it?
I am a bit of a vocal proponent of the Behaviour Driven Development methodology (aka BDD).  I've been applying BDD for a couple of years now, and have adopted StoryQ as my framework of choice when developing DotNet applications. Even though I have been unit testing for many years, and had previously shifted to a test-first approach, I've found that I get much more value out of using a BDD framework, because my tests capture the intent of the requirements in relatively clear English within my code, and because my tests can execute multiple assertions without ending the test halfway through - meaning I can see which specific assertions pass/fail at a glance without debugging to prove it.

This has really been the tip of the iceberg for me, as I've also noticed that I am able to debug both test and implementation code in a more targeted manner, with the result that my productivity has grown significantly, and that I can more easily determine where a failure occurs if a problem happens to make it all the way to the integration build due to the output that makes its way into the build logs. Further, the StoryQ api has a lovely fluent syntax that is easy to learn and which can be applied in an extraordinary number of ways, requiring no external dependencies in order to use it.

So with all of these benefits, you would think it an easy to introduce the concept to the rest of the team.  Unfortunately, the other team members are reluctant to even look at StoryQ to evaluate it properly (let alone entertain the idea of applying BDD), and have convinced each other to try and remove a number of StoryQ elements from our own core testing framework, even though they originally supported the use of StoryQ, and even though the code they wish to remove doesn't impact on any other part of our testing system. Doing so would end up increasing my workload significantly overall and really goes against the grain, as I am convinced through practical experience that it is a better way to work in a test-first manner in our particular working environment, and can only lead to greater improvements in the quality of our software, given I've found it easier to stick with test first using BDD. To further clarify, the majority of the unit tests we have tend to be quite brittle and difficult to maintain, a holdover from years of poorly applied testing where a reluctance to stick with a test-driven process has seen developers fall back on old habits and do all of their testing at the end of the project (these same people claim to be Agile!).

So the question really comes down to the following:

What arguments can I use to really drive the point home that it would be better for this team to use StoryQ, or at the very least to adopt the BDD methodology?

Can you point me to any anecdotal evidence that I can use to support my argument to adopt BDD as our standard method of choice?

What counter arguments can you think of that could suggest that my wish to encourage the team to adopt BDD might be in error?  Yes, I'm happy to be proven wrong provided the argument is a sound one.

NOTE: I am not advocating that we rewrite our tests in their entirety, but rather to simply start working in a different manner for all future testing work, and preferably in the manner in which we engage our customers.

And for those of you wishing to learn more about BDD, the following links may be useful:

http://dannorth.net/introducing-bdd/

http://en.wikipedia.org/wiki/Behaviour_driven_development

http://behaviour-driven.org/Introduction

For those interested in more details, we're a small team of 4 working on about 5 large projects. The "pilot trial" for BDD ran for about 2 months initially, with another approximately 4 month period following. Team accepted that I should continue to work this way and were to do their own trials. I've been BDD-ing for about 2 years now since the trial ended, while the others have become very good at ducking the issue. Rather than forcing a "confrontation" over the issue, I'm looking for ways to gently persuade the team to get off their collective behinds and make the time to do their bit.

答:
It may be time to recruit management.  If you have given a try and seen solid results, but the team is balking, management may have to get involved.

This is especially true if they are hurting the companies most productive team member.  Be prepared for backlash.  You may start by approaching management and seeking to have the team stop undercutting you by taking out your test cases.


问:
How to draw an E-R diagram?
I am learning DBMS in my college. Recently I was given an assignment to draw a E-R Model of a Bus Reservation system which handles Reservations, Ticketing and cancellations.

I understand the theory about E-R model when I study from a book, but it gets confusing when I try to draw one from scratch.

How should one proceed? There seem to be a lot of ways to model a E-R diagram for a particular requirement. It's really confusing.

Can anyone explain taking Bus reservation System as an example?

Here is the model I made (But I am not confident with it because at every step, I could think of many more alternatives!)  -

Entity_Set  Passenger(passengerID,name,age,gender)

Entity_Set Ticket(ticketID,status)

//Status is either WaitingList , Confirmed  or Cancelled

Entity_Set Bus (busID,MaxSeats,Type)

//Type is Ac or Non-AC

Entity_Set Route(routeID,ArrivalTime,DepartureTime,Source,Destination)

And a Ternary relationship between Passenger, Ticket and Bus with attributes as passengerID, ticketID, busID .

Binary relationship between Bus and Route with attributes as busID, routeID .

I have few doubts regarding -

1 . Should we take Time as a composite attribute with Arrival and Departure as its attributes (What's the difference if we take that way?)

2 . The same with Source and Destination. Should they be made into a composite attribute "Place" or something like "Location"?

3. Are there any weak entity sets here? I have no idea at all what to take as a Weak entity set?

答:
An E-R diagram simply displays the objects (entities) and how they relate to one another.

So, to draw your diagram, first identify your objects. These are often identified by nouns (people, places, things - and objects are things). We'll start with the following:

Bus

Reservation

From there, each object has certain attributes that help describe them (often, they're fields that hold adjectives). So you might have something like:

Bus

-ID

-LicensePlate

-Capacity

-PurchaseDate

Reservation

-ID

-BusID

-PassengerName

Now, how do these things relate to one another? Well, a bus can hold many passengers, but any given passenger can only be on one bus at any given time (as indicated in the above entity definitions by the BusID attribute in Reservation). Therefore, the relationship between a Bus and a Reservation would be one to many and is generally displayed by something similar to |---> (this is "Crow's Foot" notation, which is what I was taught as what's typically used, adjust if necessary, of course). To display the relationship, you might have something like:

Bus <----| Reservation

The head of the arrow should be on the side of "one" (one bus, many reservations).
If you're still stuck, just start identifying all the possible objects and draw your blocks, then start filling in the attributes, then look for the relationships between them. A diagram tool, such as Visio or Dia, makes it really easy to draw, change, and delete diagram blocks, so I recommend grabbing something like that to help you work it out.

Edit - Your diagram looks good to me. You mention that you can think of many more alternatives, so ask yourself these questions:

If the alternative is attributes, are they required for my assignment? Remember, this can be either explicit or implicit (keep in mind, too, your professor's expectations for past assignments to help you predict what is needed). If not, then you probably don't need to include it.

If the alternative is a different way of expressing the relationships, does the alternate way follow the rules of the E-R diagram you're building?

On relationships again, if you've learned about normalization, does it follow normalization rules? (This may or may not be a requirement for you right now, depending on whether you're expected to know about data normalization techniques.)

Does it actually make sense? It might be worth drawing out your alternatives just to see if they make as much sense "on paper" as they did in your head. This is where using a drawing tool comes in handy, since you can draw it out fairly quickly and easily in another file and compare the two side by side.

Title: How to draw an E-R diagram?


问:
Declaring return variables in c# methods vs returning the value directly
In a debate regarding return variables, some members of the team prefer a method to return the result directly to the caller, whereas others prefer to declare a return variable that is then returned to the caller (see code examples below)

The argument for the latter is that it allows a developer that is debugging the code to find the return value of the method before it returns to the caller thereby making the code easier to understand: This is especially true where method calls are daisy-chained.

Are there any guidelines as to which is the most efficient and/or are there any other reasons why we should adopt one style over another?

Thanks

```<code>    private bool Is2(int a)
    {
        return a == 2;
    }

    private bool Is3(int a)
    {
        var result = a == 3;
        return result;
    }
</code>```

答:
Personally I find the first example easier to read. You can still debug it, by setting a break point in the return statement and adding a == 2 to the watch window or by using quick watch.

But this is really a matter of personal preference. Both versions are OK.

ContentLicense: CC BY-SA 4.0


问:
SQL DB design to support user feeds (in application like facebook)
I have a social network server with a MySql DB. I want to show the users feeds like done in Facebook. Example - UserX now Friend with userY, userX did like on postX etc.

Currently I have table: C1 : UserId C2 : LogType (now friend, did like etc) C3 : ObjectId (Can be userId or postId) - set depending on the LogType.

Currently to get all related logs to show to the user I do the following queries: 1. Get All user Friends userIds 2. Query all rows which C1 is in userIds (I query completed) 3. Scan the DB and see - if LogType equals DidLike, check if post's OwnerId is the userId - if yes add it to logs.

And so on.

Obvious this is not efficient at all.

I am looking for a better way. I thought I had in mind: Create a new table (in addition to the Log table) C1 : UserId C2 : LogId (from Log table) C3 : UserID of the one who did the action When querying logs - look in the table and get related Logs (by LogId) from LogTable.

Updating the table: Whenever user doing action that should be in the log: 1. Add the Log entry to LogTable. 2. Scan the DB and see which users are interested with the Log (Who my friends are, Who is the owner of the post) and add related entries to the new table. (must be done in BG). 3. If user UNFRIEND another user - then look in the logs for all rows where C3 == UNFRIENDED user id and delete them.

Any opinions? Other suggestions?

答:
Your Problem is Data is not normalized, That is what writing this query a Pain.

It can still be done though, (I would give you the SQL if I fully understood your data Model).

TO properly normalize your data, You need the following tables:

```<code>Users
UserFriends - M:M With Users (Needs a timestamp for the action)
Posts - 1:M With Users (Needs a timestamp for the action)
PostsLikes - 1:M With Posts (Needs a timestamp for the action)
</code>```

Now I know what you are thinking I created the LOG table to Speed this up, to not have so many joins! TO avoid this exactly this! Well you basically shot yourself in the foot. Because writing efficient complex queries against your data is basically an impossibility.

That that your new data model is Done, If you need better performance Denormalize the entire Data model into one Giant table called TimeLine, that is used to display the timeline. This Table Does not replace your data model, it Complements it. Any time you insert a record into the any of the other tables insert a record here too logging that action. (Insert to records if the action effects two users). Index this table On Userid & TimeStamp. You should always be able to rebuild this table based off you other data.

If you need a complex query,  query your base tables.

Body:
Your Problem is Data is not normalized, That is what writing this query a Pain.

It can still be done though, (I would give you the SQL if I fully understood your data Model).

TO properly normalize your data, You need the following tables:

Users
UserFriends - M:M With Users (Needs a timestamp for the action)
Posts - 1:M With Users (Needs a timestamp for the action)
PostsLikes - 1:M With Posts (Needs a timestamp for the action)

Now I know what you are thinking I created the LOG table to Speed this up, to not have so many joins! TO avoid this exactly this! Well you basically shot yourself in the foot. Because writing efficient complex queries against your data is basically an impossibility.

That that your new data model is Done, If you need better performance Denormalize the entire Data model into one Giant table called TimeLine, that is used to display the timeline. This Table Does not replace your data model, it Complements it. Any time you insert a record into the any of the other tables insert a record here too logging that action. (Insert to records if the action effects two users). Index this table On Userid & TimeStamp. You should always be able to rebuild this table based off you other data.

If you need a complex query,  query your base tables.


问:
Optimal communication pattern to update subscribers
What is the optimal way to update the subscriber's local model on changes C on a central model M? ( M + C -> M_c)

The update can be done by the following methods:

Publish the updated model M_c to all subscribers. Drawback: if the model is big in contrast to the change it results in much more data to be communicated.

Publish change C to all subscribes. The subscribers will then update their local model in the same way as the server does. Drawback: The client needs to know the business logic to update the model in the same way as the server. It must be assured that the subscribed model stays equal to the central model.

Calculate the delta (or patch) of the change (M_c - M = D_c) and transfer the delta. Drawback: This requires that calculating and applying the delta (M + D_c = M_c) is an cheap/easy operation.

If a client newly subscribes it must be initialized. This involves sending the current model M. So method 1 is always required.

Think of playing chess as a concrete example: Subscribers send moves and want to see the latest chess board state. The server checks validity of the move and applies it to the chess board. The server can then send the updated chessboard (method 1) or just send the move  (method 2) or send the delta (method 3): remove piece on field D4, put tower on field D8.

答:
Consider following scenarios: 1) client subscribes to changes and needs initial snapshot, 2) client subscribes to changes and does not need initial snapshot and 3) client needs only initial snapshot and not interested in changes.

For initial subscription, you can send a model snapshot (M) or its schema if snapshot is not required.

For updates, you need to calculate the delta to send to client. If the M is small, then D_c will be calculated easily. You could send the whole model to client, but what will happen when the model will grow? And you don't want to client to be aware of  the business logic to send only C


答:
When the code is as easily readable as your example, there is nothing wrong with returning the result of a logical operation such as return a == 2.  However, if the return value is a more complex statement or looks something like

```<code>return a > 2? doOptionA().getResult() > makeDecision("greaterThan2") : doOptionB().getResult() == makeDecision("lessThan2");
</code>```

then you'll want to use variables to store pieces of that first and simplify the return statement, for the sake of readability.

Title: Declaring return variables in c# methods vs returning the value directly

Body:
In a debate regarding return variables, some members of the team prefer a method to return the result directly to the caller, whereas others prefer to declare a return variable that is then returned to the caller (see code examples below)

The argument for the latter is that it allows a developer that is debugging the code to find the return value of the method before it returns to the caller thereby making the code easier to understand: This is especially true where method calls are daisy-chained.

Are there any guidelines as to which is the most efficient and/or are there any other reasons why we should adopt one style over another?

Thanks

```<code>    private bool Is2(int a)
    {
        return a == 2;
    }

    private bool Is3(int a)
    {
        var result = a == 3;
        return result;
    }
</code>```

Body:
When the code is as easily readable as your example, there is nothing wrong with returning the result of a logical operation such as return a == 2.  However, if the return value is a more complex statement or looks something like

return a > 2? doOptionA().getResult() > makeDecision("greaterThan2") : doOptionB().getResult() == makeDecision("lessThan2");

then you'll want to use variables to store pieces of that first and simplify the return statement, for the sake of readability.


问:
What is the simplest human readable configuration file format?
Current configuration file is as follows:

```<code>mainwindow.title = 'test'
mainwindow.position.x = 100
mainwindow.position.y = 200

mainwindow.button.label = 'apply'
mainwindow.button.size.x = 100
mainwindow.button.size.y = 30

logger.datarate = 100
logger.enable = True
logger.filename = './test.log'
</code>```

This is read with python to a nested dictionary:

```<code>{
  'mainwindow':{
    'button':{
      'label': {'value':'apply'},
       ...
  },
  'logger':{
     datarate: {'value': 100},
     enable: {'value': True},
     filename: {'value': './test.log'}
  },
  ...
}
</code>```

Is there a better way of doing this? The idea is to get XML type of behavior and avoid XML as long as possible. The end user is assumed almost totally computer illiterate and basically uses notepad and copy-paste. Thus the python standard "header + variables" type is considered too difficult.

The dummy user edits the config file, able programmers handle the dictionaries. Nested dictionary is chosen for easy splitting (logger does not need or even cannot have/edit mainwindow parameters).

答:
The best thing you can do is provide a mockup of your solution, and perhaps a mockup of a couple other solutions, and ask two or three representative users of your system. They will be much better at telling you what they like than the self-selected people who answer questions on this site.

That being said, for "basically computer illiterate" users I think the format you show in your question is probably the best plain text format. If they really are computer illiterate, you might want to consider a simple GUI so they don't have to hand-edit configuration files.

OwnerDisplayName: Juha


答:
Because I use Resharper with Visual Studio, Ctrl-RV (Or Ctrl-Alt-V, if you use the Resharper/IntelliJ key bindings) turns your first example into your second example. So when I want to debug, I can do that easily enough. And if I forget to put it back then I won't feel bad because Ctrl-RI will put it right back again to make it easier to read.

Seriously, waste your time arguing about more important things. Like where to put your leading braces or spaces vs tabs.


问:
How to improve designer and developer work flow?
I work in a small startup with two front end developers and one designer. Currently the process starts with the designer sending a png file with the whole page design and assets if needed. My task as front end developer is to convert it to a HTML/CSS page. My work flow currently looks like this:

Lay out the distinct parts using html elements.

Style each element very roughly (floats, minimal fonts and padding) so I can modify it using inspection.

Using Chrome Developer Tools (inspect) add/change css attributes while updating the css file.

Refresh the page after X amount of changes

Use Pixel Perfect to refine the design more.

Sit with the designer to make last adjustments.

Inferring the paddings, margins, font sizes using trial and error takes a lot of time and I feel the process could become more efficient but not sure how to improve it.

Using PSD files is not an option since buying Photoshop for each developer is currently not considered. Design guide is also not available since design is still evolving and new features are introduced.

Ideas for improving the process above and sharing how the process looks like in your company will be great.

答:
Make sure that the designer uses web-safe fonts. Many designers come from a print and/or rendered design background and are used to being able to pick from any font they can find. Web is different.

The design should clearly indicate font type, size, weight and decoration on each text element.

Sit down with your designer and show and explain what happens when text overflows the bounds of it's container and how important it is to identify which text-containers must be able to expand in the design.

Re-use design elements. Links, buttons, panels, menu - what have you. It's the designers job to make sure that any new pages or components conform to existing design and uses the same look-and-feel components.

Mark distances and paddings between component in pixels. A design is a lot like an architects drawing of a house. If you want pixel-perfect, the design has to indicate pixel-distance and dimensions.


答:
In a simple example such as that, either one is OK.

For more complicated examples, I prefer the second way.  That is only becuase it is more readable and others will likely have to maintain the code.


答:
I'd follow these steps:

Set the remote server up with a proper public/private key pair for remote push/pull

Set up two branches testing and release

Develop locally with a test environment in the testing branch

When you are happy merge with the release branch and push to the remote server

Hook on the remote server to update to latest version of release

Set up one repo per website, to keep them from cluttering each other up. The separate branches allow you to avoid having the current "good" version lock stepped to what you are currently working on, which may or may not function.


答:
I second the style guide. One thing though that was not clear is if the design is shipped as a flattened png, then how are non-css-able assets derived? Ideally these would be provided by the designer at time of inital hand off, rather then have your developers spend the time slicing them out of the single image that they have.

Also you will likely gain from having your developers in the room while your designer starts with some rough sketches and initial comps. This gets the developers up to speed quickly as well as giving them a voice to present limitations with the design.

Title: How to improve designer and developer work flow?

Body:
I work in a small startup with two front end developers and one designer. Currently the process starts with the designer sending a png file with the whole page design and assets if needed. My task as front end developer is to convert it to a HTML/CSS page. My work flow currently looks like this:

Lay out the distinct parts using html elements.

Style each element very roughly (floats, minimal fonts and padding) so I can modify it using inspection.

Using Chrome Developer Tools (inspect) add/change css attributes while updating the css file.

Refresh the page after X amount of changes

Use Pixel Perfect to refine the design more.

Sit with the designer to make last adjustments.

Inferring the paddings, margins, font sizes using trial and error takes a lot of time and I feel the process could become more efficient but not sure how to improve it.

Using PSD files is not an option since buying Photoshop for each developer is currently not considered. Design guide is also not available since design is still evolving and new features are introduced.

Ideas for improving the process above and sharing how the process looks like in your company will be great.


问:
What is history and concept of code annotation?
C# and Java has code attribute and code annotation. I don't know about other languages, but I know the code annotation feature is used to expand language itself.

I knew what it is, but I want to know how it developed over time. I want to know its history. How it demanded and how it implemented. Is this possible to implement this in kind of concept on LISP, Smalltalk or C++?

And is there a general term to call the concept of annotation?

答:
This usually is related to reflection, since reflection is the only way to look at attributes or annotations (depending on the language). So it might be possible for LISP but not for C++.

Also, annotations are only a series of name/values that are tagged to a specific class, method, field, etc.

So inside the meta-object that stores information about a class (ex. it's methods, fields, etc.), one needs to add another map (or list) that contains information about all the attributes an class or method contains.

Obviously, if you don't know what a meta-object is, you should study meta-programming a little, particularly CLOS (Common Lisp Object System), that is the mother of all languages implementing metaprogramming.


答:
I can't speak much for Java Annotations but C# Attributes were introduced in the first version of .NET when Microsoft was pushing Web Services heavily. Attributes allow you to provide metadata about your code (or metaprogramming as it were) that the framework can look at and use to enhance your code. For instance in .NET 1, you could use the WebMethod attribute to tell the framework that you want to expose a method over a Web Service. The framework would handle the rest.

In C++ people use Preprocessor Directives and Macros to perform Metaprogramming. Other languages (like Lisp and Boo) have Metaprogramming built into the language. This article on wikipedia provides a great starting point on the topic.

Title: What is history and concept of code annotation?

Body:
C# and Java has code attribute and code annotation. I don't know about other languages, but I know the code annotation feature is used to expand language itself.

I knew what it is, but I want to know how it developed over time. I want to know its history. How it demanded and how it implemented. Is this possible to implement this in kind of concept on LISP, Smalltalk or C++?

And is there a general term to call the concept of annotation?


问:
Actor based concurrency and cancellation
I'm reading about actor based concurrency and I appreciate the simplicity of actors sequentially processing messages on a single thread. However there is one scenario that doesn't seen possible.

Suppose that actor A sends a message to actor B, who then performs some long running task and returns a completion message to actor A. How can actor A force actor B to cancel the long running task after it has started?

If actor B is running the task in its message queue thread, it won't pick up the cancellation message until it had completed the task; if actor B runs the task in a background thread then it seems to be violating the principle of actors.

Is there a common way that this scenario is handled with actors? Or does each actor language/framework take a different approach? Or is this not a suitable problem to tackle via actors?

答: Split a long-running operation into chunks and have the actor send itself a Continue-message.</p>

OwnerDisplayName: Akash

OwnerDisplayName: Viktor Klang


问:
C++ and function pointers assessment: lack of inspiration
I've got an assessment to give to my students.

It's about C++ and function pointers.

Their skill is middle: it the first year of a programming school after bachelor.

To give you something precise, here's a sample of a solution of one of 3 exercices they had to do in 30 minutes (the question was: "here's a version of a code that could be written with function pointers, write down the same thing but with function pointers"):

```<code>typedef void (*fcPtr) (istream &);
fcPtr ArrayFct [] = { Delete , Insert, Swap, Move };

void HandleCmd (const string && Cmd)
{
    string AvalaibleCommands ("DISM");
    string::size_type Pos;
    istringstream Flux (Cmd);

    char CodeOp;
    Flux >> CodeOp;

    Pos = AvalaibleCommands.find (toupper (CodeOp));

    if (Pos != string::npos) {
        ArrayFct [Pos](Flux);
    }
}
</code>```

Any idea where I could find some inspiration?

Some of the students have understood the principles, even though it's very hard for them to write C++ code. I know them, I know they're clever, and I'm pretty sure they should be very good project managers. So, writing C++ code is not that important after all. Understanding is the most important part (IMHO).

I'm wondering about maybe break the habits, and give half of the questions about the principle, or even better, give some sample in other language and ask them why it's better to use function pointers instead of classical programming (usually a big switch case).

Any idea where I could look? Find some inspiration?

答:
My immediate reaction would be to sit back and think twice about doing this at all. Pointers to functions aren't exactly the most commonly used feature in C. At least 95% of the time that you'd use a pointer to a function in C, you'd be better off using a virtual function in C++.

What you're left with is such a tiny amount of legitimate usage that there's just not much point in teaching it at all unless you've covered every other detail of the language in so much detail that there's just nothing else left to cover (which, after only 4 years of classes strikes me as highly unlikely).


问:
Is application-specific data required for good unit testing?
I am writing unit tests for a fairly simple function that depends on a fairly complicated set of data. Essentially, the object I am manipulating represents a graph and this function determines whether to chart a line, bar, or pie chart based on the data that came back from the server.

This is a simplified version, using jQuery:

```<code>setDefaultChartType: function (graphObject) {
  var prop1 = graphObject.properties.key;
  var numCols = 0;
  $.each(graphObject.columns, function (colIndex, column) {
    numCols++;
  });

  if ( numCols > 6 || ( prop1 > 1 && graphObject.data.length == 1) ) {
    graphObject.setChartType("line");
  } else if ( numCols <=6 && prop1 == 1 ) {
    graphObject.setChartType("bar");
  } else if ( numCols <=6 && prop1 > 1 ) {
    graphObject.setChartType("pie");
  }
}
</code>```

My question is, should I use mock data that is procured from the actual database? Or can I just fabricate data that fits the different cases?

I'm afraid that fabricating data will not expose bugs arising from changes in the database, but on the other hand, it would require a lot more effort to keep the test data up-to-date that I'm not sure is necessary.

答:
If you already have data that you can anonymise, using it that will be quicker than chasing down a BA (Business Analyst) to review your test data to make sure that you have appropriate coverage.

I'm afraid that fabricating data will not expose bugs arising from changes in the database

That's not the point of unit testing, if your tests depend on LIVE data, then it's an integration test.

For your unit tests, get a snapshot of data that covers ALL situations (or as many as possible that already exist) from the database and use that for your unit tests, and fabricate any edge cases with the help of a BA.

If your requirements don't change, your tests won't get out of date. If your requirements do change, you'd need to update the tests anyway.


问:
Dual-licensing LGPL 2.1 and LGPL 3
I maintain a software, a small PHP library, that is released under the LGPL version 3 license (LGPLv3). Someone wants to use the library in their software which has the GPL version 2 license. This license compatibility matrix suggests this is not possible without changing the licensing terms of one of the software. I have been requested to dual-license my code under LGPLv2.1 and LGPLv3. Does it make sense, and what might the drawbacks be?

Thank you.

答:
The major drawback is that you lose the benefit of the changes made in LGPLv3.  These changes mainly clarify how libraries may be combined with other works.

I would suggest just dual-licensing under LGPLv3 and plain GPLv2.  This will give the other software project what they want, while mostly not giving up the benefits of LGPLv3.

Title: Dual-licensing LGPL 2.1 and LGPL 3

OwnerDisplayName: novalis


答:
You shouldn't be testing the code that brings the data to the browser in the same test as the code that builds your bar/line/pie chart.  You should make it easy to supply the data to your chart building code and easily test it.  This will also provide you with good separation of concerns AND make your tests run faster by simply taking mocked data rather than the results of a database read.

Ensure that tests are easy to write, fast to run, and have clear intent (short).  Part of clear intent means it's better to show the mocked data your test is using rather than relying on a blackbox of data that another developer will have to run SQL/read an outside file to see.

Title: Is application-specific data required for good unit testing?

Body:
I am writing unit tests for a fairly simple function that depends on a fairly complicated set of data. Essentially, the object I am manipulating represents a graph and this function determines whether to chart a line, bar, or pie chart based on the data that came back from the server.

This is a simplified version, using jQuery:

```<code>setDefaultChartType: function (graphObject) {
  var prop1 = graphObject.properties.key;
  var numCols = 0;
  $.each(graphObject.columns, function (colIndex, column) {
    numCols++;
  });

  if ( numCols > 6 || ( prop1 > 1 && graphObject.data.length == 1) ) {
    graphObject.setChartType("line");
  } else if ( numCols <=6 && prop1 == 1 ) {
    graphObject.setChartType("bar");
  } else if ( numCols <=6 && prop1 > 1 ) {
    graphObject.setChartType("pie");
  }
}
</code>```

My question is, should I use mock data that is procured from the actual database? Or can I just fabricate data that fits the different cases?

I'm afraid that fabricating data will not expose bugs arising from changes in the database, but on the other hand, it would require a lot more effort to keep the test data up-to-date that I'm not sure is necessary.


答: For a real unit test the data should describe the happy path as well as edge cases and malformed data. Figure out how the data would look like for the average case (happy path). If it works with that, try to think of data that is on the edges like no data at all or data that is exactly as long as your columns permit (edge cases). At last check if the code wirks with data that does not look like you would normally expect it, e.g. if you store a phone number as a string serve your object a phone number that contains letters (malformed data).</p>


问:
What are some best practices for minimizing code?
While maintaining the sites our development team has created, we have come across include files and plugins that have proven to be very useful to more then one part of our applications.  Most of these modules have come with two different files, a normal source file and a min file.  Seeing that the performance and speed of a page can be increased by minimizing the size of the file, we're looking into doing that to our pages as well.

The problem that we run into is a lot of our normal pages (written in ASP classic) is a mix of HTML, ASP, Javascript, CSS, and include files.  We have some pages that have their JS both in include files and in the page, depending on if the function is only really used in that page or if it's used in many other pages.  For example, we have a common.js and an ajax.js file, both are used in a lot of pages, but not all of them.  As well as having some functions in a page that doesn't really make sense to put into one master page.

What I have seen a few other people do online is use one master JS file and place all of their javascript into that, minify it, gzip it, and only use that on their production server.  Again, this would be great, but I don't know if that fully works for our purposes.

What I'm looking for is some direction to go with on this.  I'm in favor of taking all of our JS and putting it in one include file, and just having it included in every page that is hit.  However, not every page we have needs every bit of JS.  So would it be worth the compilation and minifying of the files into one master file and include it everywhere, or would it be better to minify all other files and still include them on a need-to-use basis?

答:
I suppose the 80-20 rule might apply here.

Suppose that all your pages have 80% of common JS code. Identify it, make it into a single file and include everywhere.

The rest is page-specific; if some of it can be reused across a meaningful subset of pages, put it to another file, or several such files. If you have some truly unique code on some pages, leave it as is.

You will end up with something like this:

common.js // included on each of 100 pages;

foo.js // used on 10 foo-related pages

bar.js // used on 7 bar-related pages

etc.

Your typical page will include common.js and maybe a specific file.


答:
The designer could put the font/color/line-height in the copy of the thing in the design.
For example:

Tahoma Bold 20px / 26px #000


答: I'm with Patrick Hughes.  Build a simple app for editing configurations.  The config file itself could be a little more complex and might contain attributes for the editor to use (display name, help text, value type, min/max value, etc).</p>

Title: What is the simplest human readable configuration file format?

Body:
Current configuration file is as follows:

```<code>mainwindow.title = 'test'
mainwindow.position.x = 100
mainwindow.position.y = 200

mainwindow.button.label = 'apply'
mainwindow.button.size.x = 100
mainwindow.button.size.y = 30

logger.datarate = 100
logger.enable = True
logger.filename = './test.log'
</code>```

This is read with python to a nested dictionary:

```<code>{
  'mainwindow':{
    'button':{
      'label': {'value':'apply'},
       ...
  },
  'logger':{
     datarate: {'value': 100},
     enable: {'value': True},
     filename: {'value': './test.log'}
  },
  ...
}
</code>```

Is there a better way of doing this? The idea is to get XML type of behavior and avoid XML as long as possible. The end user is assumed almost totally computer illiterate and basically uses notepad and copy-paste. Thus the python standard "header + variables" type is considered too difficult.

The dummy user edits the config file, able programmers handle the dictionaries. Nested dictionary is chosen for easy splitting (logger does not need or even cannot have/edit mainwindow parameters).


答: One way to do this is to to build a controller object. This controller has the ability to receive messages, and route commands to other actors. In addition, you will have another worker object where the actual processing occurs (that is the one responsible for the possibly long operation). That worker object should be able to accept commands from the controller and act on them. It can periodically check a memory location to see if it is required to continue processing or not.</p>

Title: Actor based concurrency and cancellation

Body:
I'm reading about actor based concurrency and I appreciate the simplicity of actors sequentially processing messages on a single thread. However there is one scenario that doesn't seen possible.

Suppose that actor A sends a message to actor B, who then performs some long running task and returns a completion message to actor A. How can actor A force actor B to cancel the long running task after it has started?

If actor B is running the task in its message queue thread, it won't pick up the cancellation message until it had completed the task; if actor B runs the task in a background thread then it seems to be violating the principle of actors.

Is there a common way that this scenario is handled with actors? Or does each actor language/framework take a different approach? Or is this not a suitable problem to tackle via actors?


答: You can include in the structure of the Command a Boolean token stating whether the Command has been cancelled. Actors which enqueue this Command can retain or separately store a reference to the Command and thus to the cancellation token. During execution of the Command by a second actor, especially while waiting for long-running external processes like file or stream reading/writing, the actor should periodically check the value of this cancellation flag. To cancel the Command, any thread with knowledge of the Command can set the cancellation Boolean, and the thread running the Command will see it has been cancelled on its next inspection, stop work, clean up and exit. This generally requires the code relating to a Command to be designed with the ability to be cancelled; this doesn't necessarily require knowledge of the Command itself by the code, but it usually does require passing in a Boolean by reference, which must be periodically tested within the method.</p>


问:
Is there a difference in usage between halting and terminating?
The title says it all: Are halting and terminating synonyms in the context of computability theory?</p>

答:
Well, it's not called the Terminating Problem; it's called the "Halting Problem."

Given that:

```<code>while(true) { }
</code>```

does not halt, but you could "terminate" it by kicking the power cord out of the wall (or clicking "End Task" in Task Manager), I would say, no, they are not synonyms.

Body:
Well, it's not called the Terminating Problem; it's called the "Halting Problem."

Given that:

while(true) { }

does not halt, but you could "terminate" it by kicking the power cord out of the wall (or clicking "End Task" in Task Manager), I would say, no, they are not synonyms.


答:
http://en.wikipedia.org/wiki/Divergence_(computer_science)

In computer science, a computation is said to diverge if it does not terminate or terminates in an (unobservable) exceptional state. Otherwise it is said to converge.

More specifically relevant to halting,

In the lambda calculus an expression is divergent if it has no normal form.

So the difference between halting -- process does not continue indefinitely -- and terminating is that terminating implies returning a normal result.  Not finishing abruptly (with an error or exceptional condition) or wedging itself in a state where no reduction rule applies.

This problem can be illustrated in the λ-calculus extended with booleans and numbers used by Benjamin Pierce:

```<code>(λx.if x then x else x)(1)
</code>```

which will not reduce because it gets stuck at

```<code>(if 1 then 1 else 1)
</code>```

which does not match any reduction rule since the only rules that apply to if are

if true then v else t → v

if false then t else v → v

and 1 is neither true nor false.

Title: Is there a difference in usage between halting and terminating?

Body: The title says it all: Are halting and terminating synonyms in the context of computability theory?</p>

Body:
http://en.wikipedia.org/wiki/Divergence_(computer_science)

In computer science, a computation is said to diverge if it does not terminate or terminates in an (unobservable) exceptional state. Otherwise it is said to converge.

More specifically relevant to halting,

In the lambda calculus an expression is divergent if it has no normal form.

So the difference between halting -- process does not continue indefinitely -- and terminating is that terminating implies returning a normal result.  Not finishing abruptly (with an error or exceptional condition) or wedging itself in a state where no reduction rule applies.

This problem can be illustrated in the λ-calculus extended with booleans and numbers used by Benjamin Pierce:

(λx.if x then x else x)(1)

which will not reduce because it gets stuck at

(if 1 then 1 else 1)

which does not match any reduction rule since the only rules that apply to if are

if true then v else t → v

if false then t else v → v

and 1 is neither true nor false.


问:
Why do "Joke" programming languages exist?
First of all please be aware this post contains some abusive language but I hope it will not bother anyone. I apologize for the bad language but that's what the name is.

As I've been doing documentation on existing programming languages attempting to make a complete list of them I stumbled across terrible programming languages, which were clearly not made for actual use and implementation due to their insane difficulty. Languages such as Brainfu*k and LOLCODE or Whitespace are fool languages because they have no real use.

For example, a "Hello world" program written in BrainFu*k. Taken from Wikipedia:

```<code>The following program prints "Hello World!" and a newline to the screen:

+++++ +++++             initialize counter (cell #0) to 10
[                       use loop to set the next four cells to 70/100/30/10
    > +++++ ++              add  7 to cell #1
    > +++++ +++++           add 10 to cell #2
    > +++                   add  3 to cell #3
    > +                     add  1 to cell #4
    <<<< -                  decrement counter (cell #0)
]
> ++ .                  print 'H'
> + .                   print 'e'
+++++ ++ .              print 'l'
.                       print 'l'
+++ .                   print 'o'
> ++ .                  print ' '
<< +++++ +++++ +++++ .  print 'W'
> .                     print 'o'
+++ .                   print 'r'
----- - .               print 'l'
----- --- .             print 'd'
> + .                   print '!'
> .                     print '\n'
</code>```

or another example taken from LOLCODE language:

```<code> HAI
 CAN HAS STDIO?
 PLZ OPEN FILE "LOLCATS.TXT"?
     AWSUM THX
         VISIBLE FILE
     O NOES
         INVISIBLE "ERROR!"
 KTHXBYE
</code>```

These languages are very difficult to learn/read/work with. My question is - Why do they exist? What is the purpose of them? Also, is there an official "name" for these type of languages?

答: Your question answers itself: they're jokes, they're supposed to make you laugh. Occasionally they're written to make fun of bad decisions in other languages (satire). If you are working in language design to begin with, you'll have a lot of tools for parsing and code generation at your fingertips, so these generally aren't that hard to implement. The only reason to actually use one of these is languages is to show that you are in on the joke.</p>


答:
My question is - Why do they exist? What is the purpose of them?

Paraphrased from Wikipedia's page on Esoteric Programming Languages:

They are designed as a test of the boundaries of computer programming
  language design, as a proof of concept, or as a joke. There is usually
  no intention of the language being adopted for mainstream programming,
  although some esoteric features such as visuospatial syntax have
  inspired practical applications in the arts. Such languages are often
  popular among hackers and hobbyists.

Usability is rarely a high priority for such languages; often quite
  the opposite. The usual aim is to remove or replace conventional
  language features while still maintaining a language that is
  Turing-complete, or even one for which the computational class is
  unknown.

Also, is there an official "name" for these type of languages?

Yes - "Esoteric Programming Languages"

Title: Why do "Joke" programming languages exist?

Body:
First of all please be aware this post contains some abusive language but I hope it will not bother anyone. I apologize for the bad language but that's what the name is.

As I've been doing documentation on existing programming languages attempting to make a complete list of them I stumbled across terrible programming languages, which were clearly not made for actual use and implementation due to their insane difficulty. Languages such as Brainfu*k and LOLCODE or Whitespace are fool languages because they have no real use.

For example, a "Hello world" program written in BrainFu*k. Taken from Wikipedia:

```<code>The following program prints "Hello World!" and a newline to the screen:

+++++ +++++             initialize counter (cell #0) to 10
[                       use loop to set the next four cells to 70/100/30/10
    > +++++ ++              add  7 to cell #1
    > +++++ +++++           add 10 to cell #2
    > +++                   add  3 to cell #3
    > +                     add  1 to cell #4
    <<<< -                  decrement counter (cell #0)
]
> ++ .                  print 'H'
> + .                   print 'e'
+++++ ++ .              print 'l'
.                       print 'l'
+++ .                   print 'o'
> ++ .                  print ' '
<< +++++ +++++ +++++ .  print 'W'
> .                     print 'o'
+++ .                   print 'r'
----- - .               print 'l'
----- --- .             print 'd'
> + .                   print '!'
> .                     print '\n'
</code>```

or another example taken from LOLCODE language:

```<code> HAI
 CAN HAS STDIO?
 PLZ OPEN FILE "LOLCATS.TXT"?
     AWSUM THX
         VISIBLE FILE
     O NOES
         INVISIBLE "ERROR!"
 KTHXBYE
</code>```

These languages are very difficult to learn/read/work with. My question is - Why do they exist? What is the purpose of them? Also, is there an official "name" for these type of languages?


答:
Esoteric languages are really just mind exercises.  Why do crossword puzzles or word jumble puzzles exist?  Because we can.

Brainf*ck is an exercise in spartanism; what sort of language can we create that has as few opcodes as possible, while still being Turing-complete?

LOLCATS is a nod to those folks who ask "CAN I HAZ THE CODEZ," while delightfully being a language that actually works.


问:
When does pair programming work? When to avoid it?
Rather than slavishly pair program all the time, we use pair programming selectively on our team. I think it works best in the following circumstances:

Ramping up brand new team members on a project (instead of letting them wade through documentation or code on their own).

Having junior and senior people work together (helps to show some of the skills and tricks of the more experienced developers, plus it allows the old dogs to learn new tricks sometimes).

When someone is trying to track down a defect, it often helps to pair with a fresh set of eyes.

When to use pair program and why?

When to avoid pair programming? Why?

答:
Good night

many times we have debated about practices of Extreme Programming and the pair programming. Back in time, we are able to understand that programming is a solo activity because programmers needed concentration and isolation. The programmers at that time were in the zone, a mental state where they could efficiently focus on the code and make nice and creative decisions.

Pair programming seems to be also risky if you assume one programmer interrupts each other. On the other hand, it's more difficult to interrupt two programmers working together. On Solo programming for example, it will be easier to be interrupted, so it's almost impossible to a solo programmer to stay in the "zone".

The code quality is another when dead line is just around the corner. People will be always in a hurry, be a pair programmers or a solo programmer: they will not apply certain best practices and will just forget about unit testing.

I would stick with pair programming. Because when it come to risks, when one programmer is gone, you will always have another guy to document the process and teach everyone else how it works.


答:
Esoteric Programming languages, also known as Turing Tarpits due to the difficulty of writing anything useful with them, are mostly built for fun or to see how far a particular idea can be taken. Whitespace for instance, privileges a lexical item typically ignored in most languages. Shakespeare on the other hand is designed to mimic Shakespearean Drama. Brainfuck actually has a practical purpose. It is designed to employ the smallest possible compiler at under 200 Bytes.

There is a second category of the actual joke languages such as Malebolge and INTERCAL, neither of which is designed to be practical in any way whatsoever and have features that actively make them harder to use.


答:
For fun.

Because can be worth in designing a language, even if the language is, syntactically, a steaming pile of mythical brontosaurus poo.

It is an absurdest sort of thing to do.  Or a zen thing maybe.


答:
To quote brainf*ck's entry in wikipedia:

Urban Müller created brainfuck in 1993 with the intention of designing a language which could be implemented with the smallest possible compiler,[2] inspired by the 1024-byte compiler for the FALSE programming language.

These languages are created by the creator as some sort of exercise or a way to try something new or even just as a joke. It is a fun way for a programmer to keep their skills sharp and get internet famous.


答:
Take a look at the wikipedia article Esoteric programming languages. That's what these languages are called.

Shakespeare and Chef are other nice examples.

The reason for writing such a language could be just to see what's possible or just for the fun of it. I think most of the time they're not intended to do serious work with them.

Just enjoy looking at the codes and maybe if you're into creating programming languages try to understand how they work and how they are implemented.

Edit: There are also "jokes" that you can do in "proper" programming languages. See the programs at The International Obfuscated C Code Contest. I don't understand almost none of these programs and yet they do amazing stuff with them and only just for fun.


答: I think creating such a language can be a useful and fun way of learning how to implement a parser and/or compiler...</p>


问:
How would you know if you've written readable and easily maintainable code?
How would one know if the code one has created is easily readable, understandable, and maintainable? Of course from the author's point of view, the code is readable and maintainable, because the author wrote it and edited it, to begin with. However, there must be an objective and quantifiable standard by which our profession can measure code.

These goals are met when one may do the following with the code without the expert advice of the original author:

It is possible to read the code and understand at a basic level the flow of logic.

It is possible to understand at a deeper level what the code is doing to include inputs, outputs, and algorithms.

Other developers can make meaningful changes to the original code such as bug fixes or refactoring.

One can write new code such as a class or module that leverages the original code.

How do we quantify or measure code quality so that we know it readable, understandable, and maintainable?

答:
Readable and maintainable code:
Code that, upon first-sight, a programmer can understand well enough to be able to easily:

re-use it via its interface, or

debug it, or

change its behaviour. (add/remove a feature), or

optimise it

test it

This boils down to 'clarity'. i.e How many questions does the programmer have to ask of a particular segment of code before they are sure that they 'understand what it does well enough' to achieve the current task in hand without causing unexpected side-effects.

The book 'Code Complete, by Steve McConnell' goes into this in great detail.

He goes through various metrics that you can use determine if code is of good quality.

See an example here:
http://books.google.co.uk/books?id=3JfE7TGUwvgC&lpg=PT376&pg=PT389#v=onepage&q&f=false


问:
C++ : Lack of Standardization at the Binary Level
Why ISO/ANSI didn't standardize C++ at the binary level? There are many portability issues with C++, which is only because of lack of it's standardization at the binary level.

Don Box writes, (quoting from his book Essential COM, chapter COM As A Better C++)

C++ and Portability

  Once the decision is made to
  distribute a C++ class as a DLL, one
  is faced with one of the fundamental
  weaknesses of C++, that is, lack of
  standardization at the binary level.
  Although the ISO/ANSI C++ Draft
  Working Paper attempts to codify which
  programs will compile and what the
  semantic effects of running them will
  be, it makes no attempt to standardize
  the binary runtime model of C++. The
  first time this problem will become
  evident is when a client tries to link
  against the FastString DLL's import library from
  a C++ developement environment other
  than the one used to build the
  FastString DLL.

Are there more benefits Or loss of this lack of binary standardization?

答:
I think the lack of a standard for C++ is  a problem in today's world of de-coupled, modular programming. However, we have to define what we want from such a standard.

No-one in their right mind wants to define the implementation or platform for a binary. So you can't take a x86 Windows dll and start using it on a x86_64 Linux platform. That would be a bit much.

However, what people do want is the same thing we have with C modules - a standardised interface at the binary level (ie once compiled). Currently, if you want to load a dll in a modular app, you export C functions and bind to them at runtime. You cannot do that with a C++ module. It would be great if you could, which would also mean that dlls written with one compiler could be loaded by a different one. Sure, you still wouldn't be able to load a dll built for an incompatible platform, but that's not a problem that needs fixing.

So if the standards body defined what the interface a module exposed, then we'd have a lot more flexibility in loading C++ modules, we wouldn't have to expose C++ code as C code, and we'd probably get a lot more use of C++ in script languages.

We also wouldn't have to suffer things like COM that attempt to provide a solution to this problem.

OwnerDisplayName: Nawaz


答:
I think it's worth adding that the Wiki page doesn't mention what I consider probably the most interesting esoteric programming language: unlambda. Unlambda claims to be: "Your Functional Programming Language Nightmares Come True".

Whereas most esoteric languages are just minimalist and fairly ugly, unlambda honestly has some quite interesting concepts (albeit, expressed in the ugliest possible ways). It does, however, have/use some rather interesting concepts -- chief among them, "abstraction elimination" (see the web site for details).

All in all, it's definitely at least as ugly as most of the others, but from a viewpoint of programming language theory, much more interesting than most.

Getting back to the original question about why the exist: at least most of them are just for fun. Most, however, do represent a fairly serious attempt at some exploration of the bare minimum of features necessary while still being Turing complete.


问:
Handling "related" work within a single agile work item
I'm on a project team of 4 devs, myself included. We've been having a long discussion on how to handle extra work that comes up in the course of a single work item.

This extra work is usually things that are slightly related to the task, but not always necessary to accomplish the goal of the item (that may be an opinion). Examples include but are not limited to:

refactoring of the code changed by the work item

refactoring code neighboring the code changed by the item

re-architecting the larger code area around the ticket. For example if an item has you changing a single function, you realize the entire class now could be redone to better accommodate this change.

improving the UI on a form you just modified

When this extra work is small we don't mind. The problem is when this extra work causes a substantial extension of the item beyond the original feature point estimation. Sometimes a 5 point item will actually take 13 points of time. In one case we had a 13 point item that in retrospect could have been 80 points or more.

There are two options going around in our discussion for how to handle this.

We can accept the extra work in the same work item, and write it off as a mis-estimation. Arguments for this have included:

We plan for "padding" at the end of the sprint to account for this sort of thing.

Always leave the code in better shape than you found it. Don't check in half-assed work.

If we leave refactoring for later, it's hard to schedule and may never get done.

You are in the best mental "context" to handle this work now, since you're waist deep in the code already. Better to get it out of the way now and be more efficient than to lose that context when you come back later.

We draw a line for the current work item, and say that the extra work goes into a separate ticket. Arguments include:

Having a separate ticket allows for a new estimation, so we aren't lying to ourselves about how many points things really are, or having to admit that all of our estimations are terrible.

The sprint "padding" is meant for unexpected technical challenges that are direct barriers to completing the ticket requirements. It is not intended for side items that are just "nice-to-haves".

If you want to schedule refactoring, just put it at the top of the backlog.

There is no way for us to properly account for this stuff in an estimation, since it seems somewhat arbitrary when it comes up. A code reviewer might say "those UI controls (which you actually didn't modify in this work item) are a bit confusing, can you fix that too?" which is like an hour, but they might say "Well if this control now inherits from the same base class as the others, why don't you move all of this (hundreds of lines of) code into the base and rewire all this stuff, the cascading changes, etc.?" And that takes a week.

It "contaminates the crime scene" by adding unrelated work into the ticket, making our original feature point estimates meaningless.

In some cases, the extra work postpones a check-in, causing blocking between devs.

Some of us are now saying that we should decide some cut off, like if the additional stuff is less than 2 FP, it goes in the same ticket, if it's more, make it a new ticket.

Since we're only a few months into using Agile, what's the opinion of all the more seasoned Agile veterans around here on how to handle this?

答:
Agile planning and user stories are focused around providing value and transparency to the project stakeholders and users of the software.  This is a good thing, but it doesn't and should not supersede, include or demote the importance of good architectural guidelines, design stewardship, good development practices and maintaining technical debt.

Agile doesn't do the latter well because it was not intended as an answer to these mostly technical problems and issues.

Knowing that I highly disagree that refactoring tasks, technical debt handling, and design work should account for seperate user stories in a given sprint.  These are merely tasks that a developer might undertake to help meet the user story for that sprint.

Remember that a Task is any unit of assignable work that helps move a given user story to completion within the architectural guidelines and maintaining the good design and devlopment practices of the software as a whole.

This is why the hours estimation should be on tasks and not on user stories.  This is also why some tasks are critical to the completion of multiple user stories.


答:
Red, Green, Refactor. That is the scope of a single work item. Write a failing test suite covering the scope of change, code the minimum required amount to pass your test, then refactor to meet coding standards while still passing the tests. All three of these steps are required; you cannot code the solution until you have defined the problem, if you refactor as you write the line of code you will invariably violate YAGNI, but if you do not come in behind yourself and refactor after passing the tests, by definition you incur technical debt that you will eventually have to repay.

Given this definition, and that it was followed, a 5-pointer that turns out to be a 13-pointer was a mis-estimation. What you would consider refactoring work was probably more like restructuring; you had to reorganize a pretty significant area of the codebase in order for the new functionality to be included in an understandable, maintainable way. That usually indicates a failure of the team to understand the general future path of development, leading to something being implemented very simply in a previous iteration when it would eventually be required to be very SOLID. Better communication between the BAs and PM, who know what's further down in the backlog, and the development team who are generally focused on the current sprint, can mitigate this. Alternately, this story exposed a large amount of technical debt incurred in past development, and it simply caught up with the team. Better code review processes, in addition to better conceptual knowledge of design patterns and of the general future path of the project, can help reduce such occurrences.

One thing to keep in mind is that refactoring is "non-ideal" work. In Agile SCRUM, tasks are estimated in "ideal hours"; that is, the number of hours spent heads-down writing brand-new code that never existed and furthers the feature base of the project. An 8-hour  developer-day might realistically only have 5 ideal hours; sometimes you can count on 6, especially in the "stretch" of a project where the team's really humming along. Refactoring, or going back and making changes that do not affect the functionality of the project but that improve the codebase in other ways, is non-ideal work, as is planning, design, communication, review, breaks, or technical downtime. Other than technical downtime, non-ideal work is important, but does not make progress in the eyes of the product owner.

So, provided that refactoring doesn't double the actual hours spent, a certain amount of refactoring work is to be expected when you estimate in ideal hours. Let's say, because I don't know exactly how your team's point scale is calibrated, that a 5-pointer is equivalent to one ideal developer-week, or about 25 ideal hours. That 5, which turned into a 13 (more than two developer-weeks by the same scale), is cause for some retrospection about what caused the complexity to balloon. Perhaps the codebase didn't need as much refactoring as was actually done, perhaps a large amount of technical debt had piled up unbeknownst to the team that had to be resolved to make the new features work, or perhaps this was an honest mis-estimation of the amount of new work required (perhaps the team thought extending an existing part of the domain would be enough, when in reality several new domain classes and related schema changes were necessary).

In an alternate universe, let's imagine that a 5 as estimated in ideal hours became a 7 (~35 hours) based on actual hours, because you needed 10 hours of additional refactoring to put the new code and some previous bits into a properly-patterned design architecture. In that case, the extra is within the "gap" between ideal and total hours during the number of developer-days the story was supposed to take. So, as a project manager, I'd call a 5 that became a 7 a reasonable estimate and move on.

Title: Handling "related" work within a single agile work item

Body:
I'm on a project team of 4 devs, myself included. We've been having a long discussion on how to handle extra work that comes up in the course of a single work item.

This extra work is usually things that are slightly related to the task, but not always necessary to accomplish the goal of the item (that may be an opinion). Examples include but are not limited to:

refactoring of the code changed by the work item

refactoring code neighboring the code changed by the item

re-architecting the larger code area around the ticket. For example if an item has you changing a single function, you realize the entire class now could be redone to better accommodate this change.

improving the UI on a form you just modified

When this extra work is small we don't mind. The problem is when this extra work causes a substantial extension of the item beyond the original feature point estimation. Sometimes a 5 point item will actually take 13 points of time. In one case we had a 13 point item that in retrospect could have been 80 points or more.

There are two options going around in our discussion for how to handle this.

We can accept the extra work in the same work item, and write it off as a mis-estimation. Arguments for this have included:

We plan for "padding" at the end of the sprint to account for this sort of thing.

Always leave the code in better shape than you found it. Don't check in half-assed work.

If we leave refactoring for later, it's hard to schedule and may never get done.

You are in the best mental "context" to handle this work now, since you're waist deep in the code already. Better to get it out of the way now and be more efficient than to lose that context when you come back later.

We draw a line for the current work item, and say that the extra work goes into a separate ticket. Arguments include:

Having a separate ticket allows for a new estimation, so we aren't lying to ourselves about how many points things really are, or having to admit that all of our estimations are terrible.

The sprint "padding" is meant for unexpected technical challenges that are direct barriers to completing the ticket requirements. It is not intended for side items that are just "nice-to-haves".

If you want to schedule refactoring, just put it at the top of the backlog.

There is no way for us to properly account for this stuff in an estimation, since it seems somewhat arbitrary when it comes up. A code reviewer might say "those UI controls (which you actually didn't modify in this work item) are a bit confusing, can you fix that too?" which is like an hour, but they might say "Well if this control now inherits from the same base class as the others, why don't you move all of this (hundreds of lines of) code into the base and rewire all this stuff, the cascading changes, etc.?" And that takes a week.

It "contaminates the crime scene" by adding unrelated work into the ticket, making our original feature point estimates meaningless.

In some cases, the extra work postpones a check-in, causing blocking between devs.

Some of us are now saying that we should decide some cut off, like if the additional stuff is less than 2 FP, it goes in the same ticket, if it's more, make it a new ticket.

Since we're only a few months into using Agile, what's the opinion of all the more seasoned Agile veterans around here on how to handle this?


答:
Story points are an estimate of the relative complexity of a given user story. It sounds like you're using story points to say this will take X man days/hours. Instead, strive for two goals

Break down stories until they are in a consistent range (3, 5, or 8 points)

Assume that the story includes any refactoring necessary

Over time this will give you a baseline for velocity. Every 5 point story won't take the same amount of time as the others but the average velocity per sprint (how many story points the team can complete) will be consistent.

Worrying about how much time a specific story will take is counter productive. The estimates only average out over consistently sized stories in volume (I.E. one 5 pointer might take a little longer due to refactoring but you pick up the benefit of that effort on a related one).


答:
I think this kind of issue falls on the broad yet uncomfortable boundary between unit testing and acceptance testing.  If you can specify correct behaviour without real data, then go for it.

But a lot of real requirements (or refinements to requirements) often only emerge once real data rear their ugly malformed heads, e.g:

"Oh, you mean that field uses single quotes (except when it uses double quotes)?"

"Oh, you can get negative values there, even though that makes no sense?"

"Oh, you mean that value can exceed Integer.MAX_VALUE? Nobody said..."

and so on...


答: Lose everything you can lose.  name.name.name=value, each on a separate line, is about as simple as you can get.  You don't need the quotes for parsing, you know when true is a boolean and when true is a string, don't make the "dumb human" tell you that.  For strings, if the field shouldn't have leading/trailing blanks, strip them yourself.


答:
There should be a relative cut-off of how much is within the original work item and how much is something else.  User stories are starting points for discussions and thus there may be all kinds of scope elements to nail down during a sprint while working on a story.

There may be times where in a sprint planning a story may get additional criteria added to it in an effort to avoid "scope creep" which can happen where a user wants a new form and then 101 changes to that form which isn't realistic to get done in a 2 week sprint sometimes.

A flip side to keep in mind is how much value is being gained from this extra work.  There may be tons of possible refactorings that could be done but how much benefit is there to anyone for all that work?  This is where there have to be some guidelines to help keep the team working well but not get lost in trying to make the code perfect.


问:
Are there any OS which are simple enough for learning?
I would really like to understand how an operating  system works behind the scenes. However, I think that the kernel of most open-source OSs out there are too complex for learning purposes, even for a full-time programmer to learn. Are there any "simple" OSs made for learning purposes only out there?</p>

答: If you're into the .NET family of technologies, you can check out Singularity. It hasn't been updated since 2008, but can be downloaded in source and ISO form from CodePlex here.</p>


问:
Are there any actual case studies on rewrites of software success/failure rates?
I've seen multiple posts about rewrites of applications being bad, people's experiences about it here on Programmers, and an article I've ready by Joel Spolsky on the subject, but no hard evidence or case studies.  Other than the two examples Joel gave and some other posts here, what do you do with a bad codebase and how do you decide what to do with it based on real studies?

For the case in point, there are two clients I know of that both have old legacy code.  They keep limping along with it because as one of them found out, a rewrite was a disaster, it was expensive and didn't really work to improve the code much.  That customer has some very complicated business logic as the rewriters quickly found out.

In both cases, these are mission critical applications that brings in a lot of revenue for the company.  The one that attempted the rewrite felt that they would hit a brick wall if the legacy software didn't get upgraded at some point in the future.  To me, that kind of risk warrants research and analysis to ensure a successful path.

Have there been actual case studies that have investigated this?  I wouldn't want to attempt a major rewrite without knowing some best practices, pitfalls, and successes based on actual studies.

Aftermath:  okay, after more searching, I did find three interesting articles on case studies:

Rewrite or Reuse.  They did a study on a Cobol app that was converted to Java.

The other was on Software Reuse: Developers Experiences and Perceptions.

Reuse or Rewrite Another study on costs of maintenance versus a rewrite.

I recently found another article on the subject: The Great Rewrite. There the author seems to hit on some of the major issues.  Along with this was the idea of prototyping by using the proposed new technology stack and measuring how quick the devs picked it up.  This was all as a prelude to a rewrite, which I thought was a great idea!

答: I skimmed Working Effectively with Legacy Code by Michael Feathers a while back and found it offered some good insights into the real-world practice of maintaining legacy code, including writing tests (even when you don't know what the code was for) and of course refactoring/rewriting.  It's a bit dated but highly rated on Amazon.


问:
Is the 'C' in MVC really necessary?
I understand the role of the model and view in the Model-View-Controller pattern, but I have a hard time understanding why a controller is necessary.

Let's assume we're creating a chess program using an MVC approach; the game state should be the model, and the GUI should be the view. What exactly is the controller in this case?

Is it just a separate class that has all the functions that will be called when you, say, click on a tile? Why not just perform all the logic on the model in the view itself?

答:
It really comes into play when you are dealing with event handlers, but you still need the controller to handle interactions between the view and the model.  Ideally you don't want the view to know anything about the model.  Think about it, do you want a jsp to make all the database calls directly?  (Unless it's something like a login lookup.)  You want the view to render data and not have any business logic, unless it's view rendering logic, but not business logic perse.

In GWT, you get a cleaner separation with MVP.  There is no business logic whatsoever (if it's done right) in the view.  The presenter acts as a controller and the view has no knowledge of the model.  Model data is simply passed over to the view.

Title: Is the 'C' in MVC really necessary?


答:
Using your example the Controller would be what decided what was a legal move or not. The Controller would let the view know how to arrange the pieces on the board at start up using the information it received from the Model. There are more things that can be handled by the Controller but the key is to think about Business Logic on that layer.

There are times when all the Controller does is pass information back and forth, like a sign up page. Other times the Controller is the difficult part of the development because there are many things that need to be done at that layer like enforcing rules or doing complicated math for example. Don't forget the Controller!

Title: Is the 'C' in MVC really necessary?

Body:
I understand the role of the model and view in the Model-View-Controller pattern, but I have a hard time understanding why a controller is necessary.

Let's assume we're creating a chess program using an MVC approach; the game state should be the model, and the GUI should be the view. What exactly is the controller in this case?

Is it just a separate class that has all the functions that will be called when you, say, click on a tile? Why not just perform all the logic on the model in the view itself?


问:
Does giving a developer a slower development machine result in faster/more efficient code?
Suppose I give my developers a screaming fast machine.  WPF-based VS2010 loads very quickly.  The developer then creates a WPF or WPF/e application that runs fine on his box, but much slower in the real world.

This question has two parts...

1) If I give a developer a slower machine, does that mean that the resulting code may be faster or more efficient?

2) What can I do to give my developers a fast IDE experience, while giving 'typical' runtime experiences?

Update:

For the record, I'm preparing my even-handed response to management. This isn't my idea, and you folks are helping me correct the misguided requests of my client.  Thanks for giving me more ammunition, and references to where and when to approach this.  I've +1'ed valid use cases such as:

- specific server side programming optimizations

- test labs

- the possibly buying a better server instead of top of the line graphics cards

答:
Asking programmers whether programmers should get good hardware is like asking a fat man whether he likes food.  I know this is the subjective exchange, but still ... is the question worth asking us? :P

That said I of course agree with the majority: NO.


问:
Version control and personal configuration file
Our project uses a user-specific configuration file. This file is currently not in version control, since it is different for each user. The problem is, whenever a developer adds a new module that requires configuration, or changes the name of an existing modules, the other developers get errors because their private configuration files are not updated.

To solve the problem, we thought of working with two configuration files: a default/global configuration file that will be in version control and will be updated regularly by each developer that adds a new module, and a private configuration file that will be kept out of version control and will contain only the user-specific changes.

However, this still seems like an ad-hoc solution.

Can you propose a better solution?

What do the professionals do?

答:
Put a version number into the personal configuration file (the version number of the config file format).

Make the code that processes the personal configuration file check the version number, and if it is out-of-date, run through an update procedure. So, basically, anyone who makes a change that will break existing config files needs to bump the version number of the config file format, and write a procedure to update config files of the previous version (renaming sections, etc.) and re-save them.

You'll probably want some process like this for end-users anyway, so you might as well use it to make your developers' lives easier.


答:
We have a somewhat interesting solution, we're primarily PHP developers, so we use Phing which allows you to create automated tasks written in PHP, so instead of doing our normal svn update, we do a "phing update" which calls svn update, and then replaces our configs with the proper variables, for example, a config:

```<code>$db_user = "${test.db_user}";
</code>```

So the configuration files are all versioned with that interesting syntax, and then we generate an adhoc, unversioned config file for my specific instance, which replaces those "variables" with unversioned settings specified in unversioned ini files. This way we can modify any user-specific files and have the changes populate throughout other working copies.

Body:
Our project uses a user-specific configuration file. This file is currently not in version control, since it is different for each user. The problem is, whenever a developer adds a new module that requires configuration, or changes the name of an existing modules, the other developers get errors because their private configuration files are not updated.

To solve the problem, we thought of working with two configuration files: a default/global configuration file that will be in version control and will be updated regularly by each developer that adds a new module, and a private configuration file that will be kept out of version control and will contain only the user-specific changes.

However, this still seems like an ad-hoc solution.

Can you propose a better solution?

What do the professionals do?

Body:
We have a somewhat interesting solution, we're primarily PHP developers, so we use Phing which allows you to create automated tasks written in PHP, so instead of doing our normal svn update, we do a "phing update" which calls svn update, and then replaces our configs with the proper variables, for example, a config:

$db_user = "${test.db_user}";

So the configuration files are all versioned with that interesting syntax, and then we generate an adhoc, unversioned config file for my specific instance, which replaces those "variables" with unversioned settings specified in unversioned ini files. This way we can modify any user-specific files and have the changes populate throughout other working copies.