答:
"Scrum recognizes no titles for Development Team members other than
  Developer, regardless of the work being performed by the person; there
  are no exceptions to this rule;"
  - The Scrum Guide, Ken Schwaber and Jeff Sutherland

So it's pretty clear that in Scrum, you can not have a person designated as team lead by the organization.

If you're not doing Scrum, you're obviously free to do whatever you want.  There is research suggesting that in certain circumstances not designating a team lead has a positive impact on team performance.  In their 1984 seminal paper, "The new new product development game" (Hirotaka Takeuchi and Ikujiro Nonaka, Harvard Business Review):

"This holistic approach has six characteristics: built-in instability,
  self-organizing project teams, overlapping development phases,
  "multilearning," subtle control, and organizational transfer of
  learning. The six pieces fit together like a jigsaw puzzle, forming a
  fast and flexible process for new product development, just as
  important, the new approach can act as a change agent: it is a vehicle
  for introducing creative, market-driven ideas and processes into an
  old, rigid organization."

The body of research on this is huge and this beyond the scope of this answer.

Whether one or more "leaders" emerge in various phases for various tasks is definitely a possibility, this is very different than the organization designating a "team lead".

A while back there was a news story about a motorcyclist trapped under a burning car and a team of by-standers spontaneously assembled to lift the car and rescue him.  If you wish, this is an analogy to the self-organizing team.  The analogy to the "organization designated team-lead" has a less fortunate outcome for the motorcyclist.

Title: Benefits of a leaderless team in Scrum


问:
Should I use automatic properties?
I'm new to C# coming from a Java background. I'm working on a take home assignment for a coding interview. I normally write my code as following(Java):

```<code>public class Test {

   //fields

   private string fieldA;
   private int fieldB;

   public Test () {
      //.....
   }

   public String getFieldA() {
      return fieldA;
   }

   //ETC.
}
</code>```

The point is that I use getters/setters like above. Now, I have a coding assignment to do for a job interview, and using C# I have stumbled across automatic properties. I was initially slightly confused about it but understand what it does now and have used it.

So for fields I would write

```<code>public string fieldA {get; set;}
</code>```

It feels weird declaring fields public like that and doesn't it violate some OOP encapsulation principles ?

My question is, should I just go ahead and use automatic properties to show interviewers that I know what it is? In case I want to prevent setting a field I could just use:

```<code>public string fieldA {get; private set;}
</code>```

But would it appear like I don't follow encapsulation "rules", I obviously wouldn't want to risk that. I could write it out as I do in Java.

In general what is your view on using automatic properties ?

答:
Automatic properties are an idiomatic way of doing getters/setters in C#. If you're heading off to an interview and want to show that you're fluent in C#, by all means, use automatic properties. Especially if you come from a Java background, it should be reassuring to the interviewers if they see you're already a step ahead from writing Java in Visual Studio.

However, you are right in that using public string fieldA {get; set;} blindly is a code smell. It's very tempting and convenient to define a set of properties upfront as public and never get back to review whether they actually should be part of the class interface or not. And you can actually break encapsulation (as in 'information hiding') that way.

So to summarize: do use them, but be careful not to make them into glorified public fields.

ContentLicense: CC BY-SA 3.0

Title: Should I use automatic properties?


问:
Is it okay to make coding style changes on an open source project that doesn't follow best practices?
Recently, I came across a number of open source Ruby (or majority of it was Ruby) projects on GitHub that when checked with a code analyzing tool like Rubocop, create a lot of offenses.

Now, most of these offenses include using double quotation marks instead of single quotes (when not interpolation), not following the 2 spaces per level rule, exceeding the 80 character line length rule, or using { and } for multi-line blocks.

[The] Ruby style guide recommends best practices so that real-world
  Ruby programmers can write code that can be maintained by other
  real-world Ruby programmers. ~ Source: Ruby Style Guide

Although they are small and easy to fix, is it appropriate to change the coding style of an open source project by fixing the offenses and making a Pull Request? I acknowledge that some projects, like Rails, do not accept cosmetic changes and some are just too large to "fix" all at once (Rails for example generates over 80,000 offenses when Rubocop is run - regardless, they have their own small set of coding conventions to follow when contributing). After all, the Ruby Style Guide is there for a reason together with tools like Rubocop.

People appreciate consistency so making these kinds of changes is kind of doing a good thing for the Ruby community in general, right?

[The author(s) of the Ruby Style Guide] didn't come up with all the
  rules out of nowhere - they are mostly based on my extensive career as
  a professional software engineer, feedback and suggestions from
  members of the Ruby community and various highly regarded Ruby
  programming resources, such as "Programming Ruby 1.9" and "The Ruby
  Programming Language". ~ Source: Ruby Style Guide

Isn't not following community coding style conventions and best practices basically encouraging bad practices?

答:
Although they are small and easy to fix, do you think it is okay to change the coding style of an open source project by fixing the offences and making a Pull Request?

In short, no!

Of course, I'm assuming here that these are just matters of style and aren't actual bugs - pull requests for the latter would always be sensible (IMO.) I'm also assuming that you're a stranger to the project and not in contact with the people who maintain it already.

However, amongst any language there's always some people who have their preferences which differ from the style guide, for better or worse, and trying to enforce those style changes on people that you don't know, and a project that you're not part of if nothing else could comes across as a bit rude. After all - what are you achieving (in reality) if the request was accepted? In all likelihood, if the members of one project wanted to change the style to something different, they would have done it already - and all you'd be doing with that request is forcing a style on them that doesn't necessarily work any better for the existing members.

This changes slightly if you're willing to contribute to the project in other ways other than doing style "fixes". I'd say if you want to open a dialogue with the maintainers about how you'd like to work on the project but find a non-standard style difficult, then that's fine. But I really wouldn't just go around blindly creating pull requests for a bunch of projects that only contain style changes!


问:
Fixing a security exploit - but then everyone knows about it
Earlier, I was messaged about a potential security risk in one of my projects.
I checked it and found that it allows for "arbitrary code execution". (Quotes because it is running in a VM, but the damage that can be done is huge nonetheless)

Since it is an open source project, I imagine other people have found it and exploited it already. However, I am reluctant to fix it, because everybody will be able to see the commit and know about the exploit. Since I have no way of contacting the users and no way of forcing an update (updates are manual), I am at a loss at what to do here.

If I let it stay, people are going to exploit it. If I fix it, people are going to exploit it even more.

How can I proceed?

答:
Softwares are not perfect. Bugs are always there, just undiscovered. Even big websites suffer from simple attacks (Youtube script injection, etc).

Here are your scenarios:

Someone already knows about the security risk, and fortunately reported it to you.

It is also totally possible that other people also discovered the security hole and this person might not be friendly enough to report it to you; heck, he might even or already had exploited it.

Also, have you checked which version the security hole appear? It is possible that it's there for a long time already (if it is, see point #2).

TL;DR You're being too irresponsible here and you should fix your program.


答:
It should be up to users to ensure that they're running an up-to-date, secure version of your software - not fixing it in the hope that not quite as many people find out about it is not a good plan, IMHO.

Of course, you should make it as simple for users as possible to ensure they're running an up to date version of the software, so if there's no good way within your application to alert users of a new version or that their current version is insecure, then that's something I'd consider adding as a separate feature. However, the absence of this feature currently cannot be used as an excuse for not fixing major security holes.

Title: Fixing a security exploit - but then everyone knows about it

Body:
Earlier, I was messaged about a potential security risk in one of my projects.
I checked it and found that it allows for "arbitrary code execution". (Quotes because it is running in a VM, but the damage that can be done is huge nonetheless)

Since it is an open source project, I imagine other people have found it and exploited it already. However, I am reluctant to fix it, because everybody will be able to see the commit and know about the exploit. Since I have no way of contacting the users and no way of forcing an update (updates are manual), I am at a loss at what to do here.

If I let it stay, people are going to exploit it. If I fix it, people are going to exploit it even more.

How can I proceed?


问:
Benefits of a leaderless team in Scrum
Scrum advocates assume that a team without a designated team leader (as it is in Scrum) is more effective than a team with a designated leader (as in traditional hierarchy). Although I can understand this point of view, I am not entirely certain that's the case.

In Scrum teams leaders always emerge. Power vacuums get filled. So if the organization already recognizes certain people as talented leaders, why not assign them an official leadership role in the first place?

答:
Yes, in many Scrum teams a leader may emerge. You're assuming from the beginning, management will be able to determine who this is? Some times leaders are perceived to be those who don't get along with the team and are people who will supposedly make the tough decisions because they are not friends with the other team mates.

When you designate a title to a leader, there may be other people on the team who feel they now have to sit back and wait for the "leader" to make all the decisions. This is especially true if individual leaders are singled out and given more compensation, privileges, etc.

If you are so confident a leader will emerge and have a positive impact on the team, what is the point in trying to designate this person? If you try to give them additional rewards, you may undermine the power the team chooses to give them.

Title: Benefits of a leaderless team in Scrum


答:
To offer an alternate opinion here, in many cases, such a change would be welcome.  Open source projects tend to have many authors. There is often no "coding style"; the style is just whatever the person who wrote the code in question happened to use. If one file was written by a different person than another, the style may be different as well. Even in projects where there is a consensus style, unless they check for this style regularly, it often is not used.

