答:
What you have experienced is quite normal. The estimations when you are a junior developer (based on your text I assume this) differs largely from a good and experienced senior developer. A senior developer will find pitfalls already in architecture phase of a project and takes this into accountance in his estimation.

Next point you mentioned is that a project with a new technology will take more time than a project where there technology is already known.

Next is refactoring. As Karl already mentioned refactoring is needed. For your question about how often must be refactored: Refactor the application when it is needed (the code smells). I personally refactor about one third (more or less) of the time. And I do this immediately if it is needed.

I hope that this insights help you (at least with your next project).

Title: systems/software engineering design process

Body:
I just developed my first non-trivial android app. It was a complete nightmare. I came up with an idea, build the app, changed my idea, and implemented a lot of input from others on new features. All in all my app took 10 times longer than I think that it should have, it is almost impossible to look the source code and tell what's going on with the classes, and may or may not have unused methods that I'll never be able to find...

So I would like an opinion from those of you with experience on how to plan out my designs for the future. I created a flow chart (pencil drawn) of a plan:

I would like constructive criticism.


问:
How are blocking calls implemented?
This may be a very simple question. I'm curious how blocking calls are implemented. Specifically, how do they block? Is this just thread.sleep?</p>

答:
Specifically, I was implementing a socket class in C# and one of the
.Net socket methods blocks until data is received. I was just curious
how that works.

There are several ways to implement a blocking call.  The obvious way to do it is to return when the work is done See Robert Harvey's Answer.

In the case where there is no work to be done (e.g., waiting for a signal or for input), there are several choices:

Spinlock.  Basically, code like while(signal not found){}.  Spinlocks have almost no overhead and return faster than other methods, but burn CPU until they return.  They are useful if the signal you are waiting for is going to return fast or if giving up a timeslice is to be avoided, but are generally a bad idea in high-level code.

Locks, Mutexes, etc.  In C#, these are accessed with things like lock(obj){} (cause other threads to block) and ManualResetEvent (block until another thread signals).  Generally, there are implemented at the kernel or hardware level.  E.g., C# lock is implemented on x86 machines using the assembly lock cmpxchg assembly instruction (see Junfeng Zhang's blog).

ContentLicense: CC BY-SA 3.0

Title: How are blocking calls implemented?

ContentLicense: CC BY-SA 4.0


问:
What reasons are there to reduce the max-age of a logo to just 8 days?
Most websites set max-age=31536000 (1 year) on the Cache-control headers of static assets such as logo images. Examples:

YouTube

Yahoo

Twitter

BBC

But there is a notable exception: Google's logo has max-age=691200 (8 days).

I've checked the headers on the Google logo in the past, and it definitely used to be 1 year. (Also, it used to be part of a sprite, and now it is a standalone logo image, but that's probably another question...)

What could be valid technical reasons why they would want to reduce its cache lifetime to just 8 days? Google's homepage is one of the most carefully optimised pages in the world, so I imagine there's a good reason.

Edit:

Please make sure you understand these points before answering:

Nobody uses short max-age lifetimes to allow modifying a static asset in future. When you modify it, you just serve it at a different URL. So no, it's nothing to do with Google doodles. Think about it: even if Google didn't understand this basic trick of HTTP, 8 days still wouldn't be appropriate, as only those users who don't have the original logo cached would see the doodle on doodle-day – and then that group of users would go on seeing the doodle for the following 8 days after Google changed it back :)

Web servers do not worry about "'filling up' the caches of clients (or proxies). The client manages this by itself – when it hits its own storage limit, it just starts dropping the lowest priority items to make space for new items. The priority score is based on the question "How likely am I to benefit from having cached this URL?", which is nothing to do with what max-age value the server sent when the URL was originally requested; it's a heuristic based on the 'frecency' of requests for that URL. The max-age simply lets the server set a cut-off point – the time at which the client is supposed to discard the item regardless of how often it's being re-used. It would be very nice and trusting of a downstream client/proxy to rely on origin servers 'holding back' from filling up their caches, but I don't think we live in that world ;)

答:
Setting the max-age to 8 days instead of 1 year gives Google better control over the way it presents itself to the world. You're right that they can simply use a different URL for temporary changes like the Google doodle, but if they think they might want to change the way their real corporate logo appears, it makes sense to use a shorter expiration time for two reasons:

Any references to their logo on any of their existing pages will change automatically -- no need to modify them to use a different URL.

The countless third party web pages that load Google's logo will display the new version automatically after 8 days or less.

Furthermore, longer expiration times provide diminishing returns. With no caching, a typical user might load Google's logo a thousand or more times each year. An 8 day expiration cuts that down to 46 times a year. A 1 year expiration further reduces that to potentially as little as 1 time each year. It seems like the largest benefit, by far, is due to the fact that the image is cached at all -- caching for just 1 day provides a huge benefit, and caching for 8 days extends that somewhat.

The image above is only 7007 bytes in size. Loading that every 8 days means that you're loading 312 kilobytes of their logo over the course of a year. That's really not a lot as a percentage of all the data you load from Google, and the good folks at Google have apparently made a decision that the flexibility they gain from the 8 day expiration is more important than reducing that number further. If they thought otherwise, you can bet they'd use a longer expiration time.

I don't work at Google, and even if I did I probably wouldn't be in a position to know their reasoning for certain, so the above is somewhat speculative. The real answer could be something as simple as: it seemed like a good idea at the time. Nevertheless, there's obviously a tradeoff between minimizing traffic and creative control, and I think we can tell from the expiration time that Google uses where they wanted to draw that line.

Also, I think it's worth noting that Google's isn't just any logo: it's the main feature on their most important web page, and it's presentation is something that they're known to be very careful about. The other sites that you mention (BBC, YouTube, Twitter, and Yahoo) all include their logo on their main page, but in each case the logo is smaller and a much less important element of the page than Google's is. Google has also made a number of changes to its logo over the years (no, I'm not talking about doodles), and there's no reason to think that they won't do it again.


问:
Best setup/workflow for distributed team to integrated DSVC with fragmented huge .NET site?
So we have a team with 2 developers one manager. The dev server sits in a home office and the live server sits in a rack somewhere handled by the larger part of my company. We have freedom to do as we please but I want to incorporate Kiln DSVC and FogBugz for us with some standard procedures to make sense of our decisions/designs/goals.

Our main product is web-based training through our .NET site with many videos etc, and we also do mobile apps for multiple platforms. Our code-base is a 15 yr old fragmented mess. The approach has been rogue .asp/.aspx pages with some class management implemented in the last 6 years. We still mix our html/vb/js all on the same file when we add a feature/page to our site. We do not separate the business logic from the rest of the code.

Wiring anything up in VS for Intelli-sense  or testing or any other benefit is more frustrating than it is worth, because of having to manually rejigger everything back to one file.

How do other teams approach this?

I noticed when I did wire everything up for VS it wants to make a class for all functions. Do people normally compile DLLs for page-specific functions that won't be reusable?

What approaches make sense for getting our practices under control while still being able to fix old anti-patterns and outdated code and still moving towards a logical structure for future devs to build on?

答:
It seems that the dvcs is the smallest part of the problem. I'm not sure if you're saying you're not on source control. If not, that's the first step and Kiln/Mercurial is an excellent choice.

Regarding how to move your code to a managed approach is to step back from your code base and to analyze, refactor and group common sections of code into logical sections. Determine which design pattern(s) will best fit what you're trying to achieve. Keep in mind a few ideas when designing your new solution. Particularly DRY and loose coupling. Consider brushing up on SOLID.  Unit tests would come in very handy here but my guess is you don't have any. I would suggest writing down logic on how you expect the site to work in specific scenarios, particular the key sections of the site. This way, as you move to the next step, you're not breaking logic.

Secondly, implement these changes. Many teams structure their code base in a solution with multiple projects. Generally, we use a classic approach where a solution will consist of 3 projects (UI, Business Logic, Data Access). Work to create an abstraction between each layer, particularly between the business logic and data access. Each layer should know very little about the other.

Thirdly, add unit tests to your project. Specifically, unit test key elements of your business logic to confirm everything works as expected. Generally, this is done first. However, since this is a Brownfield project, this is the only approach we have.

Once done, you'll find adding changes to the site are manageable and predictable.


问:
How can I pull data from PeopleSoft on demand?
I work in IT at a university and I'm working with about 5 different departments to develop a new process for students to apply to a specific school within the university (not the university as a whole).  We're using a  web-based college application vendor and adding the applicant questions for the school itself to the main university application.  Currently the main application feeds into PeopleSoft.  The IT staff here is building a new table to hold just our school's applicant data.  I want to be able to access that data from PeopleSoft for use in external applications, but our IT staff doesn't really seem to understand what I'm requesting, as they simply tell me I can have access to the PS query tools.  The problem is, I don't want to run just ad hoc queries, I want to be able to connect from outside PeopleSoft and show current data within the external app.

I am unable to find documentation or get a clear answer to my question.  Does PeopleSoft support access via a web services API or anything similar, and does that sound like the right direction for me to take?

答:
All that is needed to query the PeopleSoft database is to install the PeopleTools 2-tier client (aka the development tools) on a PC.  The client will install an ODBC driver from which you can then create a DSN. Your application can then communicate with PeopleSoft through the DSN connection.  Technically you don't need the development tools (and the IT staff probably doens't want to give you the dev tools), but that's ok, all you really need is the ODBC driver.  You will also need to work with the IT staff (in particular the DBA) to set up a user account in the database granting you the necessary permissions to the tables that must be queried.  And finally ... you will need to have an understanding of the database schema so you may build your query statements.  PeopleSoft has thousands! of tables and thousands! of views.  Your query will most certainly involve more than just the one table that the IT staff is creating for you.