A common example of this in my experience is when someone contributes some code via pull request that is of relatively low quality style-wise. However, the code may work. Different people have different views on this. Some people will refuse to merge a pull request unless the style is good. Some people don't care, as long as the code works. Some people prefer to have good style, but they don't want to scare off contributors with a bunch of "fix the whitespace here" comments (I personally always feel a little guilty making these comments, even though I know they are for the better good of the codebase, because it it does feel like it might scare the contributor away).

So don't assume straight out that the style that you see is the style that the project wants.  In fact, that can probably be generalized to contributing to open source in general: don't assume that the code an open source project has is the code that it wants.

You should be aware of some things, though:

Some people are religious about style. If it becomes clear that they don't want to budge, then don't bother.

This is a huge bikeshed issue. Everybody and their brother has an opinion about these things. Getting such a pull request merged can be difficult because of this.

It can also be hard to get such a pull request merged because it will get merge conflicts very quickly; basically whenever any part of the codebase that you modified changes, even if its in trivial ways.

I would stick with the "ask first" approach. If they are open to it, and you are willing to stick with the pull request to completion, then go for it.

Title: Is it okay to make coding style changes on an open source project that doesn't follow best practices?

Body:
Recently, I came across a number of open source Ruby (or majority of it was Ruby) projects on GitHub that when checked with a code analyzing tool like Rubocop, create a lot of offenses.

Now, most of these offenses include using double quotation marks instead of single quotes (when not interpolation), not following the 2 spaces per level rule, exceeding the 80 character line length rule, or using { and } for multi-line blocks.

[The] Ruby style guide recommends best practices so that real-world
  Ruby programmers can write code that can be maintained by other
  real-world Ruby programmers. ~ Source: Ruby Style Guide

Although they are small and easy to fix, is it appropriate to change the coding style of an open source project by fixing the offenses and making a Pull Request? I acknowledge that some projects, like Rails, do not accept cosmetic changes and some are just too large to "fix" all at once (Rails for example generates over 80,000 offenses when Rubocop is run - regardless, they have their own small set of coding conventions to follow when contributing). After all, the Ruby Style Guide is there for a reason together with tools like Rubocop.

People appreciate consistency so making these kinds of changes is kind of doing a good thing for the Ruby community in general, right?

[The author(s) of the Ruby Style Guide] didn't come up with all the
  rules out of nowhere - they are mostly based on my extensive career as
  a professional software engineer, feedback and suggestions from
  members of the Ruby community and various highly regarded Ruby
  programming resources, such as "Programming Ruby 1.9" and "The Ruby
  Programming Language". ~ Source: Ruby Style Guide

Isn't not following community coding style conventions and best practices basically encouraging bad practices?


问:
What's the idea behind defining rectangles with two points?
It's not that this doesn't make sense, but it just works out awkward 99% of the time.

Often in 2D graphics rectangles are initialized, stored and manipulated as a pair of points.  In no particular language,

```<code>class Rect:
   p1, p2: point
</code>```

It makes more sense to define a rectangle as two x values and two y values, like this:

```<code>class Rect
   xleft, xright: int
   ytop, ybottom: int
</code>```

With two points, if at some place in the source code you want to make use of the y value of the top, you'd have to say rect.p1.y  (hmmm, stop and think, is it p1 or p2) but with the four values as plain data members, it's clear and direct:  rect.ytop (no thinking required!)     The use of two points means that in dealing with the vertical, you have to tangle the horizontal; there's an extraneous relation between indepenent elements.

How did this two-point idea come about and why does it persists?  Does it have some benefit over bare x and y coordinates?

ADDED NOTE: This question is in the context of X-Y aligned rectangles, such as in windows managers and GUI toolkits, not in the context of arbitrary shapes in drawing and painting app.

答:
i think it makes more sense for a rectangle to be represented by an x and y extent and a point; you could even make the location point the center of the rectangle so it would be independent of rotation

but it was probably easiest to code it as two points!

ContentLicense: CC BY-SA 2.5


问:
How to ensure method finishes running before being run again
I'm new and I am trying to figure something out. I have a simple program which executes a method either when an event happens or when my timer ticks. Lets just say the method takes 5 seconds to complete. During that 5 seconds an event could happen. What would I use/do to make sure my method isn't called while its already running.

Or is this something I would not have to worry about in a simple program, as it wouldn't run until the method is done anyway ?

A little background and example.
I am using System.Windows.Forms.Timer, I am not using any threads or anything, and I just have a simple windows form application with a timer, a method to do stuff, and two event handlers.

```<code>Program{
  public Program(){
    DoSomething();
    Event.EventHappened += HandleEvent;
  }
  void DoSomething(){
    MyTimerVariable.Stop();
    InitMyTimer();
    //Just do something check network, access db write line, something
    //that in this example takes 5 secs for example purposes
    MyTimerVariable.Start();
  }
  void HandleEvent(){
    DoSomething();
  }
  void InitMyTimer(){
    // Create Timer, and add Timer tick event
  }
  void TimerTickedEvent(){
    DoSomething();
  }
}
</code>```

I left a few things out of that program, but just was trying to show how simple it is. I was just thinking about making it more efficient so that say in the middle of doing "DoSomething()" an event is triggered, I wouldn't want two "DoSomething()"s method running.

答:
As this is using a System.Windows.Forms.Timer instead of System.Threading.Timer, the event will be executed on the UI thread and therefore will not be executed out of sequence.

If you were using threading though, simply creating a private object lockObject = new object(); and locking it in the DoSomething() method, you will similarly ensure that the body of DoSomething does not get executed until it has finished.


问:
In PHP, should I delete objects immediately after use?
I've read in PHP Advanced and Object Oriented Programming by Larry Ullman that it is good programming practice to delete object immediately after use but reason is given nowhere.

I am a student web developer and objects in web applications are deleted automatically as soon as the script finishes. So, there seems no good reason to delete them manually.

So, my question is what are the good reasons to delete unnecessary objects after use other that blindly following a convention?

答:
PHP's GC was hit and miss prior to 5.3 with many arrays and objects becoming unfreeable until the script ended. Because of this, PHP development basically took on an unspoken “who needs GC anyways” attitude because vars were only guaranteed to be freed when the script ended.

Two things are happening which change this:

First, PHP's GC has advanced to where its only unreliable with  arrays that contain copies of other arrays. PHP's GC will be totally functional and reliable once this issue is fixed .

Secondly, PHP's pthread extension is coming along pretty well. It's very likely that PHP will have full thread support within the next couple years, making long running scripts as usefull as many Java appliations.

These two things are likely to change many standards in the way PHP is used. For example, your already starting to see serious efforts to create PHP based network services (such as Ratchet) now that the GC is reliable under most circumstances.

So to make a long story short -  no, your currently not required to unset any form of resources in PHP because they will all be freed when the script ends. However, unsetting objects and other resources will make sure that each unneeded resource is freed before the script ends, potentially freeing up highly contented resources and thus improve performance.

Moreover, the practice of unsetting objects and resources is likely to become the norm in the near future, and likely an absolute requirement in many cases.

Note that many PHP objects/resources don't fall out of scope until the script ends. This means that unset() is the only way to ensure that their ref count is set to 0 in order to become a candidate for freeing by the GC (before the script ends, that is.)


问:
Can I use an LGPL-licenced library in my commercial app?
I want to use an LGPL-licensed library in my app for Microsoft's app marketplace.  Is that OK?</p>

答:
This article may help.

I suspect that because LGPL allows making the source code (of the library that you linked to) available via a download, it must be OK to use an LGPL-licensed lib in your app for Microsoft's marketplace.

Quote from LGPL version 2.1:

If distribution of object code is made by offering access to copy
  from a designated place, then offering equivalent access to copy the
  source code from the same place satisfies the requirement to
  distribute the source code, even though third parties are not
  compelled to copy the source along with the object code.

The only thing that seems to be an issue is the "same place" requirement, which you will not be fulfilling if your app is being distributed via the marketplace.


问:
Is embedded programming closer to electrical engineering or software development?
I am being approached with a job for writing embedded C on micro controllers. At first I would have thought that embedding programming is too low on the software stack for me, but maybe I am thinking about it wrong.

Normally I would have shrugged off an opportunity to write embedded code, as I don't consider myself an electrical engineer. Is this a bad assumption? Am I able to write interesting and useful software for embedded systems, or will I kick myself for dropping too low on the software stack?

I went to school for computer science and really enjoyed writing a compiler, thinking about concurrent algorithms, designing data structures, and developing frameworks. However, I am currently employed as a web developer, which doesn't scream the interesting things I just described. (I currently deal with issues like: "this check box needs to be 4 pixels to the left" and "this date is formatted wrong".)

I appreciate everyone's input. I know I have to make the decision for myself, I just would like some clarification on what it means to be a embedded programmer, and if it fits what I find to be interesting.

答:
I was in a similar situation about 8 years ago. I had at that point 7 years of software development in application and server environments.  My only experience dealing low level with hardware before had been writing in Z80 assembler as a teenager on a ZX spectrum.

It was certainly a challenge.  I found dealing with the chip sets in assembler very enjoyable and I certainly learned a lot about hardware.  A substantial part of my role was in testing the hardware using software, so learning to cope with programming and recognising that your software bug is actually a hardware bug.  Actually sometimes it can take quite a bit of work by software and hardware people to identify if a bug is hardware or software.

One aspect that I failed to deliver on was device driver work.  I never really grasped this, which is one thing that myself and that company director never understood why. It just became an accepted fact.

Becomming familiar with an occiloscope and a soldering ion will be essential. remembering that when a hardware guy says the number 26 he ALWAYS means 0x26 is useful.  Realising that Hardware engineers find dealing with software very frustrating helps, but then, a hardware project that doesn't involve software is called a cable.

I stayed in that role for 4 years and only left because I was poached for a really fantastic opportunity.


问:
When to store Date/DateTime?
I'm working on a social network website and I'm not quite sure when I should store the date/datetime. The service includes some of the following events:

Register/Login

Follow

"Like" (images & comments)

Post a comment

Post an image

In my eyes, I would use DateTime for all of them... Although I'm not sure if that's professional or maybe it's just a waste of space.

When should I store the time of an event? Thanks in advance.

答:
General rule of thumb when talking about your primary data store; tend towards storing more information rather than less.

There are good reasons why you might want to know a date & time for all those events, as others have pointed out. If not now then later.

In all those specific cases you list, I would store a date and time.

And really, adding a date and time field should only have a tiny impact on performance. If your doing an INSERT anyway, what's one extra field? You can start micro-optomising performance later if you need to.

Title: When to store Date/DateTime?


问:
Is reinventing the wheel really all that bad?
Its common knowledge in programming that reinventing the wheel is bad or evil.

But why is that?

I am not suggesting that it's good. I believe it to be wrong. However, I once read an article that said, if someone is doing something wrong (programming wise) explain to them why its wrong, if you can't, then maybe you should be asking yourself if it is really wrong.

That leads me to this question:

If I see someone is clearly reinventing the wheel by building their own method of something that is already built into the language/framework. First, for arguments sake, lets assume that their method is just as efficient as the built in method. Also the developer, aware of the built in method, prefers his own method.

Why should he use the built in one over his own?

答:
As offensive as it may be to some, I've always found this term to be unclever when used by any form of engineer or in reference to a topic of creating or designing things. In fact, I can't help but to see it as disingenuous when considering the pressures to innovate in today's fast paced world. Repeating yourself (or ignoring adequate, pre-existing solutions) is never wise, but really, there's a reason why we're not all still staring at black screens full of green letters.

I understand "If it ain't broke don't fix it", though I guess such a phrase may sound ignorant to some. Yet with the current effort to re-invent the wheel for the needs of space travel, racing, shipping, etc, "don't re-invent the wheel" is pretty ignorant as well, and is nowhere near as clever as it sounds.

My background consists of leading many projects and I have had to work with many interns and other forms of green developers, and I have had to handle many naive questions that some would call 'stupid', and have also had to divert people from chasing rabbit wholes outside of the scope of their tasks. However, I would never discourage innovation or creativity, and have seen great things come from 're-inventing the wheel'.

My actual answer to the question: There are only two situations that make re-inventing the wheel is a bad thing:

If it is not really needed

If it is the other guy doing it when you could have

Edit:
I can see by the drive-by down votes that I must have offended some. The one thing that I would like to add is that this phrase has always been a major pet-peeve of mine. I understand that my two cents might sound rather trollish, but I have no intentions to troll, cause fires, or offend.


答:
You need to find out if the maintainers consider these coding style violations a defect, or if the project has a different standard for coding style.

If it has a different standard, you could offer to help document or formalize it. Then it might turn out there are some violations of that style, and you could fix those.


问:
Learning Scala, feeling discouraged
I'm coming from a Java background and trying to learn Scala. At the moment I'm feeling pretty overwhelmed, there seems to be so much more to learn with Scala, so many different ways of doing the same thing.

I was wondering if anyone has any advice on where to start, and how long it took them to feel reasonably competent in the language?

Even little things like for loop comprehensions seem really powerful but it's just another piece of syntax you need to remember!

答:
I've been where you are, and almost gave up a few times. While by no mean an expert Scala developer, I feel I now have a firm grasp on the language - certainly enough for it to have thoroughly poisoned my relationship with Java.

The first thing I did was spend a few weeks playing around, reading various blogs and introductions to the language. That was a mistake, I didn't learn (or at least understand) much that was useful, and felt entirely out of my depths.

The second thing was to spend some time working out problem that were technically simple but forced me to explore specific aspects of the Scala syntax on my own:

99 Scala Problems

Project Euler

While this did not turn me into an expert overnight, it gave me enough familiarity with the language that it didn't feel quite that impossible anymore.

With that boost in confidence, I finally did what I should have started with: get Programming in Scala by Martin Odersky, and attempt to read an entire chapter every couple of days. It's a well written and comprehensive book, and if you already have a sound programming background, should not prove too daunting. There's no need to make your first read too painful: skip the parts marked as optional, make sure you understand the concepts but don't get bogged down in the details (in particular, I feel that the chapters on collections are overkill and can be skimmed). Knowing that a concept exists and where to read a comprehensive explanation of how it works is a tremendous help.

An alternative to reading the book is attending the Coursera class - it's much less comprehensive, but covers most of the crucial points and is broken down into manageable, logical units. On the other hand, I don't know whether it's possible to access the lessons once the class is complete, and I also found that I was much less engaged while listening to someone (even someone as obviously smart and knowledgeable as Martin Ordesky) than when reading a book.

Another issue with Scala is the amount of vocabulary you've got to ingest - by-name parameters? for-comprehension? closure? If you feel overwhelmed by this, I found that a good mixture of the Scala Glossary and targeted stack overflow searches helped me out a lot (seek out answers by Daniel Sobral and Travis Brown). In fact, I went so far as to create an Anki deck with the glossary, and feel it was a big help.

Finally, this is probably obvious, but code, code, code. Find a side project you can work on, even if it's something trivial. What I did was write a very simple Amazon crawler that would send me a tweet whenever an author I was interested in released a new book. It took longer than it probably should have, but this is when I fell in love with the language.

If you get that far, you'll probably need no further help, but a good suggestion, once you've come to grasp with the language, is to delve deeper in the underlying concepts. You're familiar with OOP, try to read up on functional programming - I can say with absolute certainty that it will blow your mind. Functional Programming in Scala should be released soon(ish), but the early access edition is already excellent. Another answer suggests Functional Programming for Java Developers, which I'm not familiar with but am inclined to believe is good (when has an O'Reilly book not been worth at least skimming?).

I hope this didn't get too long winded and obvious, and honestly wish you the best. Scala has its faults, but it's a wonderful language and will take your brain in directions you never knew existed. And I'll be looking for your "Learning Haskell, feeling discouraged" in a year :)

Title: Learning Scala, feeling discouraged


问:
Security through obscurity and storing unencrypted passwords
What exactly does "Security through obscurity" means in the context of stroing unencrypted passwords?

I'm using a small program (I won't name it, to not enlarge enough large shame on its author) that uses my Google account for some tasks. I've noticed, that it stores my password in plain-text unencrypted file. Just a string, clearly seen to everyone, that can drag&drop it to Notepad or use F3 in Total Commander.

I have risen a ticket asking program author to fix this ASAP. I haven't got any reply yet, but my issue got one comment, that includes only above mentioned link to Wikipedia's "Security through obscurity" page.

How should I understand this comment? Is it pro or con my issue? At first I thought, that it supports my statement of fixing this ASAP. But then I found a Eric Raymond's Fetchmail example (in "The Cathedral and the Bazaar"), who refused to implement config file encryption (passwords are stored in config file for Fetchmail), claiming that it is up to the user to assure security by not letting anyone "from the outside" access that configuration file.

This statement (or refusal) is often brought as example of Security through obscurity. And looking from this point of view, I'm completely wrong and that program author is right. He do not have to implement encryption of file with my password, it can remain there, stored unencrypted and it is I, who is responsible for assuring security by not giving anyone access to this file or by deleting it each time I stop using that soft.

(another question is, how can I achieve this on system as unsecure as Windows itself?)

These seems to be in a complete opposition, to what I've been told and learnt for years, so I would like to ask more experienced developers, who is right here and how exactly I should understand "StO"?

答:
The problem is that data encryption is unnecessary, when data and key are kept on the same system.

When the application would encrypt your password, it would have to include the decryption algorithm and the decryption key. Anyone with access to your data could just extract algorithm and key from the program itself and use it to decrypt the password file.

That's why encrypting your password would just be security through obscurity. When I get 10 minutes alone with your computer, I just need to look at the file with the encryption key in addition to the file which stores your password to obtain your login information.

The only way where it makes sense to encrypt local data is when you use a passphrase as decryption key which is not stored and must be entered by the user manually everytime the encrypted data is accessed. But when the only data which is protected by that scheme is another password, you could just have the user enter that password instead.


问:
Tracking correct order details in commerce database when modifying 'products'
I am implementing an ecommerce database. This is slightly different than most as the 'products' that are for sale are for services provided. For example a user (vendor) of the system may define a service to 'wash your car'.

```<code>Table: Services
--------------------------------------------------
| ID (pk) |      Title       |    Description    |
--------------------------------------------------
     1       Home Services      wash your car
</code>```

I have omitted a number of columns, but should still be able to make my point.

A client can then purchase the Home Services. So I have an orders table with a FK to the the Services table. Standard ecommerce stuff.

The issue I have is what happens if the vendor decides to slightly update the description or even the title? This may have the affect of changing the entire service. For a normal commerce site, you'd add a discrete product. If this product changed, you would create a new product and discontinue the old one. With the packages, we need to allow updates as the description is the product and the sales pitch (maybe thats my problem though - maybe separate the two?) so I have to allow changes.

For example they could change the description to 'wash your car and clean your house'.

The obvious issue with this is that existing orders will still reference the same PK on the services table but the service is now different.

I'm wondering what the best solution is to allow changes to be added, but maintain the correct data for existing orders. One solution I thought of is to not update the row, but add a new one and a version number