Not for the faint of heart, but the full PeopleTools 8.52 documentation can be found on Oracle's web site:  http://docs.oracle.com/cd/E25741_01/psft/html/docset.html


问:
What is the best way to compose an object with components across two assemblies?
In my project, I have a collection of classes. These classes for the most part contain data which is updated infrequently or not at all - that is they don't really do much - their purpose is to be passed around consumer objects that do do things, seperating data from functionality.

I would like to continue this model, by allowing the user to treat them as such - i.e. they can be serialised/deserialised with no special code, can easily be used to compose larger classes, subclassed, etc.

The catch is, as many control things like the GPU, they aren't really decoupled or stateless at all, because for every one there are a whole load of resources that need to be created and disposed of during the life of the application - but the user doesn't need to worry about that.

I would like to know the preferred way to attach all the information to the simple object in a way that is safe, maintains the illusion of statelessness, but is also clear to anyone else looking at the code what is going on (also, the objects are defined in different assemblies).

Q. Why not just put A in B and pass around Object B?

A. Because the user creates Object A, and works with Object A only, and shouldn't need to know Object B exists at all.

Q. Why not use factories and create Object C?

A. Because then Assembly A can't contain classes composed of a whole load of Object-A-like-objects (because the factory would be defined in Assembly B so they wouldn't be able to be instantiated).

Q. Then how is Object B created?

A. Object B is created and populated on demand, when Object A is passed to a method that needs it.

Note - I know this problem isn't 'hard' and there are many ways to do it (at the moment I have an abstract member added to all of them which is casted in the consumer and it works OK), I just want some new ideas/opinions on what is the best way - what would you like to see if you inherited the code?

答:
Simple Composition.

Have NeatObject and HardwareResources be composed within a BuiltNeatObject or something. One part comes from serialized resources, the other is spawned at runtime by the consumer and they live together (ideally in a read-only/immutable state), even if they're consumed independently.

A Factory might be useful to hide 'how' the two parts are aggregated, but then again it might limit flexibility in the future. I'll leave that to you since you know the problem best.


问:
Is the output of Eclipse's incremental java compiler used in production? Or is it simply to support Eclipse's features?
I'm new to Java and Eclipse. One of my most recent discoveries was how Eclipse comes shipped with its own java compiler (ejc) for doing incremental builds. Eclipse seems to by default output incrementally built class files to the projRoot/bin folder.

I've noticed too that many projects come with ant files to build the project that uses the java compiler built into the system for doing the production builds.

Coming from a Windows/Visual Studio world where Visual Studio is invoking the compiler for both production and debugging, I'm used to the IDE having a more intimate relationship with the command-line compiler. I'm used to the project being the make file. So my mental model is a little off.

Is whats produced by Eclipse ever used in production? Or is it typically only used to support Eclipse's features (ie its intellisense/incremental building/etc)? Is it typical that for the final "release" build of a project, that ant, maven, or another tool is used to do the full build from the command line?

Mostly I'm looking for the general convention in the Eclipse/Java community. I realize that there may be some outliers out there who DO use ecj in production, but is this generally frowned upon? Or is this normal/accepted practice?

答:
I've never seen the eclipse compiler's output being used for production in any professional or open source project. It probably would work just fine, but it's just not what you do.

Part of the reason is probably that eclipse is not quite as dominant as Visual Studio, another that build tools like Ant and Maven have always existed separate from the IDE, and there is a strong expectation to use them for build automation.


问:
What should be allowed inside getters and setters?
I got into an interesting internet argument about getter and setter methods and encapsulation. Someone said that all they should do is an assignment (setters) or a variable access (getters) to keep them "pure" and ensure encapsulation.

Am I right that this would completely defeat the purpose of having getters and setters in the first place and validation and other logic (without strange side-effects of course) should be allowed?

When should validation happen?

When setting the value, inside the setter (to protect the object from ever entering an invalid state - my opinion)

Before setting the value, outside the setter

Inside the object, before each time the value is used

Is a setter allowed to change the value (maybe convert a valid value to some canonical internal representation)?

答:
There's not always a 1-1 mapping between property accessors and the ivars that store the data.

For example, a view class might provide a center property even though there's no ivar that stores the center of the view; setting center causes changes to other ivars, like origin or transform or whatever, but clients of the class don't know or care how center is stored provided that it works correctly. What should not happen, though, is that setting center causes things to happen beyond whatever is necessary to save the new value, however that's done.


问:
Why are tools like git-svn that allow git to integrate with svn useful?
I have read these related questions:

I'm a Subversion geek, why should I consider or not consider Mercurial or Git or any other DVCS?

git for personal (one-man) projects. Overkill?

...and I understand why git is useful. What I don't understand is why tools like git-svn that allow git to integrate with svn are useful.

When, for example, a team is working with svn, or any other centralised SCM, why would a member of the team opt to use git-svn? Are there any practical advantages for a developer that has to synchronize with a centralized repository?

答:
One other point to make is that it's less likely that a developer on a project is going to "go rogue" and use git while the rest of the team uses SVN, but it is likely that an entirely different group of developers wants to use and develop a project that uses SVN and this group prefers git.

For example, our group uses an open-source chemistry software that is hosted online with SVN. But we have changes we make internally that will not leave our group and we all know git. So rather than force everybody to learn both, we just let an educated one or two figure out git-svn and clone the project into an internal repository. And then our development processes continue without issue.

Even if we were not to make changes, some people are not programmers and can't (or really, won't) learn how to use both git and SVN. So we provide an intermediate step for those users, all they need to know is how to clone with git.


问:
How do people deal with Android fragmentation?
I've spent the past few years working on iOS apps, and I'm now giving some serious consideration to creating an Android port of one of my apps.

I'm sure that complaints about fragmentation are a frustrating cliche to experienced Android programmers, but as an iOS programmer, I'm quite honestly overwhelmed by the number of configurations and devices that my app might end up running on.

There are literally thousands of Android devices in the wild, but I know there are successful Android developers in the world and I know they're not testing or developing for thousands of different devices.

So how can a relatively small company deal with fragmentation? Is it possible to pick the five or six most popular devices, focus on those and prevent the app from being installed on any other devices? Are there any other strategies for practically dealing with the number of different configurations an app will face?

答:
Android is great at dealing with flexible designs that run across multiple devices. It's a huge topic that can't be expanded in detail as an answer, but I think fragmentation has gotten a bad rap. It really isn't that bad, and isn't that hard to handle.

It's great to see your App run from small screen phones to large 10" tablets, and Android handles all the layout of the fragments for you. I think you'll find iOS development could take a thing or two from Android ;).

What I've found is the App often has an objective of what it needs to achieve. As you develop you discover that the lower Android API levels don't meet those needs. So rather then thinking about what devices you need to target. Decide first on what Android version you must use to build the App.

Also, people using older Android platforms also might have a phone that can't handle the needs of the App anyway. So dropping support for older versions isn't really a loss, because it wouldn't have worked very well for them anyway (but that depends more on the App).


答:
My reasoning are somewhat less sophisticated than the other guys - but it's mostly combining the best of both worlds (my own local branches, stash, detached from the main repo).

As for the advantage of keeping SVN - single revision number for everyone - starting from support, developers, managers... all the way up to the managing director. And yes - I'm aware of git describe, but unfortunately: I need more than that to convince ppl.

Title: Why are tools like git-svn that allow git to integrate with svn useful?

Body:
I have read these related questions:

I'm a Subversion geek, why should I consider or not consider Mercurial or Git or any other DVCS?

git for personal (one-man) projects. Overkill?

...and I understand why git is useful. What I don't understand is why tools like git-svn that allow git to integrate with svn are useful.

When, for example, a team is working with svn, or any other centralised SCM, why would a member of the team opt to use git-svn? Are there any practical advantages for a developer that has to synchronize with a centralized repository?


问:
What is the career path for a software generalist?
A question on software specialties inspired this question.

How valuable is a software generalist compared to a specialist?

When I say generalist, I mean someone who can take a project from requirements to deployment, and is competent with all phases of the software development lifecycle. Someone who can put all the specialties together into a cohesive whole. An expert generalist knows his or her weaknesses and fills them by relying on specialists - example: Oracle specialists or UX specialists.

What do you see as the ultimate career path of the software generalist?

答: I think working for a smaller company, if you can find a good one, is the way to go. I once I had a job where my duties entailed being the web developer, sysadmin, content writer, online marketer/"SEO", and general office tech support. Daunting at times, but it was a lot of fun and a good learning experience   </p>

ContentLicense: CC BY-SA 2.5


问:
Hash Algorithm Randomness Visualization
I'm curious if anyone here has any idea how the images were generated as shown in this response: Which hashing algorithm is best for uniqueness and speed?

Ian posted a very well-received response but I can't seem to understand how he went about making the images. I hate to make a new question dedicated to this, but I can't find any means to ask him more directly. On the other hand, perhaps someone has an alternative perspective.

The best I can personally come up with would be to have it almost like a bar graph, which would illustrate how evenly the buckets of the hash table are being generated. I have a working Cocoa program that does this, but it can't generate anything like what he showed there.

So the question is two fold I suppose:

A) How does one truly interpret the data he shows? Is it more than "less whitespace = better"?

B) How does one generate such an image based on some set of inputs, a hash, and an index?

Perhaps I'm misunderstanding entirely, but I really would like to know more about this particular visualization technique. Or maybe I'm mis-applying this to hash tables rather than just hashes in general, but in that case I don't know how it would be "bounded" for the image.

答:
From the comment by Ian in the answer

Development tool is Delphi. i assume you mean the images though. For
  "linear" map i created a square bitmap of size nxn, (where n =
  Ceil(sqrt(hashTable.Capacity))). Rather than simply black for list
  entry is occupied and white for list entry is empty, i used an
  HSLtoRGB function, where the hue ranged from 0 (red) to 300 (magenta).
  White is still an "empty list cell". For the Hilbert map i had to hunt
  wikipedia for the algorithm that turns an index into an (x,y)
  coordinate.

Basically, less visually identifiable "pattern" is better as it means the hash is more truly random. Big holes (white space) would indicate that the hash is not spreading the values particularly well.

Title: Hash Algorithm Randomness Visualization


答:
There are many good answers already with some key reasons like

Offline/Private/Experimental commits

Exchange within small subgroups outside the main svn tree

But in my opinion there is another major reason to use git-svn for svn projects: Quickly accessible history. With svn you need a net connection for anything more than a simple svn diff. Depending on your location relative to the repository server and the server's load examining the history to find reasons for a potential bug or such can be quite slow. With git it only depends on the speed of your local disk. and then, thanks to git's compression, many history-related operations are quite fast.


问:
Persisting natural language processing parsed data
I've recently started experimenting with natural language processing (NLP) using Stanford's CoreNLP, and I'm wondering what are some of the standard ways to store NLP parsed data for something like a text mining application?

One way I thought might be interesting is to store the children as an adjacency list and make good use of recursive queries (Postgres supports this and I've found it works really well).

But I assume there are probably many standard ways to do this depending on what kind of analysis is being done that have been adopted by people working in the field over the years. So what are the standard persistence strategies for NLP parsed data and how are they used?

答:
I once worked with an NLP toolkit and ran into the problem you described. I think there are (at least) two approaches:

(implicit approach), use memoization

In programming languages where functions are first-class objects (such as Lua, Python, or Perl 1), automatic memoization can be implemented by replacing (at run-time) a function with its calculated value once a value has been calculated for a given set of parameters.

This was the approach I used and it could be implemented quickly; drawback was, that certain larger data structures would be persisted on disk, and while loading was orders of magnitude faster than recalculation, it still took its time.

(explicit), use some database, be it relational or document-oriented, to store
all the results you might care about in the future. This requires more attention in the beginning, but would pay off in the longer run.

Maybe of interest:

Data-Intensive Text Processing with MapReduce (PDF)

Edit: Another thing that I've been using lately for multistep long running computations is a workflow framework, of which there are dozens. It is not really about persistence, but persistence is a step in the workflow. I'm trying luigi for that and it comes, e.g. with Hadoop and Postgres helper classes, which can eliminate a lot of boilerplate code.


问:
Project Dashboards
I'm attempting to create a dashboard so that people not intimately involved with the project can get an indication of project's health. I'm struggling with determining what to put on said dashboard. I think it needs to be brief to be useful, yet complete. The project I'm working on depends on both 3rd party contractors, external hardware and of course my team's effort. Are there any suggestions or guidelines on how to encapsulate it all in a relatively easy manner?

Mods, I believe this question falls squarely between development methodologies and business concerns as outlined in the faq.

Thank you!

答:
I like a chart presenting planned completion date over time. I cannot find a good example right now, so I will describe it.

Both X and Y axis are dates. For each date on X axis we put on Y axis the project completion date as estimated on that day. The Y values will raise when tasks or milestones slip, or when we realize there's additional work (usually just discovered) that was not included in previous estimates. The Y values go down as we cut scope. Whenever there is a significant bump I would add a short comment explaining it (like "feature X slipping by 2 weeks" or "cut feature X" or "updated estimates for localization work"). This assumes you have a way of tracking the progress daily (in automated way) and you're honest about the data.

The chart works because it shows the thing that stakeholders are most interested in: when are we going to be done! It's value is in how it paints a dynamic view of how the team makes progress and how the team finds out hidden dependencies, surface issues, etc.

I would also think about having another line with known risks as of each day. If this line is not going down it will indicate, well that the projected completion date line is at more and more risk :-)

Title: Project Dashboards