```<code>Table: Services
------------------------------------------------------------------------------
| ID (pk) |      Title       |            Description             |  Version |
------------------------------------------------------------------------------
     1       Home Services     wash your car                           1
     2       Home Services     wash your car and clear your house      2
</code>```

We can now access the correct information for previous orders, and existing customers can purchase the new home services option.

This feels like a sensible way to do it, but want to see if anyone knew of any other solutions?

One other solution is to allow updates on the services table, but then for each order, save the description and title (similar to how sometimes in commerce schemas the final price is saved directly to the order). Issue I have with this is a lot of duplicate data being saved.

答:
What you want to do is "freeze" the information at the time of an order.

When a client makes an order you just make a copy of the description, price, product etc. in the order record.

For instance, the price of a product can change a lot. You don't want a new product record for every price change. So you "freeze" the price in the order record.

Once an order is made, a lot of the information references to the order and not to the products anymore. Things like price, description, vendor, vat, but also shipping adress get stored with the order.
It now has become historical data.
That way, even when things change, like price, decription or adress you can always see what the actual order was.
A change of shipping adress for a client for instance, doesn't change where an order was shipped originally.

See it as a contract: you take your product catalog, get the product details and client details and put them in the contract, the actual product and the name and adress of the client.
You don't put in the contract: client 12345 has ordered 3 of product 7 on page 25 of the catalogue version B from may 2013 with 10% sunday sales discount.


问:
Why are the Java 8 java.time classes missing a getMillis() method?
Java 8 has a whole new library for dates and times in the package java.time which is very welcome thing to anyone who has had to use JodaTime before or hassle with making it's own date processing helper methods. Many classes in this package represent timestamps and have helper methods like getHour() to get hours from timestamp, getMinute() to get minutes from timestamp, getNano() to get nanos from timestamp etc...

I noticed that they don't have a method called getMillis() to get the millis of the time stamp. Instead one would have to call method get(ChronoField.MILLI_OF_SECOND). To me it seems like an inconsistency in the library. Does anyone know why such a method is missing, or as Java 8 is still in development is there a possibility that it will be added later?

https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html

The classes defined here represent the principal date-time concepts, including instants, durations, dates, times, time-zones and periods. They are based on the ISO calendar system, which is the de facto world calendar following the proleptic Gregorian rules. All the classes are immutable and thread-safe.

Each date time instance is composed of fields that are conveniently made available by the APIs. For lower level access to the fields refer to the java.time.temporal package. Each class includes support for printing and parsing all manner of dates and times. Refer to the java.time.format package for customization options...

Example of this kind of class:

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html

A date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.

LocalDateTime is an immutable date-time object that represents a date-time, often viewed as year-month-day-hour-minute-second. Other date and time fields, such as day-of-year, day-of-week and week-of-year, can also be accessed. Time is represented to nanosecond precision. For example, the value "2nd October 2007 at 13:45.30.123456789" can be stored in a LocalDateTime...

答:
JSR-310 is based on nanoseconds, not milliseconds. As such, the minimal set of sensible methods are based on hour, minutes, second and nanosecond. The decision to have a nanosecond base was one of the original decisions of the project, and one that I strongly believe to be correct.

Adding a method for millis would overlap that of nanosecond is a non-obvious way. Users would have to think about whether the nano field was nano-of-second or nano-of-milli for example. Adding a confusing additional method is not desirable, so the method was omitted. As pointed out, the alternative get(MILLI_OF_SECOND) is available.

FWIW, I would oppose adding the getMillis() method in the future.

ContentLicense: CC BY-SA 4.0


问:
DDD: Domain Model Factory Design
I am trying to understand how and where to implement domain model factories.  I have included my Company aggregate as a demo of how I have done it.

I have included my design decisions at the end - I would appreciate any comments, suggestions, critique on those points.

The Company domain model:

```<code>public class Company : DomainEntity, IAggregateRoot
{
    private string name;
    public string Name
    {
        get
        {
            return name;
        }
        private set
        {
            if (String.IsNullOrWhiteSpace(value))
            {
                throw new ArgumentOutOfRangeException("Company name cannot be an empty value");
            }

            name = value;
        }
    }

    internal Company(int id, string name)
    {
        Name = name;
    }
}
</code>```

The CompanyFactory domain factory:

This class is used to ensure that business rules and invariants are not violated when creating new instances of domain models. It would reside in the domain layer.

```<code>public class CompanyFactory
{
    protected IIdentityFactory<int> IdentityFactory { get; set; }

    public CompanyFactory(IIdentityFactory<int> identityFactory)
    {
        IdentityFactory = identityFactory;
    }

    public Company CreateNew(string name)
    {
        var id = IdentityFactory.GenerateIdentity();

        return new Company(id, name);
    }

    public Company CreateExisting(int id, string name)
    {
        return new Company(id, name);
    }
}
</code>```

The CompanyMapper entity mapper:

This class is used to map between rich domain models and Entity Framework data entities.  It would reside in infrastructure layers.

```<code>public class CompanyMapper : IEntityMapper<Company, CompanyTable>
{
    private CompanyFactory factory;

    public CompanyMapper(CompanyFactory companyFactory)
    {
        factory = companyFactory;
    }

    public Company MapFrom(CompanyTable dataEntity)
    {
        return DomainEntityFactory.CreateExisting(dataEntity.Id, dataEntity.Name);
    }

    public CompanyTable MapFrom(Company domainEntity)
    {
        return new CompanyTable()
        {
            Id = domainEntity.Id,
            Name = domainEntity.Name
        };
    }
}
</code>```

The Company constructor is declared as internal.

Reason: Only the factory should call this constructor.  internal ensures that no other layers can instantiate it (layers are separated by VS projects).

The CompanyFactory.CreateNew(string name) method would be used when creating a new company in the system.

Reason: Since it would not have been persisted yet, an new unique identity will need to be generated for it (using the IIdentityFactory).

The CompanyFactory.CreateExisting(int id, string name) method will be used by the CompanyRepository when retrieving items from the database.

Reason: The model would already have identity, so this would need to be supplied to the factory.

The CompanyMapper.MapFrom(CompanyTable dataEntity) will be used by the CompanyRepository when retrieving data from persistence.

Reason: Here Entity Framework data entities need to be mapped into domain models.  The CompanyFactory will be used to create the domain model to ensure that business rules are satisfied.

The CompanyMapper.MapFrom(Company domainEntity) will be used by the CompanyRepository when adding or updating models to persistence.

Reason: Domain models need to be mapped straight onto data entity properties so that Entity Framework can recognise what changes to make in the database.

Thanks

答:
There is one thing I don't like about your design. And that is fact you are going to have 3 additional classes for each aggregate root (Factory, Mapper, Repository) with semi-duplicate code in form of reading and setting properties everywhere. This will be problematic as you add and remove properties, because forgetting to change a single method might cause an error. And the more complex the domain entity is, the more of this duplicate code is. I don't want to see CompanyFactory.CreateExisting when company has 10 properties and 2 entities in aggregate.

Second thing I might complain about is the IdentityFactory. In DDD, the identity should either be related to domain, in which case you set it to some calculated value. Or it is transparent, in which case you can have DB take care of it. Adding some kind of factory for identity is IMO overenginering.

I also don't like the mapping. While I agree it might not be possible to use EntityFramework directly, you could at least try. EF is getting better with POCO lately and you might be surprised how powerfull it is. But it still isn't NHibernate. If you really want to create separate models, try thinking about using some auto-mapping library.

It is nice you are demoing the design on one simple class, but try also demoing or at least imagining how the design will work with dozens of aggregates that have lots of properties and entities. Also, write a code that will use this design. You might realize that while the design might look good from the inside, it is cumbersome to use from the outside. Also, no one here is going to tell you if the design is appropriate for your team and your domain.

Title: DDD: Domain Model Factory Design


问:
Why is it hard to make a Java program 'appear native'?
Most Java applications don't look the same as C/C++ applications. Swing might have been designed on purpose to have a distincitve look, but based on what I've read, SWT for example tried to 'look native', and doesn't completley succeed.

My question is:

Why is it hard for the developers of the Java language to design a GUI system that copies exactly the look of native GUIs? What's different in native GUIs? Isn't it only a matter of designing buttons that look like 'native' buttons? Or does it go deeper than that?

答:
Isn't it only a matter of designing buttons that look like 'native' buttons?

Well - sort of, for buttons. But this might be harder than you imagine. These days the graphics used to represent GUI components aren't as simple as random bitmaps that are stretched (since these don't scale very well at all) - they're often vector based graphics with a lot of corner cases programmed into them (so when the button reaches the edge of the screen it may look slightly different, for instance.) And of course, you'll need different graphics when a button is clicked. For copyright reasons, developers often can't just use these existing graphics outright, so they have to be recreated - and while they do a good job for the most part, inevitably some things get missed given the huge array of graphical components out there. This is much less severe than it used to be - these days if I set the default platform look and feel in Swing, I notice very little that looks odd.

I'm saying all the above based on Swing, which is of course a lightweight, non-native GUI toolkit. You specifically mention SWT not looking native, which is a bit odd, because SWT is native. It's a toolkit that uses JNI underneath to call native components - so if something doesn't look right there, it's not going to be because of the look and feel.


答:
Yes, it does go deeper.

Building a button which looks like a Windows or OS X button is easy, when you are building only this button. But the button must "behave" like the original ones, which might not be easy: maybe there is more space in one version available, but not in the other, maybe the color is more fitting for your design in the Windows version, etc.