问:
Clustering and custom applications
So lets say we have a clustered environment setup. We have a cluster SQL Server (I don't know exactly how its done but lets just say its been done for the sake of argument). Now if a website or application is trying to access that database for read/write (say an ASP.NET app or a C# Winforms app) and during that time SQL goes down - it takes a couple of minutes for the clustering failover to take affect to switch to another node. What happens during this time?

I think it will time out/unable to connect. BUT is there a way for it to place the request in some pipeline so when the cluster node is back up/switched over it will continue as normal?

答:
answer of the first question is, as you said, it will either timeout or get some error messages from server. it depends on how you design your program.

I suppose some of nodes in the cluster are working as api servers as it's a reasonable configuration. If you don't have an api server in the cluster, I believe you must have to set it up in somewhere else. otherwise, I don't think you are able to pipeline your requests.

once you have machines that are able to work for your pipeline task, I think there are two ways to complete your task.

the first one:

create another independent db server (let's call the db server you are using A and this isolated server B) that stores the info of requests, and write a function (let's call the function C) that keeps querying B in your api server (we call this action as 'polling'). of course, you can set query interval in C to improve the performance. the length of interval should depend on your situation.

Once the api node gets the request from B, it will query A to get relative info and do relative task. If the task is completed as expectation, C will ask B to delete the request. On the other hand, if A is not available, C will do nothing. Therefore, this request will not be deleted from B, and C will get the same request again when it queries B next time.

the second one:

set up a message queue server. all the requests from client-side will be sent to this mq server.

the duty of this mq server is keeping asking api server to work. if api works without any problem, then mq server should pop the request. otherwise, mq server should keep the request and ask api server to work again after an interval.

RabbitMQ with STOMP may be a good choice.

it's obvious that the first way is inefficient. you have to write, read and delete every request. all of these actions is time-consuming and may be the bottleneck if your service has to handle a lot of requests. However, if you don't want to use new framework, this may be a suitable option. Actually, I am currently working on a cloud computing system, and this is the way we use.

the second way is much more efficient, but you have to install new framework, which may be a maintaining issue in the future.

Title: Clustering and custom applications


问:
What's the web framework to use on a front-end web application?
What do you consider a good client web framework to use on interface business application? jQuery? YUI!? Another? Some plugins useful?

The application will be use mostly internally replacing a desktop application for data entry and lots of queries/views.

答:
Everyone has their own choices but my choice is Dojo.It is just too good and takes away a lot of your headaches. But yes if you are looking for all those third party extensions and stuff, then jQuery might be better for you, and yes jQuery definitely has a larger community than dojo , but believe me that wont hurt much.

Dojo might be a lot confusing in the beginning but it is worth the time you spend on it.


问:
iOS: Using Jenkins for nightly internal builds (TestFlight), plus frequent client builds
I'm an iOS dev, working for a small agency. I'm currently on a few smaller projects where I'm the only developer. We recently acquired a Jenkins server, but each project is left to fend for themselves as for how to use it.

I'd like to use it for making and distributing builds. My ideal would be:

Every commit is built as a single IPA that is placed in a HTTP-accessible location. (It only needs to keep the latest one, otherwise the disk would fill up — some of our apps are 500MB or more.)

Once a day it makes a build, signs it with our internal provisioning profile, tacks a build number onto the end of the version number, and sends it to our internal TestFlight team.

When manually prompted, it builds the latest commit, gives it a manually specified version number, signs it with the client's provisioning profile and sends it to TestFlight.

I'm pretty new to Jenkins. The developer who set up the server is running it on one of our projects, so I know it has the right stuff installed to do Xcode builds. I believe he's only using it to run unit tests though, not to do any of the code signing, IPA creation or TestFlight stuff.

So my questions:

I've listed three distinct kinds of build. How does Jenkins cope with that? I see there's a "build triggers" section in the config for a Jenkins project, but it doesn't seem to mention different types of build. Should I just set up multiple Jenkins projects, called "App X (continuous)", "App X (nightly)" and "App X (client)"?

How do I specify the provisioning profile through Jenkins? If there isn't a way, I guess I could make different configurations in the Xcode project…

Has anyone else used Jenkins to actually do the release (i.e. build and push to TestFlight) of beta builds of their apps? Is it a good idea? Or should I continue just doing it manually?

答:
The good news is that this is all possible. The bad news is that it is all manual. You will burn a lot of evenings fine-tuning things, and whether it ultimately pays off in time saved is not necessarily knowable in advance.

Here's an info-dump of things I've learned in the last few months of fiddling with Jenkins and Xcode.

There are Xcode and Testflight plugins for Jenkins, which will get you started. After you outgrow them, every chunk of logic becomes a shell/ruby/perl/python/whatever script.

For instance, I outgrew the Xcode plugin as soon as I realized I needed multi-configuration projects to create additional, closely-related builds, identical to the main one except for a single variable like an additional scheme, or a different $DEVELOPER_DIR for a beta Xcode. There was no way to pass those configuration parameters to the fields exposed by typical plugins. So, I reviewed the job logs to figure out how the Xcode plugin manipulated xcodebuild, and transplanted that into a script phase.

Signing from arbitrary identities or provisioning profiles, another thing the plugin was doing for me, became another script phase. A boolean job parameter like SIGN_WITH_DEVELOPER_ID communicates with a script phase like this:

```<code>if [ "${SIGN_WITH_DEVELOPER_ID}" = true ]; then
  echo "Re-signing build with Developer ID"
  $WORKSPACE/ci-scripts/developer-id-sign --path [...]
fi
</code>```

The script it calls boils down to something like:

```<code>/usr/bin/security unlock-keychain -p yourkeychainpassword ~/Library/Keychains/login.keychain
/usr/bin/codesign -f -vv -s 'Developer ID Application' path/to/binary 2>&1
</code>```

You'll outgrow the Testflight plugin as soon as you no longer want to upload every single build output by a given job. Instead, you'll probably want to invoke Testflight's upload API programmatically, signaled by another job parameter.

(I haven't fully automated the Testflight upload process yet, because we mostly use Testflight to distribute to clients, and I've been burned a time or two sending out a client build that defaulted to the wrong profile or which got mangled in transit. So, I vet those things by hand. The process of uploading to Testflight, though, is just a matter of invoking curl on your build server. Without having done it, I'm confident that it's viable because we have Jenkins doing something almost identical to upload dsyms to HockeyApp for in-the-wild releases of Mac apps, and that's working great.)

I recommend multi-configuration jobs as the best way to achieve multiple closely-related builds without job duplication, which creates a bunch of housekeeping for yourself as you then have to keep those related jobs in sync. Multi-configuration jobs are generally incompatible with plugins, unless you want them to run on every build variant, every time. In this way, multi-configuration jobs are a tradeoff between initial complexity and down-the-road flexibility.

However, your three builds as outlined aren't really that different, and don't strictly need to be multi-configuration jobs. The continuous build, kicked off after every landed commit, is the default. Whether or not you update the CFBundleVersion, and/or upload to Testflight with any given distribution, can be runtime configuration decisions, controlled via job parameters and script phases watching for them, or by the logic which kicks off your build in the first place.

More miscellaneous thoughts:

Without specifying a shebang line in a script phase, /bin/bash -xe behavior is assumed, which prints each line to the log as it goes, and fails the whole build as soon as it encounters a non-zero return value. This combination is usually what you want, and makes troubleshooting less awful.

If you don't like bash, and you wind up writing in some other scripting language, be vigilant about exit codes and emulate the bash -xe behavior yourself. I've found it preferable to embed significant logic in scripts we attach to projects, and to conditionally invoke them from Jenkins, via script phases that are as short and declarative as possible.

Without getting too far into the weeds, having Jenkins write things (like updated version numbers) into source control is tricky, and considered something of a CI code smell. It's also tremendously handy for nightly builds, but I haven't found a well-sanctioned way to pull it off. I wound up grafting the ability to update the bundleversion into the script which initiates the nightly build, fetches the build artifacts, stores them on a fileserver, and uploads a copy to Dropbox. In this scenario, the updated version number is in place before Jenkins wakes up, which is preferable to trying to make Jenkins do it in the middle of a build.)

It's not the focus of the talk, but I got religion on a lot of Jenkins capabilities, including multi-configuration jobs, after seeing some examples tossed off in WWDC 2012 session 404.

I recommend running Jenkins in a virtual machine, probably Linux, with Mac build nodes to do the Xcode gruntwork. I'm a Mac guy, but Jenkins is tested most thoroughly on Linux, its weekly-ish updates are easy to apply, and you can roll back to a working snapshot in the event of a problem. A Linux VM is low-overhead, and the time investment will pay you back the first time you update to a new version that gives you trouble.

In the long run, it will give you trouble, not because Jenkins is unreliable, but because CI is a permanent addition to your company's workflow, and sooner or later, everything breaks.

Body:
The good news is that this is all possible. The bad news is that it is all manual. You will burn a lot of evenings fine-tuning things, and whether it ultimately pays off in time saved is not necessarily knowable in advance.

Here's an info-dump of things I've learned in the last few months of fiddling with Jenkins and Xcode.

There are Xcode and Testflight plugins for Jenkins, which will get you started. After you outgrow them, every chunk of logic becomes a shell/ruby/perl/python/whatever script.

For instance, I outgrew the Xcode plugin as soon as I realized I needed multi-configuration projects to create additional, closely-related builds, identical to the main one except for a single variable like an additional scheme, or a different $DEVELOPER_DIR for a beta Xcode. There was no way to pass those configuration parameters to the fields exposed by typical plugins. So, I reviewed the job logs to figure out how the Xcode plugin manipulated xcodebuild, and transplanted that into a script phase.

Signing from arbitrary identities or provisioning profiles, another thing the plugin was doing for me, became another script phase. A boolean job parameter like SIGN_WITH_DEVELOPER_ID communicates with a script phase like this:

if [ "${SIGN_WITH_DEVELOPER_ID}" = true ]; then
  echo "Re-signing build with Developer ID"
  $WORKSPACE/ci-scripts/developer-id-sign --path [...]
fi

The script it calls boils down to something like:

/usr/bin/security unlock-keychain -p yourkeychainpassword ~/Library/Keychains/login.keychain
/usr/bin/codesign -f -vv -s 'Developer ID Application' path/to/binary 2>&1

You'll outgrow the Testflight plugin as soon as you no longer want to upload every single build output by a given job. Instead, you'll probably want to invoke Testflight's upload API programmatically, signaled by another job parameter.

(I haven't fully automated the Testflight upload process yet, because we mostly use Testflight to distribute to clients, and I've been burned a time or two sending out a client build that defaulted to the wrong profile or which got mangled in transit. So, I vet those things by hand. The process of uploading to Testflight, though, is just a matter of invoking curl on your build server. Without having done it, I'm confident that it's viable because we have Jenkins doing something almost identical to upload dsyms to HockeyApp for in-the-wild releases of Mac apps, and that's working great.)

I recommend multi-configuration jobs as the best way to achieve multiple closely-related builds without job duplication, which creates a bunch of housekeeping for yourself as you then have to keep those related jobs in sync. Multi-configuration jobs are generally incompatible with plugins, unless you want them to run on every build variant, every time. In this way, multi-configuration jobs are a tradeoff between initial complexity and down-the-road flexibility.

However, your three builds as outlined aren't really that different, and don't strictly need to be multi-configuration jobs. The continuous build, kicked off after every landed commit, is the default. Whether or not you update the CFBundleVersion, and/or upload to Testflight with any given distribution, can be runtime configuration decisions, controlled via job parameters and script phases watching for them, or by the logic which kicks off your build in the first place.

More miscellaneous thoughts:

Without specifying a shebang line in a script phase, /bin/bash -xe behavior is assumed, which prints each line to the log as it goes, and fails the whole build as soon as it encounters a non-zero return value. This combination is usually what you want, and makes troubleshooting less awful.

If you don't like bash, and you wind up writing in some other scripting language, be vigilant about exit codes and emulate the bash -xe behavior yourself. I've found it preferable to embed significant logic in scripts we attach to projects, and to conditionally invoke them from Jenkins, via script phases that are as short and declarative as possible.

Without getting too far into the weeds, having Jenkins write things (like updated version numbers) into source control is tricky, and considered something of a CI code smell. It's also tremendously handy for nightly builds, but I haven't found a well-sanctioned way to pull it off. I wound up grafting the ability to update the bundleversion into the script which initiates the nightly build, fetches the build artifacts, stores them on a fileserver, and uploads a copy to Dropbox. In this scenario, the updated version number is in place before Jenkins wakes up, which is preferable to trying to make Jenkins do it in the middle of a build.)

It's not the focus of the talk, but I got religion on a lot of Jenkins capabilities, including multi-configuration jobs, after seeing some examples tossed off in WWDC 2012 session 404.

I recommend running Jenkins in a virtual machine, probably Linux, with Mac build nodes to do the Xcode gruntwork. I'm a Mac guy, but Jenkins is tested most thoroughly on Linux, its weekly-ish updates are easy to apply, and you can roll back to a working snapshot in the event of a problem. A Linux VM is low-overhead, and the time investment will pay you back the first time you update to a new version that gives you trouble.

In the long run, it will give you trouble, not because Jenkins is unreliable, but because CI is a permanent addition to your company's workflow, and sooner or later, everything breaks.


问:
Is it bad to be the only person supporting software you have developed?
My employer has a need for a web-based application to manage and share data within the department, with approximately 50-75 possible users.  I feel I have the ability to write it for them.  I would likely use Python/Django with a MySQL database, so it would be open source.  However, I'm the only IT person in my department (our larger organization has a separate IT support staff with which I often work, but not for web development).  I want to develop this application, but if I leave in 1-2 years, and someone else has to come in after me and support it, will this be seen as a bad decision?

This is assuming all the obvious points -- I will write documentation, I will comment my code, and I will strive to follow good application design principles.  But will that be enough?  In principle, is it acceptable for one person to develop and support an entire web application?  Is this a "do first, then show and ask" kind of situation, or should I be certain it will be adopted by everyone involved first?

With regards to specifics, I work in an academic department of a university that has specific processes for student applicants and for their being admitted.  You have to apply to the university, AND my department separately.  The department-specific process is very manual and pieced together, which is where my development would come in.  We (myself and IT) are already planning on incorporating the additional questions that pertain to my department into the main university application (which IS electronic, and feeds into PeopleSoft), so that solves the front-end piece and everything would be in one place.  But for the faculty and staff to acquire and "digest" that information throughout the admissions process will require an application of some sort, which I would prefer to do "my way".  The IT staff want to develop it ALL in PeopleSoft, and I fear it will be too inflexible and will not be well received by our department, and may still not completely meet our needs.  There are third-party solutions which meet this need perfectly but they are cost-prohibitive.  I would query the data from PeopleSoft and present it how I know the faculty and staff need to see it.  (Getting access to query PeopleSoft is a different battle altogether.)

答:
"Bad"? No. "Ideal"? Nope.

Depending on the impact of this application among the user base, a single person could certainly handle the maintenance of this.  And any incoming replacements could as well.  I'd say give the project a try, but stress all along the way your desire to temper expectations (the amount of time/effort required for feature requests or bug fixes, coupled with any other "duties as assigned.").


答:
I would say some of my best engineers came from doing exactly what you are describing. Being placed in a position where you get to make these decisions (many engineers in larger organizations don't get those kinds of choices) helps increase your level of understanding by leaps and bounds.

Yes - it's a little more stress. But this will be something you created, it gives you incentive and a strong desire to learn, and an ability to hone your skills for learning how to learn.

I've led too many teams where engineers rely on the answers others provide without critical thought to the implications.

This project sounds like a great way to build not only your development skill set, but your technical leadership skill set, your open source skill set, your critical thinking skill set.

You will also learn something all the other developers rarely learn ... what it is to maintain an application that you yourself wrote! You know how differently you approach software development when you have to eat your own dog food?

One of my requirements for Jr and even Sr engineers is that they maintain the software that they may one day develop on.

Title: Is it bad to be the only person supporting software you have developed?

Body:
My employer has a need for a web-based application to manage and share data within the department, with approximately 50-75 possible users.  I feel I have the ability to write it for them.  I would likely use Python/Django with a MySQL database, so it would be open source.  However, I'm the only IT person in my department (our larger organization has a separate IT support staff with which I often work, but not for web development).  I want to develop this application, but if I leave in 1-2 years, and someone else has to come in after me and support it, will this be seen as a bad decision?

This is assuming all the obvious points -- I will write documentation, I will comment my code, and I will strive to follow good application design principles.  But will that be enough?  In principle, is it acceptable for one person to develop and support an entire web application?  Is this a "do first, then show and ask" kind of situation, or should I be certain it will be adopted by everyone involved first?

With regards to specifics, I work in an academic department of a university that has specific processes for student applicants and for their being admitted.  You have to apply to the university, AND my department separately.  The department-specific process is very manual and pieced together, which is where my development would come in.  We (myself and IT) are already planning on incorporating the additional questions that pertain to my department into the main university application (which IS electronic, and feeds into PeopleSoft), so that solves the front-end piece and everything would be in one place.  But for the faculty and staff to acquire and "digest" that information throughout the admissions process will require an application of some sort, which I would prefer to do "my way".  The IT staff want to develop it ALL in PeopleSoft, and I fear it will be too inflexible and will not be well received by our department, and may still not completely meet our needs.  There are third-party solutions which meet this need perfectly but they are cost-prohibitive.  I would query the data from PeopleSoft and present it how I know the faculty and staff need to see it.  (Getting access to query PeopleSoft is a different battle altogether.)


问:
Looking for a real-world example illustrating that composition can be superior to inheritance
I watched a bunch of lectures on Clojure and functional programming by Rich Hickey as well as some of the SICP lectures, and I am sold on many concepts of functional programming. I incorporated some of them into my C# code at a previous job, and luckily it was easy to write C# code in a more functional style.

At my new job we use Python and multiple inheritance is all the rage. My co-workers are very smart but they have to produce code fast given the nature of the company. I am learning both the tools and the codebase, but the architecture itself slows me down as well. I have not written the existing class hierarchy (neither would I be able to remember everything about it), and so, when I started adding a fairly small feature, I realized that I had to read a lot of code in the process. At the surface the code is neatly organized and split into small functions/methods and not copy-paste-repetitive, but the flip side of being not repetitive is that there is some magic functionality hidden somewhere in the hierarchy chain that magically glues things together and does work on my behalf, but it is very hard to find and follow. I had to fire up a profiler and run it through several examples and plot the execution graph as well as step through a debugger a few times, search the code for some substring and just read pages at the time. I am pretty sure that once I am done, my resulting code will be short and neatly organized, and yet not very readable.

What I write feels declarative, as if I was writing an XML file that drives some other magic engine, except that there is no clear documentation on what the XML should look like and what the engine does except for the existing examples that I can read as well as the source code for the 'engine'.

There has got to be a better way. IMO using composition over inheritance can help quite a bit. That way the computation will be linear rather than jumping all over the hierarchy tree. Whenever the functionality does not quite fit into an inheritance model, it will need to be mangled to fit in, or the entire inheritance hierarchy will need to be refactored/rebalanced, sort of like an unbalanced binary tree needs reshuffling from time to time in order to improve the average seek time.

As I mentioned before, my co-workers are very smart; they just have been doing things a certain way and probably have an ability to hold a lot of unrelated crap in their head at once.

I want to convince them to give composition and functional as opposed to OOP approach a try. To do that, I need to find some very good material. I do not think that a SCIP lecture or one by Rich Hickey will do - I am afraid it will be flagged down as too academic. Then, simple examples of Dog and Frog and AddressBook classes do not really connivence one way or the other - they show how inheritance can be converted to composition but not why it is truly and objectively better.

What I am looking for is some real-world example of code that has been written with a lot of inheritance, then hit a wall and re-written in a different style that uses composition. Perhaps there is a blog or a chapter. I am looking for something that can summarize and illustrate the sort of pain that I am going through.

I already have been throwing the phrase "composition over inheritance" around, but it was not received as enthusiastically as I had hoped. I do not want to be perceived as a new guy who likes to complain and bash existing code while looking for a perfect approach while not contributing fast enough. At the same time, my gut is convinced that inheritance is often the instrument of evil and I want to show a better way in a near future.

Have you stumbled upon any great resources that can help me?

答:
Without seeing a specific example, it's difficult to say if the inheritance is inappropriate or not.  Sometimes a problem is inherently complex, and "magic glue" code could just be a sign of good (albeit poorly documented) abstraction.

That being said, if the code truly can be improved by applying a given design principle, the best way to prove it to your coworkers is to do it.  Take a small part, change it to use composition instead of inheritance, and present that code.  You've already discovered that throwing a phrase around doesn't help.  That's because they are comparing concrete and familiar code to your theoretical concept.  You have to make your concept just as concrete.  Another academic example won't help.


答:
If your employer has an IT department your development may lead to some political unhappiness :)

Where will your site be hosted?  Trying to hand some external development off to the IT folks could be problematic.

I would suggest having your department head put in a request for IT to drive such development and that you try to get involved with it.

Most organisations have a set method / SDLC they follow and may have some set technology choices that do not include those that you are familiar with.

At the very least get the OK from IT to continue with something like this.


答:
Trust me I have been in your shoes and yes I have maintained the application that I had developed earlier. From my experience I think that a senior could fasten the learning process on the best approaches to a given problem but this will pay off itself as you start finding such approaches with experience. This will enable you to be more self reliant than other developers as you will be a part of every stage of the SDLC ( Requirement Gathering to Maintenance ). This overall experience will also help you know which part of development you enjoy the most and focus more on that!

I want to develop this application, but if I leave in 1-2 years, and someone else has to come in after me and support it, will this be seen as a bad decision?

No - If you follow the obvious points you mentioned ( document, comments and good design ).

In principle, is it acceptable for one person to develop and support an entire web application?

Yes - If I understand correctly, you already have experience in development but not necessarily in the web domain. This will be a good opportunity to hone you skills on a web technology. One thing to remember is that since it is a new horizon, you have to take the criticism from the users with a pinch of salt.

Is this a "do first, then show and ask" kind of situation, or should I be certain it will be adopted by everyone involved first?

I think you can clarify your understanding in the beginning as much as possible and then increase the visibility by making a prototype with the basic functionality and ask for the user's feedback. Change your approach if required and then plunge to a full fledged development.

Wish you all the best!


问:
DB API for shell scripting (any shell)
I am faced with some legacy shell scripts that run batch data processing jobs in Oracle using SQL+.  For the most part, the data tier does not have to communicate back to the script with retrieved data to be passed for shell-level processing but in a few cases it does.

The problem is, SQL+ is really meant to be an end user app and not an API that can communicate with other clients programmaticaly.  That is why people have invented APIs such as DBD::DBI for Perl, JDBC for Java, ODBC etc.  The way it is done is they invoke SQL+ and then parse the output, which is clearly designed for human eye consumption, using tools like sed and awk.  The whole thing is at best a hack and very prone to bugs.

Since this client is rather conservative with their technology, they don't want to scale their scripts up to Perl or Python where there are data access APIs.  So I am wondering whether there are similar APIs for shell, e.g. K or bash.  What I would like is if an API would return data in a 2-dimensional array or strings (for the lack of type setting) so that I can just read DB data like that.

The way they do it now is akin to parsing regular web page HTML to get a single stock quote rather than cleanly calling a web service and be done with it.

Anybody know of a product I can use?  Thanks

答:
Classic unix/linux shell tools are almost always text based - that is their strength (because of simplicity) and their weakness (because of the reasons you gave by yourself). So tools like SQLplus fit in that scheme, because they are text-based, too (though I think you are right, using this through a shell script has a high risk of becoming error prone and fragile).

I don't know any solution to your problem for K or Bash. But in the MS Windows world, there is a modern solution called Powershell which has exactly the capabilities you are asking for, and older scripting languages like VBScript can use COM based APIs like ADO / OLE-DB for database access. This may not help you for your case, since rewriting a bash script in Powershell will produce a comparable effort as rewriting it in Perl or Python.

Actually, if you cannot replace the old Bash code by no means, I first would try to live with the SQLplus solution and learn the gory details of how to deal with the weaknesses of that approach. SQLplus is old and mature, and there are solutions around for almost every problem you might encounter. Perhaps, if you have to add new features, you can try to use additional Perl or Python scripts and combine it with the existing shell scripts. For example, use Perl to call data from a web service and convert the data to a text format which can be processed furthermore within a bash script. And perhaps, if you show that solution to your client, you may convince him that bash scripts are not the best solution for everything.

Title: DB API for shell scripting (any shell)


答:
When I've worked on script and database systems that sound similar we did most of the complex logic (in any way related to the database) in PL/SQL rather than the script.

So the bash script would be a relatively simple thing, the PL/SQL would have the complex logic.  When it was particularly complex we would use a stored procedure and trigger that from the script.

This might be a less politically-perilous route than trying to champion Perl or Python.

Title: DB API for shell scripting (any shell)

Body:
I am faced with some legacy shell scripts that run batch data processing jobs in Oracle using SQL+.  For the most part, the data tier does not have to communicate back to the script with retrieved data to be passed for shell-level processing but in a few cases it does.

The problem is, SQL+ is really meant to be an end user app and not an API that can communicate with other clients programmaticaly.  That is why people have invented APIs such as DBD::DBI for Perl, JDBC for Java, ODBC etc.  The way it is done is they invoke SQL+ and then parse the output, which is clearly designed for human eye consumption, using tools like sed and awk.  The whole thing is at best a hack and very prone to bugs.

Since this client is rather conservative with their technology, they don't want to scale their scripts up to Perl or Python where there are data access APIs.  So I am wondering whether there are similar APIs for shell, e.g. K or bash.  What I would like is if an API would return data in a 2-dimensional array or strings (for the lack of type setting) so that I can just read DB data like that.

The way they do it now is akin to parsing regular web page HTML to get a single stock quote rather than cleanly calling a web service and be done with it.

Anybody know of a product I can use?  Thanks


问:
Does automatic returning affect performance?
There's a bunch of languages that automatically return the last value in a function (mostly functional) like Ruby, Haskell, Lisp, etc.

Does this feature (or what do you call it) affect the performance of these languages?

答:
In a word - no

With a compiler the emitted code would probably be identically anyway, with an interpreter it will be more or less be the same, if anything slightly quicker.


答:
The downside - from the company's perspective, and you probably wouldn't enjoy it either - is the possibility of a "bus error". The chance that the one person who knows how the app works (you) gets hit by a bus, and suddenly the company has 0 people who know how the app works but is still depending on it.

If I were your managers, I'd be asking how critical this tool will be to try and understand the severity of the risk, and definitely whether there's some off-the-shelf tool that'll do the same work but be easier or cheaper to support.


答:
Managers here use an issue report which shows a graph of how many issues of each priority group there are over time, ideally this graph should be decreasing at a gradient in proportion to the amount of developers.
A gantt chart may be worth looking into too.</p>

Title: Project Dashboards

Body:
I'm attempting to create a dashboard so that people not intimately involved with the project can get an indication of project's health. I'm struggling with determining what to put on said dashboard. I think it needs to be brief to be useful, yet complete. The project I'm working on depends on both 3rd party contractors, external hardware and of course my team's effort. Are there any suggestions or guidelines on how to encapsulate it all in a relatively easy manner?

Mods, I believe this question falls squarely between development methodologies and business concerns as outlined in the faq.

Thank you!


答:
It's not a duality; the question is not "should I use composition or inheritance", but "at which points in my object graph do I want to have inheritance hierarchies".

As far as examples go, I like to come up with car metaphors, so here goes.

Suppose you have an abstract base class Vehicle, and two classes that implement it: Car and Truck. They have a bunch of methods, e.g. get_num_wheels() and get_fuel_type(), get_num_seats(), etc. All is fine, but now you need to further split up the Truck class, because you have to support two-axle trucks (with four wheels) and three-axle trucks (six wheels). You also have to support cars that run on diesel as well as cars that run on gasoline. So now you have TwoAxleTruck, ThreeAxleTruck, DieselCar and GasolineCar. Oh, but now your passenger car comes in a pickup version with just two seats - two more classes, because that car can also be diesel or gasoline powered. And now the customer wants you to track the kind of cargo your vehicles can support; there's eight different classes of cargo, and all types of trucks and pickups should be able to support it. Is anyone counting? And we have another problem: pickups and two-axle trucks have a lot in common, but because the pickup inherits from Car and not from Truck, we have to duplicate that common behavior over both classes.

This is where composition comes in: We define a class Vehicle, which has a few properties, say Seats, Wheels, Engine, CargoHold, and each of these has a polymorphic type. The beauty is that the vehicle itself doesn't have to be polymorphic anymore: you can just combine individual instances of your component base classes to form any kind of vehicle you need. Note that we're still using inheritance to share common functionality: we've just split up the functionality into related groups, and build individual inheritance trees for each of them. Obviously, this works best if the components are functionally orthogonal, that is, that they can function mostly independently - e.g., the wheels don't need to know what kind of cargo they're transporting.

On a side note; Python's OOP model addresses some of the problems found in the classic inheritance situation through mechanisms such as advanced multiple inheritance (unlike, say, C++, python resolves base class conflicts such as the diamond problem in a well-defined and useful way), mix-ins, run-time object construction, etc. Because of this, multiple inheritance can sometimes be the better solution in python even if it would make for messy code in something like Java or C#.

Title: Looking for a real-world example illustrating that composition can be superior to inheritance

Body:
I watched a bunch of lectures on Clojure and functional programming by Rich Hickey as well as some of the SICP lectures, and I am sold on many concepts of functional programming. I incorporated some of them into my C# code at a previous job, and luckily it was easy to write C# code in a more functional style.

At my new job we use Python and multiple inheritance is all the rage. My co-workers are very smart but they have to produce code fast given the nature of the company. I am learning both the tools and the codebase, but the architecture itself slows me down as well. I have not written the existing class hierarchy (neither would I be able to remember everything about it), and so, when I started adding a fairly small feature, I realized that I had to read a lot of code in the process. At the surface the code is neatly organized and split into small functions/methods and not copy-paste-repetitive, but the flip side of being not repetitive is that there is some magic functionality hidden somewhere in the hierarchy chain that magically glues things together and does work on my behalf, but it is very hard to find and follow. I had to fire up a profiler and run it through several examples and plot the execution graph as well as step through a debugger a few times, search the code for some substring and just read pages at the time. I am pretty sure that once I am done, my resulting code will be short and neatly organized, and yet not very readable.

What I write feels declarative, as if I was writing an XML file that drives some other magic engine, except that there is no clear documentation on what the XML should look like and what the engine does except for the existing examples that I can read as well as the source code for the 'engine'.

There has got to be a better way. IMO using composition over inheritance can help quite a bit. That way the computation will be linear rather than jumping all over the hierarchy tree. Whenever the functionality does not quite fit into an inheritance model, it will need to be mangled to fit in, or the entire inheritance hierarchy will need to be refactored/rebalanced, sort of like an unbalanced binary tree needs reshuffling from time to time in order to improve the average seek time.

As I mentioned before, my co-workers are very smart; they just have been doing things a certain way and probably have an ability to hold a lot of unrelated crap in their head at once.

I want to convince them to give composition and functional as opposed to OOP approach a try. To do that, I need to find some very good material. I do not think that a SCIP lecture or one by Rich Hickey will do - I am afraid it will be flagged down as too academic. Then, simple examples of Dog and Frog and AddressBook classes do not really connivence one way or the other - they show how inheritance can be converted to composition but not why it is truly and objectively better.

What I am looking for is some real-world example of code that has been written with a lot of inheritance, then hit a wall and re-written in a different style that uses composition. Perhaps there is a blog or a chapter. I am looking for something that can summarize and illustrate the sort of pain that I am going through.

I already have been throwing the phrase "composition over inheritance" around, but it was not received as enthusiastically as I had hoped. I do not want to be perceived as a new guy who likes to complain and bash existing code while looking for a perfect approach while not contributing fast enough. At the same time, my gut is convinced that inheritance is often the instrument of evil and I want to show a better way in a near future.

Have you stumbled upon any great resources that can help me?


问:
Do people in non-English-speaking countries code in English?
I've heard it said (by coworkers) that everyone "codes in English" regardless of where they're from. I find that difficult to believe, however I wouldn't be surprised if, for most programming languages, the supported character set is relatively narrow.

Have you ever worked in a country where English is not the primary language?

If so, what did their code look like?

答:
From Brazil,

I write generic code in English but I prefer to use Portuguese when programming near to domain application. Some terms don't fit well in application when using alien words to domain. At same time, there is a clear separation between generic coding and domain coding.


问:
how do early stage startups hire ninja programmers
I am programmer who just started working on a startup idea. At the moment I want to bring onboard at least one programmer. This programmer should be a ninja - a 10x engineer.

Since early days are probably the most risky for a startup, I want to make sure I approach this problem the best I can.

How do I find these people? and How do I convince them to come onboard?

I would love to hear from people who started their own companies and what their thoughts are about hiring

Update: I would like to get the ninja as a co-founder so besides being a ninja (ie. great programmer with computer science background) he/she has to have a healthy appetite for risk (for great programmers this is not a big deal because they can be hired anytime into mainstream jobs if the startup doesn't work)

答: Pay lots of money. If they can't do that they offer stock options and nice perks like free food, drink, nice working environment with latest equipment and good benefits. Basically you have to give them something worthwhile, no one is interested in making you rich for their toil.</p>


问:
How do you unit test private methods?
I am working on a java project. I am new to  unit testing. What is the best way to unit test private methods in java classes?</p>

答:
If you really need to test private method, with Java I mean, you can use fest assert and/or fest reflect. It uses reflection.

Import the library with maven (given versions are not the lastest I think) or import it directly in your classpath:

```<code><dependency>
     <groupId>org.easytesting</groupId>
     <artifactId>fest-assert</artifactId>
     <version>1.4</version>
    </dependency>

    <dependency>
     <groupId>org.easytesting</groupId>
     <artifactId>fest-reflect</artifactId>
    <version>1.2</version>
</dependency>
</code>```

As an example, if you have a class named 'MyClass' with a private method named 'myPrivateMethod' which take a String as parameter an update its value to 'this is cool testing !', you can do the following junit test:

```<code>import static org.fest.reflect.core.Reflection.method;
...

MyClass objectToTest;

@Before
public void setUp(){
   objectToTest = new MyClass();
}

@Test
public void testPrivateMethod(){
   // GIVEN
   String myOriginalString = "toto";
   // WHEN
   method("myPrivateMethod").withParameterTypes(String.class).in(objectToTest).invoke(myOriginalString);
   // THEN
   Assert.assertEquals("this is cool testing !", myOriginalString);
}
</code>```

This library also enables you to replace any bean properties (no matter they are private and no setters are written) by a mock, and using this with Mockito or any other mock framework is really cool. The only thing you have to know at the moment (don't know if this will be better in next versions) is the name of the target field / method you want to manipulate, and its signature.

Title: How do you unit test private methods?

Body:
If you really need to test private method, with Java I mean, you can use fest assert and/or fest reflect. It uses reflection.

Import the library with maven (given versions are not the lastest I think) or import it directly in your classpath:

<dependency>
     <groupId>org.easytesting</groupId>
     <artifactId>fest-assert</artifactId>
     <version>1.4</version>
    </dependency>

    <dependency>
     <groupId>org.easytesting</groupId>
     <artifactId>fest-reflect</artifactId>
    <version>1.2</version>
</dependency>

As an example, if you have a class named 'MyClass' with a private method named 'myPrivateMethod' which take a String as parameter an update its value to 'this is cool testing !', you can do the following junit test:

import static org.fest.reflect.core.Reflection.method;
...

MyClass objectToTest;

@Before
public void setUp(){
   objectToTest = new MyClass();
}

@Test
public void testPrivateMethod(){
   // GIVEN
   String myOriginalString = "toto";
   // WHEN
   method("myPrivateMethod").withParameterTypes(String.class).in(objectToTest).invoke(myOriginalString);
   // THEN
   Assert.assertEquals("this is cool testing !", myOriginalString);
}

This library also enables you to replace any bean properties (no matter they are private and no setters are written) by a mock, and using this with Mockito or any other mock framework is really cool. The only thing you have to know at the moment (don't know if this will be better in next versions) is the name of the target field / method you want to manipulate, and its signature.


答:
Technically what you are asking is impossible to be obtained; composition and inheritance are two distinct concepts when speaking about object modeling and one cannot be replaced by other.

When modeling there is nothing wrong with inheritance; the real problem is when in reality you do not have inheritance and in code you have inheritance. When you just use inheritance only for the sake of code reuse you usually go wrong; here composition is a better approach. It in this scenario, that the famous GoF principle "Favor composition over inheritance" is applied, that is use inheritance when and only when you model an "is-a" relationship; it would be a pretty bad design idea to model an "is-a" relationship via composition. Also, there are many more "has-a" relationships in the real world than "is-a" relationships.

On the other hand when you are not really modeling a real-world entity (software stuff) in order to obtain code reuse, composition is preferred in most of the cases. There are example that could be given here.


问:
Calculating 3d rotation around random axis
This is actually a solved problem, but I want to understand why my original method didn't work (hoping someone with more knowledge can explain).

(Keep in mind, I've not very experienced in 3d programming, having only played with the very basic for a little bit...nor do I have a lot of mathematical experience in this area).

I wanted to animate a point rotating around another point at a random axis, say a 45 degrees along the y axis (think of an electron around a nucleus). I know how to rotate using the transform matrix along the X, Y and Z axis, but not an arbitrary (45 degree) axis.

Eventually after some research I found a suggestion: Rotate the point by -45 degrees around the Z so that it is aligned. Then rotate by some increment along the Y axis, then rotate it back +45 degrees for every frame tick. While this certainly worked, I felt that it seemed to be more work then needed (too many method calls, math, etc) and would probably be pretty slow at runtime with many points to deal with.

I thought maybe it was possible to combine all the rotation matrixes involve into 1 rotation matrix and use that as a single operation.

Something like:

```<code> [ cos(-45)    -sin(-45)         0]
 [ sin(-45)     cos(-45)         0]      rotate by -45 along Z
 [    0            0             1]
</code>```

multiply by

```<code> [ cos(2)          0       -sin(2)]
 [    0            1            0 ]      rotate by 2 degrees (my increment) along Y
 [ sin(2)          0        cos(2)]
</code>```

then multiply that result by (in that order)

```<code> [ cos(45)      -sin(45)         0]
 [ sin(45)       cos(45)         0]      rotate by 45 along Z
 [    0            0             1]
</code>```

I get 1 mess of a matrix of numbers (since I was working with unknowns and 2 angles), but I felt like it should work. It did not and I found a solution on wiki using a different matirx, but that is something else.

I'm not sure if maybe I made an error in multiplying, but my question is: this is actually a viable way to solve the problem, to take all the separate transformations, combine them via multiplying, then use that or not?

答:
It's been a while since I did much matrix maths, but I'm pretty sure your approach is valid.

Sounds like you need to reverse the order of the transforms when you multiply those matrices together. When you combine matrix transforms (of any sort) you always start with the last one and work backwards.


答:
You can indeed compound ('add up') the rotations by multiplication.

I'd consider using Quaternions instead though. They're much nicer to work with and they avoid problems with Euler type rotations (e.g. gimbal lock). You can plug in arbitrary axes of rotation, rather than worrying about X, Y, Z rotations. Quaternion compound rotations nicely -- and if you have interactive 3D objects the user can spin etc., you'll want to compound rotations.

Lots on the web about Quaternions, e.g.:

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

http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Quaternion+and+Rotation+Primer

https://stackoverflow.com/questions/8919086/why-are-quaternions-used-for-rotations

Title: Calculating 3d rotation around random axis

Body:
This is actually a solved problem, but I want to understand why my original method didn't work (hoping someone with more knowledge can explain).

(Keep in mind, I've not very experienced in 3d programming, having only played with the very basic for a little bit...nor do I have a lot of mathematical experience in this area).

I wanted to animate a point rotating around another point at a random axis, say a 45 degrees along the y axis (think of an electron around a nucleus). I know how to rotate using the transform matrix along the X, Y and Z axis, but not an arbitrary (45 degree) axis.

Eventually after some research I found a suggestion: Rotate the point by -45 degrees around the Z so that it is aligned. Then rotate by some increment along the Y axis, then rotate it back +45 degrees for every frame tick. While this certainly worked, I felt that it seemed to be more work then needed (too many method calls, math, etc) and would probably be pretty slow at runtime with many points to deal with.

I thought maybe it was possible to combine all the rotation matrixes involve into 1 rotation matrix and use that as a single operation.

Something like:

```<code> [ cos(-45)    -sin(-45)         0]
 [ sin(-45)     cos(-45)         0]      rotate by -45 along Z
 [    0            0             1]
</code>```

multiply by

```<code> [ cos(2)          0       -sin(2)]
 [    0            1            0 ]      rotate by 2 degrees (my increment) along Y
 [ sin(2)          0        cos(2)]
</code>```

then multiply that result by (in that order)

```<code> [ cos(45)      -sin(45)         0]
 [ sin(45)       cos(45)         0]      rotate by 45 along Z
 [    0            0             1]
</code>```

I get 1 mess of a matrix of numbers (since I was working with unknowns and 2 angles), but I felt like it should work. It did not and I found a solution on wiki using a different matirx, but that is something else.

I'm not sure if maybe I made an error in multiplying, but my question is: this is actually a viable way to solve the problem, to take all the separate transformations, combine them via multiplying, then use that or not?


问:
What are some important guidelines when starting a software cooperative?
We are a group of people who are about to start a software cooperative, which means all of us (and other future workers) will be the owners of the 'company' rather than having bosses and employees. We do this from ideological reasons but also because we believe this allows many advantages - power of democracy (see SE..) , motivation, creativity, good work relations and atmosphere and more.

We do face some questions about how exactly ownership of our products should be split, should we give different percentage for different people which put in a different amount of work hours or brings expert knowledge.

We want people to feel they get what they deserve, not more, not less, and we're not sure just splitting it even will give this feeling.

What are some good guidelines for solving these questions in a cooperative?

答:
Both for ethical/ideological reasons and for technical/sociological/practical ones, trying to measure the performed work is a very bad idea. In Italy, where I live, it is even against the law (at least in the specific case of a cooperative). I strongly suggest you to just split even the cooperative global income, no matter how much any individual programmer has actually worked.

The typical legal structure of a cooperative provides many others managing/political tools to deal with lazy people or other problems. You do not need this.

You are right when you are looking at SE and other community-driven projects. In these projects, nobody tries to measure the work perfomed by members. There is a reason for such a lack of control. This is one of the reasons of the success of many open source projects.

Highly-skilled people, like programmers, want acknowledgment much more than anything else. You cannot measure deserved acknowledgment by hours worked or by written LoCs. Only the rest of the community (the rest of the cooperative members) can give acknowledgment to a programmer. They do it through the typical tools of any democracy: personal judgement, vote, silent recognition, given reputation and so on. Rely on these.


答:
Testing of private methods would depend on their complexity; some one line private methods wouldn't really warrant the extra effort of testing (this can also be said of public methods), but some private methods can be just as complex as public methods, and difficult to test through the public interface.

My preferred technique is to make the private method package private, which will allow access to a unit test in the same package but it will still be encapsulated from all other code. This will give the advantage of testing the private method logic directly instead of having to rely on a public method test to cover all parts of (possibly) complex logic.

If this is paired with the @VisibleForTesting annotation in the Google Guava library, you are clearly marking this package private method as visible for testing only and as such, it shouldn't be called by any other classes.

Opponents of this technique argue that this will break encapsulation and open private methods to code in the same package. While I agree that this breaks encapsulation and does open private code to other classes, I argue that testing complex logic is more important than strict encapsulation and not using package private methods which are clearly marked as visible for testing only must be the responsibility of the developers using and changing the code base.

Private method before testing:

```<code>private int add(int a, int b){
    return a + b;
}
</code>```

Package private method ready for testing:

```<code>@VisibleForTesting
int add(int a, int b){
    return a + b;
}
</code>```

Note: Putting tests in the same package is not equivalent to putting them in the same physical folder. Separating your main code and test code into separate physical folder structures is good practice in general but this technique will work as long as the classes are defined as in the same package.

Title: How do you unit test private methods?

Body: I am working on a java project. I am new to  unit testing. What is the best way to unit test private methods in java classes?</p>

Body:
Testing of private methods would depend on their complexity; some one line private methods wouldn't really warrant the extra effort of testing (this can also be said of public methods), but some private methods can be just as complex as public methods, and difficult to test through the public interface.

My preferred technique is to make the private method package private, which will allow access to a unit test in the same package but it will still be encapsulated from all other code. This will give the advantage of testing the private method logic directly instead of having to rely on a public method test to cover all parts of (possibly) complex logic.

If this is paired with the @VisibleForTesting annotation in the Google Guava library, you are clearly marking this package private method as visible for testing only and as such, it shouldn't be called by any other classes.

Opponents of this technique argue that this will break encapsulation and open private methods to code in the same package. While I agree that this breaks encapsulation and does open private code to other classes, I argue that testing complex logic is more important than strict encapsulation and not using package private methods which are clearly marked as visible for testing only must be the responsibility of the developers using and changing the code base.

Private method before testing:

private int add(int a, int b){
    return a + b;
}

Package private method ready for testing:

@VisibleForTesting
int add(int a, int b){
    return a + b;
}

Note: Putting tests in the same package is not equivalent to putting them in the same physical folder. Separating your main code and test code into separate physical folder structures is good practice in general but this technique will work as long as the classes are defined as in the same package.


问:
What programming languages exist for mechatronics purposes?
Is there any specific language which is designed for mechatronics programming? I know about LabView, which is a data flow language, but not sure about its main platform.

Could you recommend to me, some languages apart from c/c++? Any language which is used in the topic of mechatronics( robotics, sensor programming, etc ).

答:
Before "mechatronics" was called that, in the industry they just called it "automation".  The field is dominated in North America initially by Ladder logic, which everyone on this website (except me) would absolutely hate if they saw it.  It has its purposes however.

In the last 10 years you see a lot more standardization of automation languages, specifically the IEC-61131-3 standard, which includes the following languages:

LD (Ladder Diagram) - a.k.a. ladder logic

FBD (Function Block Diagram) - similar to your labview

SFC (Sequential Function Chart) - a fancy state machine or state diagram

ST (Structured Text) - a "normal" computer language with a syntax similar to BASIC/Pascal

IL (Instruction List) - kind of like assembly, but not really

In real life (I do this for a living) I see a lot of LD, and then secondarily a bunch of FBD and ST.  I myself have used SFC in several projects over the last 5 years, and I like some of its features, but it has some problems (notably gentle recovery from faults is usually harder in SFC than in LD).

Note that IEC-61131-3 is only a standard that nails down the data types and the features of the languages, but the syntax of each language typically differs greatly from vendor to vendor.  You can't just export code from one vendor's IDE and import it into another.  They're not compatible.

There was one other proprietary automation language I used, called Steeplechase.  It's a flowchart based language, similar to SFC, but simpler.  I believe it was purchased by Entivity, which was then purchased by Phoenix Contact, so I think they still sell it.  I remember it also had a ladder logic engine as well.

Edit:

For an example of ladder logic (and a bit of SFC), here's an introductory tutorial I wrote on how to get going with Rockwell Software's RSLogix 5000 ladder logic programming software for Allen-Bradley's popular line of ControlLogix PLC's: RSLogix 5000 Tutorial.  It'll give you a good idea of how it works, even though the example is a bit contrived.


答:
First of all I think actually all programming languages which allows you to write Hardware related. e.g. C/C++, Assembler. In my opinion for hardware-oriented programming, you do not manage it without C/C++. It's the best and safest choice. But you can try it with python! There existing many hardware-oriented libs for Pyro, myro.
I search for this, here is my result:

google python, sensor, robotic

python hardware programming

Title: What programming languages exist for mechatronics purposes?

Body:
Is there any specific language which is designed for mechatronics programming? I know about LabView, which is a data flow language, but not sure about its main platform.

Could you recommend to me, some languages apart from c/c++? Any language which is used in the topic of mechatronics( robotics, sensor programming, etc ).

Body:
First of all I think actually all programming languages which allows you to write Hardware related. e.g. C/C++, Assembler. In my opinion for hardware-oriented programming, you do not manage it without C/C++. It's the best and safest choice. But you can try it with python! There existing many hardware-oriented libs for Pyro, myro.
I search for this, here is my result:

google python, sensor, robotic

<a href="https://www.google.de/search?oq=safe%20safer%20safest&sugexp=chrome,mod=0&sourceid=chrome&ie=UTF-8&q=safe%20safer%20safest#hl=de&gs_nf=3&tok=pUeQgBCOZxqjo_9u__eWDw&pq=python%20sensor,%20robotic,&cp=16&gs_id=10&xhr=t&q=python%20hardware%20programming&pf=p&tbo=d&sclient=psy-ab&oq=python%20hardware%20&gs_l=&pbx=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.&fp=b7e64227ce2234f7&bpcl=38897761&biw=1366&bih=682" rel="nofollow">python hardware programming


问:
Supporting and testing multiple versions of a software library in a Maven project
My company has several versions of its core software in use by our customers at any one time. My job is to write bespoke Java software for the customers based on the version of core software they happen to be running.

I've created a common Java library that performs many of the tasks I regularly require in a normal project. This is a Maven project that I deploy to our local Artifactory and pull down into other Maven projects when required.

Currently this library includes v1.3 of our core software, for example:

<dependency>
  <groupId>com.foo</groupId>
  <artifactId>core-software</artifactId>
  <version>1.3</version>
</dependency>
```

<p>As a result, that's the only version I'm completely confident is compatible due to the success of the unit tests. <strong>How can I best automate testing with other versions of the core software to ensure compatibility?</strong></p>

<hr>

<p>One possibility is to create a series of Maven projects that incorporate my library and override the core-software version:</p>

<pre class="lang-xml prettyprint-override"><code><!-- Override core version -->
<dependency>
  <groupId>com.foo</groupId>
  <artifactId>core-software</artifactId>
  <version>1.2</version>
</dependency>
<!-- Incorporate shared library: -->
<dependency>
  <groupId>com.foo</groupId>
  <artifactId>common-lib</artifactId>
  <version>1.0</version>
</dependency>
</code>```

I could then execute the unit tests from my main project to ensure they all pass (I need to figure that bit out). The benefit of this approach is that I can incorporate these additional Maven projects in my continuous integration server and be alerted whenever a check-in breaks compatibility with another core software version.

Can anyone suggest a better alternative?

答:
You could use multiple Maven profiles in your project, overriding the version of the core software in each profile. Then just get your CI software to build with each profile.

The profile might say this:

```<code><profiles>
  <profile>
    <id>old</id>

    <!-- When this profile will turn on... -->
    <activation>
      <property>
        <name>buildVer</name>
        <value>old</value>
      </property>
    </activation>

    <!-- What this profile changes... -->
    <dependencies>
      <dependency>
        <groupId>com.foo</groupId>
        <artifactId>core-software</artifactId>
        <version>1.2</version>
      </dependency>
    </dependencies>
  </profile>

  <profile>
    <id>veryold</id>
    <activation>
      <property>
        <name>buildVer</name>
        <value>veryold</value>
      </property>
    </activation>
    <dependencies>
      <dependency>
        <groupId>com.foo</groupId>
        <artifactId>core-software</artifactId>
        <version>1.0</version>
      </dependency>
    </dependencies>
  </profile>
</profiles>
</code>```

Body:
You could use multiple Maven profiles in your project, overriding the version of the core software in each profile. Then just get your CI software to build with each profile.

The profile might say this:

<profiles>
  <profile>
    <id>old</id>

    <!-- When this profile will turn on... -->
    <activation>
      <property>
        <name>buildVer</name>
        <value>old</value>
      </property>
    </activation>

    <!-- What this profile changes... -->
    <dependencies>
      <dependency>
        <groupId>com.foo</groupId>
        <artifactId>core-software</artifactId>
        <version>1.2</version>
      </dependency>
    </dependencies>
  </profile>

  <profile>
    <id>veryold</id>
    <activation>
      <property>
        <name>buildVer</name>
        <value>veryold</value>
      </property>
    </activation>
    <dependencies>
      <dependency>
        <groupId>com.foo</groupId>
        <artifactId>core-software</artifactId>
        <version>1.0</version>
      </dependency>
    </dependencies>
  </profile>
</profiles>