This is excarberated when you have a whole GUI: an OS X program presents its content differently than a Windows program. This is next to impossible to capture in one GUI - you would need two GUIs, but not many applications make so much fuss. Instead they are aiming for "looks ok on most systems" - this still looks somewhat alien, but is usable and much easier to develop.

Title: Why is it hard to make a Java program 'appear native'?

Body:
Most Java applications don't look the same as C/C++ applications. Swing might have been designed on purpose to have a distincitve look, but based on what I've read, SWT for example tried to 'look native', and doesn't completley succeed.

My question is:

Why is it hard for the developers of the Java language to design a GUI system that copies exactly the look of native GUIs? What's different in native GUIs? Isn't it only a matter of designing buttons that look like 'native' buttons? Or does it go deeper than that?


答:
There are literally half a dozen of toolkits that could be considered “native” on some system. Some of these have rather unique concepts or capabilities, and replicating them in a cross-platform toolkit is tedious. The look & feel  of an application is not only determined by a “skin”, but also on the layout and how it behaves. Some considerations:

In a dialog, on which side does the “OK” button belong – on the left or on the right? Fair enough, let's build a separate dialog for each system.

How do we mark the default button on a screen? Color tinting, bold font, enlarging the button? Fair enough, let's put that in a stylesheet.

On Windows, the “Ribbon” concept is rather native. How would this be translated to Mac, where the Ribbon isn't common? Fair enough, let's forget pixel-exact layout and provide a different toolbar implementation for each system.

Is the menu bar part of the window (Windows, optionally KDE), or does it sit at the top of the screen (Mac, Unity)? Fair enough, let's write a different implementation for each system, as we've already thrown away pixel-exact layout

How are the fonts rendered? As crisp as possible, or smooth and antialiased? And what font should be used? Note that different fonts have different metrics, so the same paragraph rendered to the same width may have a different number of lines depending on the font.

Is the background of a window a single color, an image, or a gradient? Let's just put that into a stylesheet as well.

How do scrollbars look? Where are the buttons – if they have any? How wide are they, or are they only revealed when the pointer moves into a certain region?

How do we incorporate other color schemes?

What is expected to be draggable? Where are context menus expected?

These issues can't be solved through a simple stylesheet when they touch on the behavior or general layout of the application. The only real solution is to re-write the application for each system (thus ignoring Java's cross-platform benefits). The only realistic solution is to forget about pixel-exact layout, and to write to a common interface which abstracts over over system-specific toolkits. The solution taken by Swing is to emulate various systems, which fails spectacularly.

And then there is cross-platform consistency, the idea that your app can look exactly the same on all systems (often chosen by games, where this increases immersion). On desktop applications, this is just annoying and breaks user expectations.


问:
How to handle affinities?
Assume we have an abstract class having several concrete classes which
interfaces publish an information under several equivalent forms, with
the difference that each class has a preferred form which can be
consulted at no cost while consulting the others might require a
time-consuming computation.  How to implement a strategy selecting an
algorithm based on this “affinity”of one class for one information
form?

Example

The original example is a complicated example of a very specialised
field, so I will do my best to figure out an example that will be
familiar to most programmers.

Assume we have an abstract class representing I/O devices which has
two concrete subclasses, one for char-based devices and one for
block-based devices.  Each class provides block-based access and
cahr-based access, but each class has an affinity to one of these
methods: block-based access is preferred for block-based devices,
etc.  Say, we want to implement a copy procedure, so that, if the source
and the target devices are block-based then the copy is performed
block-per-block, in all other cases, a char-by-char approach is
preferred.

Discussion

Assume now we have not only I/O devices but several abstract classes
offers access to several logically equivalent methods, but whose
implementation differ greatly in perormance, thus displaying a greater
affinity to one method over the others.

We want to implement a strategy working on an aggregate of such
classes and selecting an algorithm taking the affinities of these
classes into account.

Because of the combinatoric complexity brought by the aggregate, the
visitor-pattern does not seem useful here.

Question

How can each concrete class expose its affinity for one or the other
access method in a way that is useful to a strategy component picking
up an algorithm suited to these affinities?  The combinatorics yield a
large number of combinations of affinities and the strategy only needs
to consider a few “lucky cases”and use a generic algorithm to handle
the vast majority of combinations.

答:
Assuming the high-cost method has the same signature as the low-cost method. It should be possible to introduce a "preferedMethod()" which also has the before mentioned signature and is in every class implemented to delegate to the low-cost method.</p>

```<code>void lowCostMethod( args ...){
    //Implementation
}

void highCostMethod( args ...){
    //Implementation
}

void preferedMethod( args ...){
   lowCostMethod(args)
}
</code>```

Title: How to handle affinities?

Body:
Assuming the high-cost method has the same signature as the low-cost method. It should be possible to introduce a "preferedMethod()" which also has the before mentioned signature and is in every class implemented to delegate to the low-cost method.

void lowCostMethod( args ...){
    //Implementation
}

void highCostMethod( args ...){
    //Implementation
}

void preferedMethod( args ...){
   lowCostMethod(args)
}


答:
I don't think that there exists a pattern for this specific implementation.  The closest you can get would be Factory pattern with some modifications.  The factory pattern because the caller shouldn't really know how it is implemented for the most part, just that it gets done.

However, you're still left with the problem of selecting the proper algorithm.  If you have few algorithms, then simply call the algorithm by name as @Lessat suggested in his answer.  Otherwise, the way I would go about it is I would have all these algorithm classes derive from an interface which in addition to "execute" to launch the algorithm, a method called "isSupported" which takes as a parameter an enumerator defined in your Factory.  This enumerator would list prerequisites which must be present or must hold true.  For example, if you wanted the process to run asynchronously, then Asynchronous would be one such enumerator.  Each implementation would then return true only if it is supported.

I would create another method "ratePriority" which takes as a parameter an enumerator defined in your factory which determines algorithm priority and returns a number from 0 to 10 (10 being best).  By priority, I mean, if we were talking about sorting a list, priorities for me would be, WorksBestAlreadySorted or WorksBestRandom or RequiresLittleMemory, etc.

When you call the factory, you pass an array of supporting features and an array of priorities.  Your factory would then, one by one, eliminate all algorithms which do not support all your supporting features.  Assuming you have more than one algorithm left, you then determine the best one by calculating each algorithm's score by calling ratePriority on each priority and you select the highest.

In this way, the caller only has to worry about supporting features and priorities of each algorithm and not on how the actual implementation is performed.  Rather than return an instance to the implementation, you could directly call execute on that implementation and return the results to that call.

I hope that helps!

Edit:  If parameters to these algorithms change, you could accept Key-Value pair mappings that would then be passed onto the algorithm itself.  The factory wouldn't have to worry about how to call it.  The caller still would, however, I don't think there is a way of getting around this if those parameters are what is required.

Title: How to handle affinities?

Body:
Assume we have an abstract class having several concrete classes which
interfaces publish an information under several equivalent forms, with
the difference that each class has a preferred form which can be
consulted at no cost while consulting the others might require a
time-consuming computation.  How to implement a strategy selecting an
algorithm based on this “affinity”of one class for one information
form?

Example

The original example is a complicated example of a very specialised
field, so I will do my best to figure out an example that will be
familiar to most programmers.

Assume we have an abstract class representing I/O devices which has
two concrete subclasses, one for char-based devices and one for
block-based devices.  Each class provides block-based access and
cahr-based access, but each class has an affinity to one of these
methods: block-based access is preferred for block-based devices,
etc.  Say, we want to implement a copy procedure, so that, if the source
and the target devices are block-based then the copy is performed
block-per-block, in all other cases, a char-by-char approach is
preferred.

Discussion

Assume now we have not only I/O devices but several abstract classes
offers access to several logically equivalent methods, but whose
implementation differ greatly in perormance, thus displaying a greater
affinity to one method over the others.

We want to implement a strategy working on an aggregate of such
classes and selecting an algorithm taking the affinities of these
classes into account.

Because of the combinatoric complexity brought by the aggregate, the
visitor-pattern does not seem useful here.

Question

How can each concrete class expose its affinity for one or the other
access method in a way that is useful to a strategy component picking
up an algorithm suited to these affinities?  The combinatorics yield a
large number of combinations of affinities and the strategy only needs
to consider a few “lucky cases”and use a generic algorithm to handle
the vast majority of combinations.


问:
Scrum: Writing the time it took to complete a task
In my organization when we move a task to the "Done" column we write the number of hours it took to complete the task. It can be useful when during retrospective the team tries to understand why certain stories took longer to implement than anticipated. However it is also burdensome and developers feel somewhat micromanaged or stressed when they have to do this.

What do you do in your teams? What do you recommend?

答:
I would recommend not recording elapsed time then!

Firstly, are these metrics actually used, or do they generally say "roughly what the estimate said"? If estimates are all over the place then you have other problems. If estimates are 90% accurate then you will know which problem tasks caused problems and there's no need to record which ones they were - the person working on it will quite happily shout "don't give me another f*** task like that f*** one again" and you can discuss why it was so problematical :)

Overall throughput of work is what matters in Agile systems, if the team is getting the job done, who gives a fig how long each bit took?! (ok, I know, some anally-retentive managerial types do. They need to loosen up and focus on the bigger picture, not micromanage each task).

Don't forget - ultimately tasks are an artificial way of splitting up work into easy-to-accomplish bites. The estimate that gets assigned to them is equally artificial. What matters is what you end up achieving.


问:
How to convince/prove my manager that a rewriting is needed rather than a refactoring
My manager wants me to refactor a gigantic amount of terribly-coupled, macroed, full of private namespace methods, hierarchy-perverted (even 10+ levels of inheritance) code which hasn't been (indeed) designed with a "whole-vision" concept.

I tried to explain to him that this code needs to be rewritten, not just refactored but he didn't listen and stated explicitly that I need to refactor it.. somehow.

I could dive into all the "dealing with legacy code" books but I think nothing useful would come out.

How can I convince him that a rewriting, instead of a refactoring, is actually needed?

答:
He's probably right.

If the codebase is so monstrous, so gigantically complicated, so difficult to understand... what makes you think you can write something that does the same thing correctly?

Generally a big refactoring is the best place to start - start ripping bits out and combining them into reusable chunks; tidy up the code so its easier to view; flatten the inheritance hierarchy and remove the dangling edge-cases; combine the namespaces; unroll the macros; whatever it takes to turn the big mess into a reasonably understandable system.

You have to understand it before you can rewrite it - otherwise you will just end up with a different mess.


答:
I never ask teams to record actual time taken for tasks. My experience teaches me that it serves no useful purpose. But I'm also aware that it's not a Scrum Master's decision to make.

Scrum Teams are self-organizing and it's for them to decide whether recording actual task time is useful. If they decide to do so, I might point out the issues I think could arise but mostly, I let them try it for themselves and retrospect on the outcome.

Title: Scrum: Writing the time it took to complete a task

Body:
In my organization when we move a task to the "Done" column we write the number of hours it took to complete the task. It can be useful when during retrospective the team tries to understand why certain stories took longer to implement than anticipated. However it is also burdensome and developers feel somewhat micromanaged or stressed when they have to do this.

What do you do in your teams? What do you recommend?


问:
How can Lisp produce an iterative process from a recursive procedure?
I am starting to learn Lisp, using the SICP book. The authors mention that a procedure (i.e. function) can be recursive or iterative. Additionally, the process those procedures will generate will also be recursive or iterative, and that, surprisingly, a recursive procedure can sometimes generate an iterative process.

The example given is the factorial procedure, which is a recursive procedure, but which generates an iterative process:

```<code>(define factorial n)
    (iter 1 1 n))

(define (iter product counter max-count)
    (if (> counter max-count)
        product
        (iter (* counter product)
              (+ counter 1)
              max-count)))
</code>```

And here's a quotation from the book:

One reason that the distinction between process and procedure may be
  confusing is that most implementations of common languages (including
  Ada, Pascal, and C) are designed in such a way that the interpretation
  of any recursive procedure consumes an amount of memory that grows
  with the number of procedure calls, even when the process described
  is, in principle, iterative. The implementation of Scheme we shall
  consider does not share this defect. It will execute an iterative
  process in constant space, even if the iterative process is described
  by a recursive procedure.

Question: I understood the principles involved (i.e. the what) but I still don't understand how the Lisp interpreter/compiler will generate an iterative process from a recursive function, being able to calculate it using constant space, and why most other languages are not able to do it.

答:
Essentially with tail recursion, the problem with recursion in general is that you each function call gets it's own stack frame. In this stack frame you store all your local variables and whatnot.

So if you run a function like

```<code>  int fact(int n){
      if(n == 0)
           return 1;
      return n * fact(n-1);
  }
</code>```

fact is called n times, allocating n stackframes. If n is big, that's a lot of memory.

There is hope however, when our function is structured in the form

```<code> int f(int x){
     ...
     return g(foo); // Function call is in the final position
 }
</code>```

Then we can throw away f's stack frame before entering g, this means that we won't allocate too many frames as long as we're using simple tail calls. It will actually compile to each function having it's own label and jmping to the tail called function, very fast.

All Schemes is tail recursive, as are most functional languages' implementations like those of SML, OCaml, Haskell, Scala, and (kind of) Clojure. This means that whenever you have a function call as the absolute last thing in your function, it won't allocate a new stack frame. Using this, we can write a do-while loop as follows in Scheme

```<code>  (define (do-while pred body)
     (body)                   ;; Execute the body
     (if (pred)               ;; Check the predicate
         (do-while pred body) ;; Tail call
         '()))                ;; Exit
</code>```

And this runs in exactly the same amount of space as the equivalent imperative code would :) Pretty nifty.

Note, Tail Call Optimization /= Tail Recursion

A common misconception is that TCO is strictly confined to the case where a function tail calls itself. This is a specific subset of TCO and what most JVM languages provide. Languages like Scheme which aren't restricted by the JVM's limitations are properly TCO'd making it possible to say write a DFA which will run in constant memory by tail calling between states.

Body:
Essentially with tail recursion, the problem with recursion in general is that you each function call gets it's own stack frame. In this stack frame you store all your local variables and whatnot.

So if you run a function like

  int fact(int n){
      if(n == 0)
           return 1;
      return n * fact(n-1);
  }

fact is called n times, allocating n stackframes. If n is big, that's a lot of memory.

There is hope however, when our function is structured in the form

 int f(int x){
     ...
     return g(foo); // Function call is in the final position
 }

Then we can throw away f's stack frame before entering g, this means that we won't allocate too many frames as long as we're using simple tail calls. It will actually compile to each function having it's own label and jmping to the tail called function, very fast.

All Schemes is tail recursive, as are most functional languages' implementations like those of SML, OCaml, Haskell, Scala, and (kind of) Clojure. This means that whenever you have a function call as the absolute last thing in your function, it won't allocate a new stack frame. Using this, we can write a do-while loop as follows in Scheme

  (define (do-while pred body)
     (body)                   ;; Execute the body
     (if (pred)               ;; Check the predicate
         (do-while pred body) ;; Tail call
         '()))                ;; Exit

And this runs in exactly the same amount of space as the equivalent imperative code would :) Pretty nifty.

Note, Tail Call Optimization /= Tail Recursion

A common misconception is that TCO is strictly confined to the case where a function tail calls itself. This is a specific subset of TCO and what most JVM languages provide. Languages like Scheme which aren't restricted by the JVM's limitations are properly TCO'd making it possible to say write a DFA which will run in constant memory by tail calling between states.


答:
This kind of problem is a familiar one, but I don't think there is a single canonical solution. The two that come immediately to mind are negotiation and so-called inversion of control.

Negotiation is commonly used to choose between protocols. Your 56K modem or fax does it. So does your mail server. Essentially one service has to say to the other: "I can do A,B,C, which would you prefer?" The second service makes the choice and it is binding. In more complex scenarios there may be multiple rounds of negotiation. So it relies on a specific negotiation side channel.

There are few useful references on protocol negotiating. Try this: https://en.wikipedia.org/wiki/SPNEGO for some ideas.

IOC in this context means there is an arbitrator with a set of rules, which will call a factory on each service to return a specific concrete implementation and will then connect them to each other. This is a widely used solution in many contexts.

This is a well known technique, widely written about. This is a good starting point: https://en.wikipedia.org/wiki/Inversion_of_control.

Title: How to handle affinities?


问:
Is it bad practice to follow up a call to a terminating function with exit()?
I'm currently working on a php frontend. Specifically, the authentication process.

I'll spare everyone the exact details of the decision tree, but it includes a lot of checks and about half of them branch to a call to do_logon() which generates the login page and then calls exit to stop processing further.

Currently, I follow up each of those calls with another exit statement in the branch itself:

```<code>if($db->authenticate($user,$password)) {
     ... continue processing checks...
} else {
    $message='Invalid password';
    do_logon($message,true);
    exit;
}
</code>```

Despite knowing that that final exit will never actually be called because do_logon ends on an exit.

My reasoning is that while I know that do_logon will always exit, other people who may wind up working on this codebase may not, or if I'm asked to maintain this code half a decade from now I might not remember, so adding the superfluous exit statement doesn't alter the code flow but does make it clear that processing will stop there, but am I overlooking something?

答:
The general answer to your question is that you should Die() and not exit.

You are describing a place in your code that should never be reached and (regardless of what anyone thinks of this particular example) these situations do arise. The proper thing to do is to implement a Die() function (if you don't already have one) and call it wherever something "can't happen". I guarantee before too long one of these will be hit, regardless of "it can't happen"!

The Die() function should log the call, including where it was called from, and then terminate. Often it can be derived from an Assert() function, which tests that some condition is true and dies if not. If you're not familiar with these concepts, or are not already using them, a bit of reading might be in order.


问:
In iOS, y-axis starts from the top and grows downward. It is the opposite to macOS. What is the rationale and technical advantage behind this change?
In iOS, the coordinate (0, 0) means the top left corner. In macOS it is the bottom left corner.

What is the Apple's rationale or technical advantage of this coordinate system?

答:
The answer is: because they can. Whenever there are 2 or more ways to do something there will be 2 or more ways that it is done.

Seriously though, Y up the page is the maths convention and Y down the page is the natural direction for filling an empty page. Both are arguable.

Other examples include: coords as (X,Y) or (Y,X); rotation origin to right (maths) or up (as in a clock); matrices in row major or column major order. The list is endless.


答:
No, you should not exit or die. You can either have the do_logon end the script internally (bad practice) or allow the script to finish on it's own.

If you place this code in a function, then you can just return from the function. Allowing all the calls to propagate until the script is finished.

```<code>function auth() {
    if(!$db->authenticate($user,$password)) {
        $message='Invalid password';
        do_logon($message,true);
        return;
    }
    ... continue processing checks...
}
</code>```

If your current design restricts this kind of behavior, then it's preferred to throw an exception.

```<code>    if(!$db->authenticate($user,$password)) {
        $message='Invalid password';
        do_logon($message,true);
        throw new Exception("Unexpected return from do_logon");
    }
    ... continue processing checks...
</code>```

You can catch the exception higher up the call chain, or allow the server to give a 500 response.

Why throw an exception?

Something has gone unexpectedly wrong inside do_logon. Maybe the code changed or there is a use case you didn't account for. Either way, the current request to the server is no longer valid. If something higher up can catch the exception and handle it, then fine otherwise stop the current request.

Title: Is it bad practice to follow up a call to a terminating function with exit()?

Body:
I'm currently working on a php frontend. Specifically, the authentication process.

I'll spare everyone the exact details of the decision tree, but it includes a lot of checks and about half of them branch to a call to do_logon() which generates the login page and then calls exit to stop processing further.

Currently, I follow up each of those calls with another exit statement in the branch itself:

```<code>if($db->authenticate($user,$password)) {
     ... continue processing checks...
} else {
    $message='Invalid password';
    do_logon($message,true);
    exit;
}
</code>```

Despite knowing that that final exit will never actually be called because do_logon ends on an exit.

My reasoning is that while I know that do_logon will always exit, other people who may wind up working on this codebase may not, or if I'm asked to maintain this code half a decade from now I might not remember, so adding the superfluous exit statement doesn't alter the code flow but does make it clear that processing will stop there, but am I overlooking something?

Body:
No, you should not exit or die. You can either have the do_logon end the script internally (bad practice) or allow the script to finish on it's own.

If you place this code in a function, then you can just return from the function. Allowing all the calls to propagate until the script is finished.

function auth() {
    if(!$db->authenticate($user,$password)) {
        $message='Invalid password';
        do_logon($message,true);
        return;
    }
    ... continue processing checks...
}

If your current design restricts this kind of behavior, then it's preferred to throw an exception.

    if(!$db->authenticate($user,$password)) {
        $message='Invalid password';
        do_logon($message,true);
        throw new Exception("Unexpected return from do_logon");
    }
    ... continue processing checks...

You can catch the exception higher up the call chain, or allow the server to give a 500 response.

Why throw an exception?

Something has gone unexpectedly wrong inside do_logon. Maybe the code changed or there is a use case you didn't account for. Either way, the current request to the server is no longer valid. If something higher up can catch the exception and handle it, then fine otherwise stop the current request.


问:
Does late have any meaning in Agile methodologies?
This came out of some of the answers and comments on another question (this one).

I've worked primarily with waterfall projects and while I've worked on ad-hoc projects that have taken on agile behaviours and have read a fair bit about agile, I'd say I've never worked on a "proper" agile project.

My question is does the concept of "late" have any meaning in agile, if so then what?

My reasoning is that with agile you have no upfront plan and you have no detailed requirements at the outset.  You may have a high level goal in mind and a notional date attached to it but both may change (potentially massively) and neither are certain.

So if you don't know exactly what you're going to deliver basically until you deliver it and the user accepts it, and if you don't have a schedule beyond the next sprint, how could you ever be late in any way that actually has meaning?

(Obviously I understand that a sprint might overrun but I'm talking about beyond that.)

Just to be clear I'm (personally) happy with the assumption that on time waterfall projects (even relatively large ones) are possible based on the fact I've seen them and been involved in them - they're not easy or common even but they are possible.

This isn't about knocking agile, it's about me understanding it.  I've always seen the benefit of agile as nothing to do with deadlines or budgets (or rather only indirectly), it's to do with scope - agile delivers closer to what is really important rather than what the project team think is important before they've seen anything.

答:
Anytime you make a commitment of some kind, you run the risk of being late. That applies to agile as well.

But we know you cannot predict the future, and we know the customer will constantly change his mind, and we agree that is a good thing. If we accept that, we must also accept that all commitments are pretty much always wrong, which, in turn, makes the question about lateness easy to answer: We are always wrong (to early or to late). It's all a matter of guesses, no matter how well polished. Toss a coin.

This is something we as developers simply must accept, and from that standpoint try to find another way to work, a way in which the lateness issue is made much less important. A change of perspective. I think the way to do that is focusing on delivering working software as soon a possible, with an option of quitting when the customer is satisfied.

And that is what agile is all about. A clever way to managing
  this uncomfortable notion that lateness is
  a fact and we simply have to deal with it the best we can.

For example, you are late when you fail to deliver on the commitments you did at the beginning of the current iteration. This is expected and you should learn from this and adapt your process so you are less likely to fail in the next iteration. The best way to handle this is to keep iterations as small as possible.

For multi iteration planning, aka release planning, you use the velocity calculated from the completed iterations and extrapolate the data to a predict a future release date. I recommend James Shores' article or my own (shorter) for more details about this. Note that it's never a solid commitment though and more of a "we are 80% certain that we will complete the next features by that date". This can (sort of) result in you being late, but the commitment is only a probability, not a fact.

Now par this with the basic promise of agile that you should always ready to release working software, feature complete or not. This gives the customer the freedom to stop development when he thinks the system is good enough, which can happen a lot sooner than anticipated. It also encourages taking the project in new directions based on real feedback from the latest iteration.

The above points should be more then enough for any customer to be in full control of the development, and I hope that answers the question about lateness in agile methods.


问:
Is it okay to make coding style changes on an open source project that doesn't follow best practices?
Recently, I came across a number of open source Ruby (or majority of it was Ruby) projects on GitHub that when checked with a code analyzing tool like Rubocop, create a lot of offenses.

Now, most of these offenses include using double quotation marks instead of single quotes (when not interpolation), not following the 2 spaces per level rule, exceeding the 80 character line length rule, or using { and } for multi-line blocks.

[The] Ruby style guide recommends best practices so that real-world
  Ruby programmers can write code that can be maintained by other
  real-world Ruby programmers. ~ Source: Ruby Style Guide

Although they are small and easy to fix, is it appropriate to change the coding style of an open source project by fixing the offenses and making a Pull Request? I acknowledge that some projects, like Rails, do not accept cosmetic changes and some are just too large to "fix" all at once (Rails for example generates over 80,000 offenses when Rubocop is run - regardless, they have their own small set of coding conventions to follow when contributing). After all, the Ruby Style Guide is there for a reason together with tools like Rubocop.

People appreciate consistency so making these kinds of changes is kind of doing a good thing for the Ruby community in general, right?

[The author(s) of the Ruby Style Guide] didn't come up with all the
  rules out of nowhere - they are mostly based on my extensive career as
  a professional software engineer, feedback and suggestions from
  members of the Ruby community and various highly regarded Ruby
  programming resources, such as "Programming Ruby 1.9" and "The Ruby
  Programming Language". ~ Source: Ruby Style Guide

Isn't not following community coding style conventions and best practices basically encouraging bad practices?

答:
ANY change is liable to introduce bugs, even changing typographical formating of the code.

Therefore no changes should be performed on the code unless there's a valid business case, and "but the code doesn't look nice" or "the code doesn't follow the coding standards" is not a valid business case. The risk is simply too great.

Now, if you're making major changes to a source file anyway, pulling the entire file in line with the standards might be acceptable, but most likely you will be making small changes in which case it's almost universally preferable to keep your own changes in line with the existing code even though that existing code does not follow the coding standards.

Heck, the code could well be the result of a code generator and at times be regenerated. Code generators are notorious for producing ugly code...


问:
Algorithm/research on detecting language of text
I am interested in finding an approach that will detect what language a string of text is. As Google translate does.</p>

答:
The tools use a mix of routines to determine the language of a string of text.

In some cases the existence of certain specific characters increase the likelihood of  specific languages: letters with accents and umlauts. In some cases it is specific words such as those language specific definite articles: der, die, das in German. In other cases it is the character types used that identifies the language family: Chinese, Arabic...

There are a number of open source and paid libraries available. They are based on ingesting a large corpus of example documents to help with the probabilities. Some allow you to add additional rules if you have specific cases that cause problems.

The longer the string you want to identify the better the results. A one word string may fit into multiple languages. A paragraph will get better results. Of course if the document has multiple languages in the different sections you can get unexpected results.


答:
What you think is native is actually native apps doing their own thing while toolkits like SWT follow the published standards for the UI of that OS. The problem is that no one builds apps following those standards so when you fire up a Java app. It appears to not be native. As an example, almost all of Microsoft's projects (Office, Outlook, etc.) cannot be reproduced visually using Windows standard controls.

It's going to get even worse as both Microsoft and Apple add dynamic UI features to their OS platforms. Allowing developers to skin/style their apps much the same way web designs create styles for websites.

Java on the Android platform is following this path. Making the UI elements for Android defined in XML with skinnable styles.

Java has never been very popular as a desktop platform. As a result these changes in the industry are not propagating down to the desktop runtimes. There just aren't enough developers willing to spend time to fix the issue.


答:
It's not hard to make a button that looks like an OSX button, or a Windows button, or that of any other toolkit. But the UI guidelines for most environments are not as simple as the basics of "this is what a button looks like." There are many subtler differences, from the spacing between UI elements to the order in which certain well-known actions should appear in a list to the exact position of the Preferences/Options dialog in the menu system. One can automate the most common cases for very simple user interfaces, but many if not most UI tasks require a much finer touch.

SWT tried to automate this to some degree, and once again, it gets it right for simple UI tasks. But there is no one-size-fits-all solution, and so when UIs get more complex, the basic methods it uses begin to fall apart. It is generally possible to bring it back into line with painstaking manual UI work, but this is not something that most programmers are able or willing to do for all platforms.

Swing's approach to this was simply to eschew native toolkits whenever possible. It's not native, and it doesn't try to be: instead, it tries to create something that will look (almost) the same no matter where it is run. Rather than trying (futilely) to please everyone, it tried to please itself, and while it succeeded as far as that goes, one can question how effective the result is to the wider community of users.


答:
There is no concept of "time taken" in Scrum, simply because all activities in Scrum are time boxed (stories are time boxed within an iteration).

There is a concept of "time left" but that is only useful for building a burn down chart of the current sprint -- it is not an indication of work done by any means (time left can go up, down or stay the same even if people are working on a task).

In other words: the time it takes to do something is not an issue that is relevant in Scrum. Velocity (points per sprint) is interesting instead, but the aim is never to increase it. The aim is to make the team move at a predictable rate.


答:
A simple approach could be to use word lists (hash-maps) of the most common words for every language you want to support.

When you parse the text, you take each word and check if it can be found in one of these lists. The word-list with the most hits is very likely the one of the language the text is written in. (check them all for every word - some words appear in more than one language, sometimes meaning something completely different).

The shorter the texts you want to analyze, the longer the word-lists will have to be to reliably identify the language.

Title: Algorithm/research on detecting language of text

Body: I am interested in finding an approach that will detect what language a string of text is. As Google translate does.</p>


答:
It’s all due to history.

Sun wished all Java software to work the same on all machines.

For software to “appear native” it has to work the same as other software on the given OS.

Sun did everything in their power to make it hard to write Java software that integrated in with an OS, as any integration with an OS would make the software work differently on each OS.

These days very few Java programmers care about anything other than web server based software.

Sun killed Java on the desktop by shafting all programmers that used the Microsoft java based systems, hence making any programmer that choose Java in the early days look bad.

Anyone writing desktop software that care about “appear native” learned a long time ago not to use Java and has their views reinforced every time they use any Oracle software.

Therefore these days there is no demand for “appear native” on desktop software from Java programmers.


问:
What's the idea behind defining rectangles with two points?
It's not that this doesn't make sense, but it just works out awkward 99% of the time.

Often in 2D graphics rectangles are initialized, stored and manipulated as a pair of points.  In no particular language,

```<code>class Rect:
   p1, p2: point
</code>```

It makes more sense to define a rectangle as two x values and two y values, like this:

```<code>class Rect
   xleft, xright: int
   ytop, ybottom: int
</code>```

With two points, if at some place in the source code you want to make use of the y value of the top, you'd have to say rect.p1.y  (hmmm, stop and think, is it p1 or p2) but with the four values as plain data members, it's clear and direct:  rect.ytop (no thinking required!)     The use of two points means that in dealing with the vertical, you have to tangle the horizontal; there's an extraneous relation between indepenent elements.

How did this two-point idea come about and why does it persists?  Does it have some benefit over bare x and y coordinates?

ADDED NOTE: This question is in the context of X-Y aligned rectangles, such as in windows managers and GUI toolkits, not in the context of arbitrary shapes in drawing and painting app.

答:
As @Steven says, I think it should be in terms of one (x,y) point, and a (w,h) size vector. That's because it's easy to fall into an ambiguity. Suppose you have the following filled-in rectangle starting at point (0,0).

```<code>  012
0 XXX
1 XXX
2 XXX
</code>```

Clearly it's width,height are (3,3), but what is it's second point?
Is it (2,2) or (3,3)?

This ambiguity can cause all kinds of problems.

I learned the hard way years ago that it's better to think of graphic coordinates as the lines between the pixels, not as the lines the pixels are on.
That way there's no ambiguity.

Body:
As @Steven says, I think it should be in terms of one (x,y) point, and a (w,h) size vector. That's because it's easy to fall into an ambiguity. Suppose you have the following filled-in rectangle starting at point (0,0).

  012
0 XXX
1 XXX
2 XXX

Clearly it's width,height are (3,3), but what is it's second point?
Is it (2,2) or (3,3)?

This ambiguity can cause all kinds of problems.

I learned the hard way years ago that it's better to think of graphic coordinates as the lines between the pixels, not as the lines the pixels are on.
That way there's no ambiguity.


问:
Where to show copyright messages?
In my Android application, I am using a couple of open source libraries. The only requirement these libraries have is that I must show their respective copyright notices in my application. I am trying to understand where would one typically display third-party copyrights. I could probably create a menu item "About" and display an about dialog box that has all the copyrights listed. However, I would appreciate your feedback on what the standard practice is.</p>

答:
Android shows copyright in Settings -> About device -> Legal Information.
I think it is good practice.
If you have settings in your app - put copyright there, otherwise use just menu item.</p>

OwnerDisplayName: Peter

Title: Where to show copyright messages?

OwnerDisplayName: Ervin Martirosyan


答:
The most common locations are:

In Settings/Preferences, you can include an "Open Source Licenses" entry and the user can see this

On an About page, you can include an Open Source Licenses link, either on the page or in the Action Bar

If you have neither of these two options available to you, then an entry in the overflow menu is appropriate

A good place to look for examples is the Google applications. Gmail has Settings -> About, and then an Open Source Licenses link. Play Music has Settings -> Open Source Licenses in a "Developer" section (this also includes the build number).

If you're looking for an easy way to show the messages, I've got some sample code that reproduces the Gmail/Play Music experience of a dialog box and loads the licenses from an HTML file. All you have to do is include 3 files - the DialogFragment, the licenses_fragment.xml layout file and licenses.html.

Title: Where to show copyright messages?

Body: In my Android application, I am using a couple of open source libraries. The only requirement these libraries have is that I must show their respective copyright notices in my application. I am trying to understand where would one typically display third-party copyrights. I could probably create a menu item "About" and display an about dialog box that has all the copyrights listed. However, I would appreciate your feedback on what the standard practice is.</p>

OwnerDisplayName: Adam S


答:
The first challenge in identifying the language is to narrow it down to something that one can handle.  Each language has its own letter frequency list.

```
English: etao insr hldc umfp gwyb vkxj qz
French:  esai tnru lodc mpév qfbg hjàx èyêz çôùâ ûîœw kïëü æñ
German:  enis ratd hulc gmob wfkz vüpä ßjöy qx
Spanish: eaos rnid lctu mpbg yívq óhfz jéáñ xúüw k
```

(specifics from http://www.letterfrequency.org and wikipedia: Letter frequency)

Using this information one can identify if certain characters appear and rapidly cut down the choices.  If a ß, well, thats likely to be German.  There are certain characters that only appear in certain languages.  This, however is not foolproof as one could be talking about classic heavy metal bands that have like to use characters outside of the normal for that language - Mötley Crüe (see Metal umlaut) or use of borrowed words (some people write résumé in English).

This is where the multiple steps are used:

Validate likely languages through character set

Compare letter frequency to languages

Compare specific words to a known dictionary for the language

In comparing letter frequency analysis, one should maintain both an accented and unaccented set for situations where someone writes the language with unaccented latin characters rather than making full use of the character set.

The combination of this information is then sent through statistical processes to identify the appropriate guess of the language (and yes, I am completely glossing over this section because my statistical math is weak and it would go quite beyond the basics).  More about this in Language identification: Statistical approaches - this link on Wikipedia goes to a number of articles and libraries for such.

Body:
The first challenge in identifying the language is to narrow it down to something that one can handle.  Each language has its own letter frequency list.

English: etao insr hldc umfp gwyb vkxj qz
French:  esai tnru lodc mpév qfbg hjàx èyêz çôùâ ûîœw kïëü æñ
German:  enis ratd hulc gmob wfkz vüpä ßjöy qx
Spanish: eaos rnid lctu mpbg yívq óhfz jéáñ xúüw k

(specifics from http://www.letterfrequency.org and wikipedia: Letter frequency)

Using this information one can identify if certain characters appear and rapidly cut down the choices.  If a ß, well, thats likely to be German.  There are certain characters that only appear in certain languages.  This, however is not foolproof as one could be talking about classic heavy metal bands that have like to use characters outside of the normal for that language - Mötley Crüe (see Metal umlaut) or use of borrowed words (some people write résumé in English).

This is where the multiple steps are used:

Validate likely languages through character set

Compare letter frequency to languages

Compare specific words to a known dictionary for the language

In comparing letter frequency analysis, one should maintain both an accented and unaccented set for situations where someone writes the language with unaccented latin characters rather than making full use of the character set.

The combination of this information is then sent through statistical processes to identify the appropriate guess of the language (and yes, I am completely glossing over this section because my statistical math is weak and it would go quite beyond the basics).  More about this in Language identification: Statistical approaches - this link on Wikipedia goes to a number of articles and libraries for such.


答:
I agree with the other answers which say that tracking time per task may not be useful for Scrum purposes. (Velocity is better tracked at an iteration time-frame, not per story or task.)

However, I also believe that software development requires discipline. There are things that professional programmers should do even if they feel like a pain, such as entering useful commit messages into SCM, sharing data regularly, code reviews, etc. Some job requirements just aren't fun, but they've got to get done.

So I'd say you go back to your team (or management) and find out if tracking that time is actually beneficial. If it isn't, get rid of it. But if it is, the team needs to buckle down and do it. Just try to figure out a way to make it as simple as possible. (On my team, we use JIRA to indicate what each team member is working on, so it's fairly simple to log time as we go.)