问:
Benefits of RTOS vs Bare Metal for MCU Programming?
Please note: This question specifically mentions two RTOSes but is more generic and can probably be answered by anybody who has written C code for embedded RTOSes before, and had their software run directly on MCUs.

I am interested in learning more about embedded RTOSes and writing applications for them. I am currently looking at Embox and RIOT because they're open source, modern, active and seem to have excellent documentation. My goal has two phases: Phase 1 is to figure out how to compile and flash these OSes to an MCU (probably AVR or ARM). Phase 2 is to then write a simple C program (basically a headless daemon), that would evolve over time as a "hobby app". I would then flash/deploy this program to the same MCU, thereby successfully deploying an appstack consisting of Embox/RIOT and my app residing on top of it.

Before I go down any roads that ultimately lead to dead ends, I stumbled across this article that does a pretty good job of explaining why real-time apps, written in C/assembler and flashed to MCUs, don't really need RTOSes underneath them.

So now I'm really confused, and am questioning some of my fundamental understanding of computing theory. I guess I'm trying to make the decision of whether or not to even use Embox/RIOT in the first place, either:

Stay the course and go with an "app stack" on the MCU of both OS + app; or

Heed the article's warning and just go with an MCU running my app "bare metal"

Obviously, the former is more work, and so there had better be a good reason/payoff for going that route. So I ask: what are the real benefits these (and similar) embedded RTOSes offer to MCU/C app developers? What specific features could my C app benefit from (perhaps by not reinventing the wheel?) by using an RTOS? What is lost by ditching the RTOS and going bare metal?

I'm asking for concrete examples here, not the media hype you get when you go to the wikipedia entry for RTOSes ;-)

答:
Microcontroller programs consist of a number of tasks.  Let's say you wanted to make a computer-controlled telescope mount.  The tasks would be:

Retrieve a new byte of input from the USB serial buffer.

Check if we've received a complete command.

If so, execute that command.

Read the sensors for the current telescope position.

Set the proper output to control the next step of the motors.

This is a fairly typical set of tasks for something you would use a microcontroller for, and are pretty easy to manage with an infinite loop, like:

```<code>while(TRUE) {
  uint8_t input = readUsbBuffer();
  parseCommand(input);
  readSensors();
  setMotors();
}
</code>```

If you keep adding and adding features, you eventually start coming across common problems you want to create abstractions for, like:

Your buffer is overflowing, so you want to make sure that task can interrupt other tasks before it overflows.

You want to save battery by sleeping when nothing is needed.

You want to make sure all tasks get a fair shot.  If readSensors takes too long, you want to be able to interrupt it and come back to it later.

You want to be able to just reset one task without affecting others.

You want a memory leak or other bug in one task to not take out the other tasks.

You want to be able to give different tasks different priorities.

You want to be able to sandbox an untrusted task.

You want to be able to execute tasks at different rates.  Perhaps your sensors can only be read 10 times per second, but you want to execute a motor step 100 times per second.

One or two of these items can be handled manually relatively easily.  If you have enough of these kinds of problems frequently enough that you start generalizing them into libraries, you've basically reinvented an RTOS.  If your program's task management is complex enough, even if you don't use an off-the-shelf RTOS, you will eventually end up reinventing one poorly.

However, in my experience, the line where you want an RTOS is very close to the line where you want a microprocessor instead of a microcontroller.  If you anticipate your firmware getting that complex, it's usually better to go the microprocessor route from the beginning.

Body:
Microcontroller programs consist of a number of tasks.  Let's say you wanted to make a computer-controlled telescope mount.  The tasks would be:

Retrieve a new byte of input from the USB serial buffer.

Check if we've received a complete command.

If so, execute that command.

Read the sensors for the current telescope position.

Set the proper output to control the next step of the motors.

This is a fairly typical set of tasks for something you would use a microcontroller for, and are pretty easy to manage with an infinite loop, like:

while(TRUE) {
  uint8_t input = readUsbBuffer();
  parseCommand(input);
  readSensors();
  setMotors();
}

If you keep adding and adding features, you eventually start coming across common problems you want to create abstractions for, like:

Your buffer is overflowing, so you want to make sure that task can interrupt other tasks before it overflows.

You want to save battery by sleeping when nothing is needed.

You want to make sure all tasks get a fair shot.  If readSensors takes too long, you want to be able to interrupt it and come back to it later.

You want to be able to just reset one task without affecting others.

You want a memory leak or other bug in one task to not take out the other tasks.

You want to be able to give different tasks different priorities.

You want to be able to sandbox an untrusted task.

You want to be able to execute tasks at different rates.  Perhaps your sensors can only be read 10 times per second, but you want to execute a motor step 100 times per second.

One or two of these items can be handled manually relatively easily.  If you have enough of these kinds of problems frequently enough that you start generalizing them into libraries, you've basically reinvented an RTOS.  If your program's task management is complex enough, even if you don't use an off-the-shelf RTOS, you will eventually end up reinventing one poorly.

However, in my experience, the line where you want an RTOS is very close to the line where you want a microprocessor instead of a microcontroller.  If you anticipate your firmware getting that complex, it's usually better to go the microprocessor route from the beginning.


问:
Refactoring code with just a few lines different
I have two for loops in a function which look like these:

```<code>for (int i=0; i < MAX; ++i) {
    identical_lines
    identical_lines
    identical_lines
    first_for_specific_line
    identical_lines
    identical_lines
    identical_lines
    first_for_specific_line
    identical_lines
    identical_lines
}

for (int i=MAX - 4; i > 0; --i) {
    identical_lines
    identical_lines
    identical_lines
    second_for_specific_line
    identical_lines
    identical_lines
    identical_lines
    second_for_specific_line
    identical_lines
    identical_lines
}
</code>```

i.e. these two for loops have different conditions and indices, but their code is pretty much the same (all the 'identical_lines' are the same in the two for loops).

However there are a few spots (the one marked with 'specific_line') which are different for each one of these for loops.

I would like to avoid code duplication and merge these for loops but I can't think of something to unify them and still have the different lines.

The language I'm using is C++

答:
Before grabbing into the "modern C++" bag, let us keep things simple and start with some classic, language agnostic techniques. One solution is to make a function of the form

```<code>   void myfunc(int i,bool upward)
   {
        identical_lines
        identical_lines
        identical_lines
        if(upward)
           first_for_specific_line
        else
           second_for_specific_line
        //...
    }
</code>```

and call that like

```<code> for (int i=0; i < MAX; ++i)
    myfunc(i,true);

  for (int i=MAX - 4; i > 0; --i)
    myfunc(i,false);
</code>```

Note that this is not always the best solution since it has a tendency to make myfunc doing "too much", maybe violating the single responsitibility principle. Often it is better to refactor each block you have marked as identical_lines into a small function on its own (lets call it block1(int i), block2(int i) , and create 2 functions

```<code>   myfunc1(int i)
   {
        block1(i);
        first_for_specific_line;
        block2(i);
        // ...
   }
</code>```

and

```<code>   myfunc2(int i)
   {
        block1(i);
        second_for_specific_line;
        block2(i);
        // ...
   }
</code>```

and use it like

```<code>  for (int i=0; i < MAX; ++i)
    myfunc1(i);

  for (int i=MAX - 4; i > 0; --i)
    myfunc2(i);
</code>```

However, to decide what is the "best" way to cut your code blocks down to small functions depends on what the blocks are really doing. It is better to build abstractions not primarily on formal criteria like "the code blocks look similar", but on "what is the task or purpose of this block. Ask yourself which of the lines belong together to fulfill that purpose and if you can characterize that task by a single, accurate name.

ContentLicense: CC BY-SA 3.0

Body:
Before grabbing into the "modern C++" bag, let us keep things simple and start with some classic, language agnostic techniques. One solution is to make a function of the form

   void myfunc(int i,bool upward)
   {
        identical_lines
        identical_lines
        identical_lines
        if(upward)
           first_for_specific_line
        else
           second_for_specific_line
        //...
    }

and call that like

 for (int i=0; i < MAX; ++i)
    myfunc(i,true);

  for (int i=MAX - 4; i > 0; --i)
    myfunc(i,false);

Note that this is not always the best solution since it has a tendency to make myfunc doing "too much", maybe violating the single responsitibility principle. Often it is better to refactor each block you have marked as identical_lines into a small function on its own (lets call it block1(int i), block2(int i) , and create 2 functions

   myfunc1(int i)
   {
        block1(i);
        first_for_specific_line;
        block2(i);
        // ...
   }

and

   myfunc2(int i)
   {
        block1(i);
        second_for_specific_line;
        block2(i);
        // ...
   }

and use it like

  for (int i=0; i < MAX; ++i)
    myfunc1(i);

  for (int i=MAX - 4; i > 0; --i)
    myfunc2(i);

However, to decide what is the "best" way to cut your code blocks down to small functions depends on what the blocks are really doing. It is better to build abstractions not primarily on formal criteria like "the code blocks look similar", but on "what is the task or purpose of this block. Ask yourself which of the lines belong together to fulfill that purpose and if you can characterize that task by a single, accurate name.


问:
Can a UML class diagram show two different relationships between two classes?
I have a class which has an inner (nested) class. I have shown this relationship between the two classes in my class diagram. However, I am also using the inner class within the outer class... do I show another relationship for this or is the containment relationship enough?</p>

答:
From The Unified Modeling Language User Guide (Booch, Rumbaugh, Jacobson) association is "a structural relationship that describes a set of links, in which a link is a connection among objects".

Aggregation is "a special form of association that specifies a whole-part relationship between the aggregate (the whole) and a component (the part)."

Finally, usage is "a dependency in which one element (the client) requires the presence of another elements (the supplier) for its correct functioning or implementation."

Given that, aggregation implies usage, so it's not necessary to depict it separately for an inner class relationship.


问:
Should functions of a C library always expect a string's length?
I'm currently working on a library written in C. Many functions of this library expect a string as char* or const char* in their arguments. I started out with those functions always expecting the string's length as a size_t so that null-termination wasn't required. However, when writing tests, this resulted in frequent use of strlen(), like so:

```<code>const char* string = "Ugh, strlen is tedious";
libFunction(string, strlen(string));
</code>```

Trusting the user to pass properly terminated strings would lead to less safe, but more concise and (in my opinion) readable code:

```<code>libFunction("I hope there's a null-terminator there!");
</code>```

So, what's the sensible practice here? Make the API more complicated to use, but force the user to think of their input, or document the requirement for a null-terminated string and trust the caller?

答:
No. Strings are always null-terminated by definition, the string length is redundant.

Non-null-terminated character data should never be called a "string". Processing it (and throwing lengths around) should usually be encapsulated within a library, and not part of the API. Requiring the length as a parameter just to avoid single strlen() calls is likely Premature Optimization.

Trusting the caller of an API function is not unsafe; undefined behavior is perfectly ok if documented preconditions are not met.

Of course, a well-designed API shouldn't contain pitfalls and should make it easy to be used correctly. And this just means it should be as simple and straightforward as possible, avoiding redundancies and following the language's conventions.


问:
Should I use inheritance to differentiate objects even if they have the same fields?
Consider this simple class that models a real world mobile device:

///
///     Model that represents a device.
///
public class Device
{
    public DateTime CreationDate { get; set; }

    public bool Enabled { get; set; }

    ///
    ///     Gets or sets the device's hardware identifier.
    ///
    /// <remarks>Commonly filled with data like device's IMEI.</remarks>
    public string HardwareId { get; set; }

    public int Id { get; set; }

    public DateTime? LastCommunication { get; set; }
}
```

<p>Now suppose a new requirement arrived and I need to start differentiating a device by platform, like <code>Windows Phone</code>, <code>Android</code> and <code>iOS</code>. The most common option I think would be to create an enumeration class:</p>

<pre class="lang-cs prettyprint-override"><code>/// <summary>
///     Defines a type of device.
/// </summary>
enum PlatformType
{
    /// <summary>
    ///     Device is an Android.
    /// </summary>
    Android,

    /// <summary>
    ///     Device is an Windows platform.
    /// </summary>
    Windows,

    /// <summary>
    ///     Device is an iOS platform.
    /// </summary>
    Ios,
}
</code>```

and then add a new property to the device class:

public class Device
{
    ...

    public PlatformType Platform { get; set; }

    ...
}
```

<p>Another approach would be to create a inheritance hierarchy on the device class itself:</p>

<pre class="lang-cs prettyprint-override"><code>public class AndroidDevice : Device { }

public class IosDevice : Device { }

public class WindowsPhoneDevice : Device { }
</code>```

When should I choose one of those approaches over the other? Should I always choose the second one or is there a reason not to?

答:
Actually none of us can tell you the best way to implement your device type, since we don't know how you're going to (re)use your code. The problem is, that some devs will say, that you should use Device as interface, AbstractDeviceImpl as abstract class and Android, etc. as concrete class which would be nice, but do you need it?

I would say the best approach is to find it out on your own by using TDD. Use your code, see what happens. Try to find out your requirements, reading your tests. Do you want it to be prepared for OCP and very abstract? Or will there be no other devices so simply one device abstraction and 3 concrete classes are your friends?

As I think that there won't be more than those 3 devices, and assume that you only need the type for logging/debugging, I would create a class Device implementing type as read-only string unknown as default. Then create 3 inner classes inheriting Device overriding the type-getter with the corresponding name.

As a matter of fact, using an enum in that way you described it above, is mostly bad OCP violation ending in switch blocks and/or if statements. Adding a new device means, changing the enum and adding a class. That's actually not what an OOP wants. You can always use enums if you need the value itself, but to distinguish between execution paths, enum with more than two elements might produce ugly code.


问:
What's the idea behind naming classes with "Info" suffix, for example: "SomeClass" and "SomeClassInfo"?
I'm working in a project which deals with physical devices, and I've been confused as how to properly name some classes in this project.

Considering the actual devices (sensors and receivers) are one thing, and their representation in software is another, I am thinking about naming some classes with the "Info" suffix name pattern.

For example, while a Sensor would be a class to represent the actual sensor (when it is actually connected to some working device), SensorInfo would be used to represent only the characteristics of such sensor. For example, upon file save, I would serialize a SensorInfo to the file header, instead of serializing a Sensor, which sort of wouldn't even make sense.

But now I am confused, because there is a middleground on objects' lifecycle where I cannot decide if I should use one or another, or how to get one from another, or even whether both variants should actually be collapsed to only one class.

Also, the all too common example Employee class obviously is just a representation of the real person, but nobody would suggest to name the class EmployeeInfo instead, as far as I know.

The language I am working with is .NET, and this naming pattern seems to be common throughout the framework, for exemple with these classes:

Directory and DirectoryInfo classes;

File and FileInfo classes;

ConnectionInfoclass (with no correspondent Connection class);

DeviceInfo class (with no correspondent Device class);

So my question is: is there a common rationale about using this naming pattern? Are there cases where it makes sense to have pairs of names (Thing and ThingInfo) and other cases where there should only exist the ThingInfo class, or the Thing class, without its counterpart?

答:
Considering the actual devices (sensors and receivers) are one thing, and their representation in software is another, I am thinking about naming some classes with the "Info" suffix name pattern.

For example, while a Sensor would be a class to represent the actual sensor (when it is actually connected to some working device), SensorInfo would be used to represent only the characteristics of such sensor. For example, upon file save, I would serialize a SensorInfo to the file header, instead of serializing a Sensor, which sort of wouldn't even make sense.

I don't like this distinction.  All objects are "representation[s] in software."  That's what the word "object" means.

Now, it might make sense to separate information about a peripheral from the actual code that interfaces with the peripheral.  So, for instance, a Sensor has-a SensorInfo, which contains most of the instance variables, along with some methods that don't require hardware, while the Sensor class is responsible for actually interacting with the physical sensor.  You don't have-a Sensor unless your computer has a sensor, but you could plausibly have-a SensorInfo.

The trouble is that this kind of design can be generalized to (almost) any class.  So you have to be careful.  You obviously wouldn't have a SensorInfoInfo class, for example.  And if you have a Sensor variable, you may find yourself violating the law of Demeter by interacting with its SensorInfo member.  None of this is fatal, of course, but API design isn't just for library authors.  If you keep your own API clean and simple, your code will be more maintainable.

Filesystem resources like directories, in my opinion, are very close to this edge.  There are some situations in which you want to describe a directory which is not locally accessible, true, but the average developer is probably not in one of those situations.  Complicating the class structure in this fashion is, in my opinion, unhelpful.  Contrast Python's approach in pathlib: There is a single class which "is most likely what you need" and various auxiliary classes which most developers can safely ignore.  If you really need them, however, they provide largely the same interface, just with concrete methods stripped out.


问:
Handling my antiquated coworker
I'm a fairly young programmer, and I work at a medium sized company's IT department. I have a coworker, and he is a really good Visual Basic 6 programmer. And I mean really good. Honestly. He can deliver working applications, containing very few bugs, in the time I need to get my first cup of coffee, and boot my machine. He is just that good.

Thing is, we are working with a team, and his working style is completely antiquated. He doesn't believe in versioning software (if you just make sure your code is correct, you don't need all that nonsense). Doesn't believe in deployment (I can deliver a working executable. How that is deployed is for the sysadmins to figure out). Doesn't believe in abstraction. ('if you want to create a subroutine, go ahead, but don't call any subroutines from that subroutine. It gets messy that way, and the code is hard to follow. This way every one can follow every step on the way.' or 'yeah, sure you can use that library to do that for you, but that way you don't really understand what's going on') and certainly doesn't believe in OOP. (we work in VB.net)

He is so good in what he does, he can deliver applications way faster than I can. But it just doesn't work in a team. Our other team member is quiet, and doesn't like to speak out, though he tends to agree. Our manager thinks I make valid points, but is not a programmer.

I have a really hard time maintaining programs he has written, and it doesn't make for a good team atmosphere. What do you think is the best thing for me to do?

答:
I'd talk to others to get a broader picture of how things look where you are.  Perhaps there are some separations there so that his code doesn't have to mix too much with others as there is the potential to segregate him into his own area for one way that this could be handled though this is more for a higher up like a director or CIO to make rather than a developer.

You may want to talk with him to see what kind of larger systems has he built as there are some big enterprise systems that tend to be a lot of building blocks where spaghetti code can run into the land of, "Oh, that is why OOP can be good!" though this does sometimes take the case where it proves quite useful to see how this can be a useful thing to have in one's toolbox.

Apathy may be another suspect to see if that is why he'd reject some things that I'd consider close to fundamental in terms of how I tend to design code but then maybe I've had too much of the Kool-aid.

Title: Handling my antiquated coworker

ContentLicense: CC BY-SA 2.5


答:
I would say that context/domain matters, since we have high level business logic code and low level models, architecture components and so on...

'Info', 'Data', 'Manager', 'Object', 'Class', 'Model', 'Controller' etc. can be smelly suffixes, especially on a lower level, since every object has some information or data, so that information is not necessary.

Class names of the business domain should be like all stakeholder talk about it, no matter if it sounds weird or is not 100% correct language.

Good suffixes for data structures are e.g 'List', 'Map' and for hinting patterns 'Decorator', 'Adapter' if you think it's necessary.

To your sensor scenario, I would not expect SensorInfo to save what your sensor is, but SensorSpec. Info imho is more a derived information, like FileInfo is something like the size, you don't save or the filepath which is built from the path and the filename, etc.

Another point:

There are only two hard things in Computer Science: cache invalidation and naming things.

-- Phil Karlton

That always reminds me of thinking about a name just for a few seconds and if I didn't find any, I use weird names and 'TODO'-mark them. I can always change it later since my IDE provides refactoring support. It's not a company slogan which must be good, but just some code we can change every time we want. Keep that in mind.

Title: What's the idea behind naming classes with "Info" suffix, for example: "SomeClass" and "SomeClassInfo"?

Body:
I'm working in a project which deals with physical devices, and I've been confused as how to properly name some classes in this project.

Considering the actual devices (sensors and receivers) are one thing, and their representation in software is another, I am thinking about naming some classes with the "Info" suffix name pattern.

For example, while a Sensor would be a class to represent the actual sensor (when it is actually connected to some working device), SensorInfo would be used to represent only the characteristics of such sensor. For example, upon file save, I would serialize a SensorInfo to the file header, instead of serializing a Sensor, which sort of wouldn't even make sense.

But now I am confused, because there is a middleground on objects' lifecycle where I cannot decide if I should use one or another, or how to get one from another, or even whether both variants should actually be collapsed to only one class.

Also, the all too common example Employee class obviously is just a representation of the real person, but nobody would suggest to name the class EmployeeInfo instead, as far as I know.

The language I am working with is .NET, and this naming pattern seems to be common throughout the framework, for exemple with these classes:

Directory and DirectoryInfo classes;

File and FileInfo classes;

ConnectionInfoclass (with no correspondent Connection class);

DeviceInfo class (with no correspondent Device class);

So my question is: is there a common rationale about using this naming pattern? Are there cases where it makes sense to have pairs of names (Thing and ThingInfo) and other cases where there should only exist the ThingInfo class, or the Thing class, without its counterpart?


问:
Compiling and deploying a C program to an MCU running an RTOS
Please note: Even though I'm specifically talking about an RTOS called Embox here, and even though I'm talking about AVR/ARm, I think this question can be answered by anybody whose ever done a fair amount of C-based MCU programming.

Say I have an MCU running Embox on it. Now, I'd like to write 2 executables, and 1 static library (used by both programs) in C and deploy all three artifacts to the MCU/RTOS. I have a few very-similarly-related questions/concerns (hence my choice to make this one question instead of 4):

What formats of executables and libraries does Embox require, and how can I tell? EXE/SO?

How does one compile a C program into an executable/library format (again, perhaps EXE/SO) that is compatible with Embox? For instance, I'm on a Windows machine with GCC provided by MinGW. I don't think I'd be able to write a program for Linux and then deploy it to a Linux machine. I'd need a Linux machine for that. But if the machine I'm deploying to is a simple RTOS/MCU, how do I develop on one platform/architecture (Windows) and make binaries that are compatible on another?

How does one deploy the executables to the MCU such that the RTOS can run the 2 apps at startup?

How does a user interact with the RTOS? Shell/SSH/console?

答:
What formats of executables and libraries does Embox require, and how can I tell?

By reading the documentation. Note that some (most?) kernels designed for embedded use might not even support loading executables from files. They may require applications to be compiled-in to the kernel image.

[...] how do I develop on one platform/architecture (Windows) and make binaries that are compatible on another?

This is called cross-compilation. Essentially, you need to install what's called a "toolchain" that will produce binaries in a target system. Compiling for the host system is just a special case. gcc specificially is of course designed to allow installation of multiple toolchains in different paths on the same system.

How does one deploy the executables to the MCU such that the RTOS can run the 2 apps at startup?

As mentioned above, the applications may be expected to be compiled-in to the kernel. You may be restricted to a single main() that would have to fork() and exec() to start a concurrent processes. For many microcontrollers, even processes can't be supported properly; only some form of kernel data protection exists. Usually you get only threads.

How does a user interact with the RTOS? Shell/SSH/console?

Usually just buttons and LEDs, until you hook up something like SPI that would allow you to communicate with a computer. On some development boards, it is supported to have a basic serial connection through a debugging (and programming) USB port. But the protocols used are usually specific to the application. Essentially, you get to program your own "shell" to run on the MCU that handles the commands and writes the output.


问:
Making folder of a git repository a separate repository while preserving history
I have a generic git repository called Workspace and each project I have that isn't big enough to deserve its own repository is stored as a folder within it. One of my mini-projects is now big enough that I feel it should have its own repository. I could easily make this happen by just copying the latest revisions into their own repository and committing them, but this doesn't transfer any of the previous revisions or history to the new repository. Is there a way to take a subfolder of a repo and make it its own repo without losing history?

I'm also fine with answers that only work for GitHub in case that has special features.

答:
This is a common workflow; the Git team even added a command for it: git subtree will convert the directory into a submodule.

See this StackOverflow answer for more details: Detach subdirectory into separate Git repository: The Easy Way™.


答:
I wrote my own co-operative multi-threading library for ARM Cortex-M0.

It was barely a couple pages of code, and the first version of it didn't take longer than a day to write and debug.

The big advantage of roll-your-own is you know the code and you can port it to chips that the RTOS might not support. Also, you spend less time thinking about questions like "will it crash I try to use features A and B simultaneously?" Since you wrote the code, you know the answer.

Threading is the main thing you get from an RTOS, and it turns out to be not such a big deal to implement yourself. It's rare that you need a lot of the features of an RTOS. But if you crunch your requirements and it turns out you do, then use an RTOS.

Title: Benefits of RTOS vs Bare Metal for MCU Programming?

Body:
Please note: This question specifically mentions two RTOSes but is more generic and can probably be answered by anybody who has written C code for embedded RTOSes before, and had their software run directly on MCUs.

I am interested in learning more about embedded RTOSes and writing applications for them. I am currently looking at Embox and RIOT because they're open source, modern, active and seem to have excellent documentation. My goal has two phases: Phase 1 is to figure out how to compile and flash these OSes to an MCU (probably AVR or ARM). Phase 2 is to then write a simple C program (basically a headless daemon), that would evolve over time as a "hobby app". I would then flash/deploy this program to the same MCU, thereby successfully deploying an appstack consisting of Embox/RIOT and my app residing on top of it.

Before I go down any roads that ultimately lead to dead ends, I stumbled across this article that does a pretty good job of explaining why real-time apps, written in C/assembler and flashed to MCUs, don't really need RTOSes underneath them.

So now I'm really confused, and am questioning some of my fundamental understanding of computing theory. I guess I'm trying to make the decision of whether or not to even use Embox/RIOT in the first place, either:

Stay the course and go with an "app stack" on the MCU of both OS + app; or

Heed the article's warning and just go with an MCU running my app "bare metal"

Obviously, the former is more work, and so there had better be a good reason/payoff for going that route. So I ask: what are the real benefits these (and similar) embedded RTOSes offer to MCU/C app developers? What specific features could my C app benefit from (perhaps by not reinventing the wheel?) by using an RTOS? What is lost by ditching the RTOS and going bare metal?

I'm asking for concrete examples here, not the media hype you get when you go to the wikipedia entry for RTOSes ;-)


答:
Don't try to change your colleague. You are describing him as someone able to deliver working software. It's probably too late to integrate it in the team either.

So you have two choices:

Adapt yourself. Maybe with time you will be able to convince him of the utility of a source control system? You will have to increase your circle of influence. The more resistant to change he is, the more time you will need.

Remove yourself from the team. You have lot of points to justify this. Maybe you should leave it maintain its own applications alone, and dedicate yourself on new stuff.

Remove yourself from the company. Sometimes, this is the only solution.

Title: Handling my antiquated coworker

Body:
I'm a fairly young programmer, and I work at a medium sized company's IT department. I have a coworker, and he is a really good Visual Basic 6 programmer. And I mean really good. Honestly. He can deliver working applications, containing very few bugs, in the time I need to get my first cup of coffee, and boot my machine. He is just that good.

Thing is, we are working with a team, and his working style is completely antiquated. He doesn't believe in versioning software (if you just make sure your code is correct, you don't need all that nonsense). Doesn't believe in deployment (I can deliver a working executable. How that is deployed is for the sysadmins to figure out). Doesn't believe in abstraction. ('if you want to create a subroutine, go ahead, but don't call any subroutines from that subroutine. It gets messy that way, and the code is hard to follow. This way every one can follow every step on the way.' or 'yeah, sure you can use that library to do that for you, but that way you don't really understand what's going on') and certainly doesn't believe in OOP. (we work in VB.net)

He is so good in what he does, he can deliver applications way faster than I can. But it just doesn't work in a team. Our other team member is quiet, and doesn't like to speak out, though he tends to agree. Our manager thinks I make valid points, but is not a programmer.

I have a really hard time maintaining programs he has written, and it doesn't make for a good team atmosphere. What do you think is the best thing for me to do?


问:
Is it bad to implement a language in other two languages?
Ok, so I have some understanding about parsers and compilers, at least the basics of how it works, and i've written a calculator and a really small toy language that compiles to another high-level language. Now if i want to write a complete language (by complete, i mean that it can be evaluated) is it bad to write the parser in some easy scripting language (like Python), convert it to my own "bytecode" and implement a small VM in C/C++?

I'm not exactly worried about performance right now, but if this is a "wrong way" to do it, i don't wanna waste my time. Also, all languages i've seen have been implemented in only one low-level language, like C, or they already have a self-hosting compiler. Is there any language compiler/interpreter implemented in this way?

答: I can't think of any downsides to this so long as your parser non parser sides are truly separate.  If you end up implementing the same things twice, in two different languages, that is problematic due to bugs when they likely don't always behave the same ways, as well as duplicated effort.  If that isn't going to happen, it seems like a fine idea and makes sense to use a parsing friendly language for the parsing and something else for the other stuff.  In a way, you can think of lexx and yac type utilities doing what you are doing. The parsing is done completely separate from the rest of it.  I say go for it, use the best tool for each job.</p>


答:
If your manager isn't a programmer try and put it in terms that he will understand.

We should use sourecontrol because if we don't we could have big problems recovering

It takes me x amount of time longer because he refuses to follow some fairly basic processes.

On the other hand, make sure you don't get too caught up in perfection i.e. this is a best practice we must follow it. It's likely your co-worker has a lot to add, you might just have to nudge him in the right direction slowly.

Title: Handling my antiquated coworker


问:
Compiling and deploying RTOS to an MCU
Please note: Even though I'm specifically talking about an RTOS called Embox here, and even though I'm talking about AVR/ARm, I think this question can be answered by anybody whose ever done a fair amount of C-based MCU programming.

I'm interested in building Embox locally on my machine and seeing if I can flash/deploy it to an AVR/ARM-based MCU. Unfortunately I'm on Windows 7, and so I had to install MinGW to get access to things like GCC (g++, make, etc.) I have written a simple "Hello World" C program and got it building successfully into a helloworld.exe executable.

I cloned Embox and followed their instructions for buildig their ARM-STM32_V1 template, but ran into a slew of errors that I'm still wading through. Don't worry, that's not my question here. What I am wondering, since I'm currently blocked, is much more basic and fundamental to the understanding of RTOSes and MCU programming:

What is the deployable unit(s) of Embox? That is, when its all said and done, what file(s) will I be flashing on to the MCU, effectively deploying the RTOS to it?

How do you deploy these files to an MCU? Can I assume SPI, UART, USART, JTAG, etc. are the usual suspects? How can I tell what approach is compatible with Embox and/or the MCU?

How do you configure the MCU to start Embox when the chip powers on? Or does that happen for you as a result of flashing the files to the MCU?

If someone could help answer these, I think I'll have a much better understanding of the "big picture" behind MCU-based programming.

答:
What is the deployable unit(s) of Embox?

As most of RTOS for MCU Embox offers deployable unit as a single image. For Embox It has ELF format and is placed in "./build/base/bin/embox" file.

How do you deploy these files to an MCU?

It depends on MCU not RTOS. The most popular hardware interface for loading images is JTAG. Here is an example how load image on STM32Discovery

How do you configure the MCU to start Embox when the chip powers on?

Starting procedure is also CPU dependently, but in common it can be presented as follow: When the chip powers on PC (program counter) is setup to 'start adress' and CPU begin executing the command.

Title: Compiling and deploying RTOS to an MCU


问:
How to draw sprint burndown chart?
In my company, there are 3 different development teams, newly started scrum. They mainly follow same path in doing scrum, but when it comes to sprint burndown chart, the act differently.

One team, gathered story points (with estimated points in them), broke them into tasks and estimated points for them too, i.e, a 10 point story may have 3 tasks with 4, 1 and 5 points estimated for them respectively. When they completed a task, they updated burndown chart respectively. The result, was a relatively smooth burndown chart, but in case of failed stories it was somehow deceptive; It showed progress that wasn't actually made for the end user.

On the opposite side, other teams didn't estimate points for tasks and just updated the burndown chart when a story fully completed. The result was a stair shape diagram: for some days team did no progress and suddenly made a big step.

The question is, what is the right way to make the burndown chart and which approach was closer to it?

答:
Personally i prefer the first way. It gives you a better sense of progress and the "work" done. Also many times the division into "User stories" is somewhat arbitrary. I prefer to see how much work was scheduled into the current sprint and how much was actually done.

But it doesn't matter. Each team should choose what suites them best. That's one of the most fundamental ideas behind agile: the team finds the best way to measure and manage itself.

I can also see the motivation behind the second way. They care less about the actual work done, and care more about how much functionality and features they completed for the users. This seems more fitting to short and simple stories and to a simple project from a technical standpoint.

Title: How to draw sprint burndown chart?


答:
Who is the audience for the burndown chart?

The second method, where you take credit after the completion of a story, is more in line with the ideas behind Scrum. There are several questions here on Software Engineering about dealing with incomplete stories (1, 2, 3, 4). A story, not a task, represents something of value to the user. If you take a step back and consider the sprint as a collection of stories and a commitment to deliver a certain amount of functionality, showing the burndown chart as indicating the completion of those stories is useful to the product owner and the user to show how close you are to meeting those commitments.

In the first method, where you take credit after the completion of a task, seems to be more useful for internal use, especially the Scrum Master and the project team. These are the people who think in terms of tasks and can use the information in this view as feedback to improve estimation and planning for sprints.

Consider using the right approach for the audience. If you aren't sure, ask them and discuss it. Although it comes from the lean approaches, eliminate waste. Produce the artifacts and have the ceremonies that you need to be effective and work as a team with the other stakeholders to decide what those artifacts and ceremonies are.

Title: How to draw sprint burndown chart?

Body:
In my company, there are 3 different development teams, newly started scrum. They mainly follow same path in doing scrum, but when it comes to sprint burndown chart, the act differently.

One team, gathered story points (with estimated points in them), broke them into tasks and estimated points for them too, i.e, a 10 point story may have 3 tasks with 4, 1 and 5 points estimated for them respectively. When they completed a task, they updated burndown chart respectively. The result, was a relatively smooth burndown chart, but in case of failed stories it was somehow deceptive; It showed progress that wasn't actually made for the end user.

On the opposite side, other teams didn't estimate points for tasks and just updated the burndown chart when a story fully completed. The result was a stair shape diagram: for some days team did no progress and suddenly made a big step.

The question is, what is the right way to make the burndown chart and which approach was closer to it?


答:
This sounds like one of those "He's a good guy but..." where you know the truth is coming.  And the truth sounds like he isn't really that good of an engineer.  Good software isn't just about working and development speed.  It's also about the other things you mentioned - maintainability, compatibility, abstraction (for future efficiency), etc.

So, that being said, it sounds like you have a problem developer on your hands.  What's worse for you is that he's proven and probably set in his ways. So what can you do?

Work around him.

Strive to produce your projects on as tight a schedule as he does.

And if you can't, produce a better result.

Over time those proven concepts which he dismisses will begin to pay off for you.

On the other hand, if you are forced to work his way, leave.

Title: Handling my antiquated coworker


问:
Are mocks in unit tests dangerous in dynamic languages?
I've started relying heavily on a mocking framework in php for my unit tests.

My concern is that with a dynamic language, there is no way of enforcing a return type. When mocking, you have to ensure that the return type of your mocked method is correct.

Take for example the following interface

```<code>interface MyInterface {

  /**
   * @return SomeObject
   */
   public function myMethod();

}
</code>```

If we are unit testing a class which requires an instance of MyInterface, we would mock the myMethod function to return a known SomeObject.

My concern is what happens if we accidentally have our mocked method return a different type of object, e.g. SomeOtherObject, and SomeOtherObject and SomeObject are not the same duck type (don't have the same methods). We'll now have code that is relying on havingSomeOtherObject, when all implementations ofMyInterfacemyMethodwill returnSomeObject`.

For example, we could write the following production code;

```<code>$someOtherObject = $myInterfaceImp->myMethod();
$newObj = new NewObject($someOtherObject);
</code>```

Hopefully the issue is obvious. We are passing what we think is SomeOtherObject into a constructor. Our tests will pass, but its very likely that in production we will get failures as myMethod() will actually be returning SomeObject. We then try passing this into the constructor, and get an error if there is a type check, or a non existent method is called.

Unless we write very detailed integration and acceptance tests using the real implementations (basically we'd have to ensure they covered all the testing we do an the unit level) we may not ever realise that we have an issue until we receive some runtime error in production.

Other than developer discipline, is there any way to mitigate the risk of incorrect mocks and implementations?

答:
You don't have to test for the correct return type in a dynamically-typed language, unless the method is specifically designed to return a specific type (i.e. a Factory).  Rely instead on other kinds of tests that are more meaningful from a program logic perspective.

To give a simple (and admittedly contrived) example, if I expected a method to return a long, but it returned an int instead, the returned value would be incorrect for any numeric result that is too large to fit in an int.

The whole point of using a dynamically-typed language is so that you don't have to think about types so much.  Otherwise, why would you trade off a strongly-typed language for a dynamically-typed one with type tests, when you could have let the compiler do all of that work for you automatically?

Most dynamically-typed languages have standard practices that you can use to minimize the risks.  For example, in Javascript, we use === instead of == to avoid unexpected type coercion during numeric comparisons, and use numbers scaled up to pennies in money calculations to avoid binary rounding errors (all numbers are floating point in Javascript).

Worth noting: Factory methods are less important in dynamically-typed languages than they are in staticly-typed ones.


答:
I'd say that mocks are dangerous in every language.

Let's say that I call:

```<code>priceCalculator.calculate(
    qty,
    item,
    isPlusCustomer,
    isSenior);
</code>```

What if:

isPlusCustomer and isSenior are supposed to be in the other order?

qty was supposed be a weight, not a qty.

you needed to initialize the priceCalculator first before using it?

There are lots of ways for mocks to fail to detect problems. Some subset of these are resolved by statically typed languages. But in general the problem remains.

There are two solutions that I'm aware one.

The first is contract tests. The idea here is that if you one test that says via mocks:

```<code>expect(priceCalculator.calculate(5, item, true, false)).returns(5.00);
</code>```

You need a contract test elsewhere that says:

```<code>assert(new PriceCalculator().calculate(5, item, true, false)).returns(5.00);
</code>```

So that every expectation you set has a matching test to ensure it actually works the way you claim it does.

The second is not to use mocks. Instead of mocking out the PriceCalculator, just use the real PriceCalculator. Instead of worrying about mocking the PriceCalculator correctly, you can actually test against the real PriceCalculator.

Title: Are mocks in unit tests dangerous in dynamic languages?

Body:
I've started relying heavily on a mocking framework in php for my unit tests.

My concern is that with a dynamic language, there is no way of enforcing a return type. When mocking, you have to ensure that the return type of your mocked method is correct.

Take for example the following interface

```<code>interface MyInterface {

  /**
   * @return SomeObject
   */
   public function myMethod();

}
</code>```

If we are unit testing a class which requires an instance of MyInterface, we would mock the myMethod function to return a known SomeObject.

My concern is what happens if we accidentally have our mocked method return a different type of object, e.g. SomeOtherObject, and SomeOtherObject and SomeObject are not the same duck type (don't have the same methods). We'll now have code that is relying on havingSomeOtherObject, when all implementations ofMyInterfacemyMethodwill returnSomeObject`.

For example, we could write the following production code;

```<code>$someOtherObject = $myInterfaceImp->myMethod();
$newObj = new NewObject($someOtherObject);
</code>```

Hopefully the issue is obvious. We are passing what we think is SomeOtherObject into a constructor. Our tests will pass, but its very likely that in production we will get failures as myMethod() will actually be returning SomeObject. We then try passing this into the constructor, and get an error if there is a type check, or a non existent method is called.

Unless we write very detailed integration and acceptance tests using the real implementations (basically we'd have to ensure they covered all the testing we do an the unit level) we may not ever realise that we have an issue until we receive some runtime error in production.

Other than developer discipline, is there any way to mitigate the risk of incorrect mocks and implementations?

Body:
I'd say that mocks are dangerous in every language.

Let's say that I call:

priceCalculator.calculate(
    qty,
    item,
    isPlusCustomer,
    isSenior);

What if:

isPlusCustomer and isSenior are supposed to be in the other order?

qty was supposed be a weight, not a qty.

you needed to initialize the priceCalculator first before using it?

There are lots of ways for mocks to fail to detect problems. Some subset of these are resolved by statically typed languages. But in general the problem remains.

There are two solutions that I'm aware one.

The first is contract tests. The idea here is that if you one test that says via mocks:

expect(priceCalculator.calculate(5, item, true, false)).returns(5.00);

You need a contract test elsewhere that says:

assert(new PriceCalculator().calculate(5, item, true, false)).returns(5.00);

So that every expectation you set has a matching test to ensure it actually works the way you claim it does.

The second is not to use mocks. Instead of mocking out the PriceCalculator, just use the real PriceCalculator. Instead of worrying about mocking the PriceCalculator correctly, you can actually test against the real PriceCalculator.


问:
Build automation vs deploy automation vs continuous integration
I want to become more efficient and I want to use ops tools efficiently.

With this in mind, I wanted to learn more about continuous integration, but it seems that there is many different things concerning it.

I m actually working with Jetbrains suits in my work (IntelliJ, WebStorm...), so I wanted to continue using them, and I wanted to use TeamCity which seemed to be a great tool with many plugins for continuous integration.

My problem is that I don't know what are the differences between:

building automation (TeamCity is this kind of software):
I know that we can build our application with a remote VCS repository and it's great, but what is the main aim of that ? What kind of information is important while doing this ? In fact, I already know if my software builds or not locally, and my teammates too. So, what is the aim of using it without deploying automation?

deploying automation (TeamCity doesn't seem to do it easily)

continuous integration (which seems to be a conjunction of the two above)

continuous delivery (what is this exactly? why it's different from continuous integration?)

Can you help me to understand a bit more this?

答:
Wikipedia gives pretty good summaries of most of these terms. Here is my take on them:

Build automation is automating how the software is built instead of manually invoking the compiler. This would be accomplished via tools such as e.g. Make or Ant.

Deployment automation is taking your built software and deploying or installing it on a test or production system.

Continuous integration means having an automated process build your software continuously as developers check in code, and run unit tests to ensure the code still works. For example, every 15 to 30 minutes a server might wake up, scan VCS for new check-ins, then update and build the project if any changes were made. In addition to performing compile steps, this is also a great opportunity to run automated unit tests and code quality checks.

Continuous delivery is a combination of all of the previous concepts where the software builds are also deployed to a test system, optionally with tests performed and reports generated.

At the very least, you need to have build automation, i.e. a build script of some sort. That allows you to click one button or issue one command to build your project. The benefit to this is reducing errors from manually running steps. Complex build environments might involve generating code (think DAOs from configs, interface code such as JAXB), compiling code, packaging it up, customizing metadata, etc. With a lot of stuff to do you need a checklist: why not make the checklist be your build script, and use a tool to run it? It reduces errors and provides consistency.

Next up is CI: this is really good to have but not strictly required. It helps identify build problems early. If you have multiple developers checking in code throughout the day and perhaps not syncing up their own workspaces constantly, there is a risk that their changes will interfere with each other. I am referring specifically to static code errors, not version control conflicts. A CI build server will mitigate this risk.

Finally we have the deployment steps. The idea here is to save time and reduce error from manually deploying software. Much like build automation, there are a hundred ways to screw up a software deployment. I have personally stayed late at the office to fix manual deployment problems on many occasions when we need a functioning system for customers coming on-site tomorrow. Automating multiple systems introduces more risk: instead of one system possibly crashing or having weird errors, we now have multiple systems that can go wrong. However, that risk is far lower than somebody missing a step on a checklist or issuing the wrong command and messing up a deployment. If you are lucky you can simply restore a DB backup and start over, if you are unlucky an error might cause the system to function incorrectly. Is it a software defect? Did the technician not set a configuration correctly? This takes time to diagnose, time that you may not have and time that need not be spent if you automate the process.


答:
Seems like you coworker have never developed in a team. That kind of solo guru kind of partner does not allow a good group dynamic.
So tell your superior about it and try to discuss pro and cons with your partner fevor doing it. If you could do it the nicer way great, but if he declines, go up in the cahin of command</p>

Title: Handling my antiquated coworker


问:
How to implement rounding in an all-purpose stack language using different types?
Disclaimer: If you are not terribly interested in numerics and mathematical processes, this is most likely nothing for you.

I am currently a bit stuck in a development process of a private project I followed for a long time and I think I need some input because I cannot decide how to do it best.
Unfortunately I must explain the problem a bit.

EDIT: This is NOT about rounding implementation. This is already done, both for float/doubles and arbitrary precision. You can assume I have enough knowledge about
numerics, rounding modes and floating-point problems, the problem is how to design rounding operators in a stack-based program.

I am interested in the reproducibility problem in numerical computations. Due to the immense power (billions of operations per second) and certain problems by the languages used for number crunching (C and FORTRAN), people cannot check what the machine is actually doing in contrast what the machine is supposedly doing (Deteoriation of language standards like indifference to qNaNs and sNaNs, allow to "optimize" a+(b+c) == (a+b)+c, x86 vs MME floating-point, silent FMA support etc. etc.). This view is shared by William Kahan, the designer of the x86 floating-point architecture.

So I worked on a stack-based language like FORTH which allows reproducible results. You have types: aggregates (Vector,Matrix,Tensor) and numbers (complex, reals). You put two space instances on the stack, execute an ADD, and you get the resulting sum. If the spaces were two floats, you get a float. If the spaces were two doubles, you get a double. If the two spaces were arbitrary precision numbers, you get an arbitrary precision number. The same with vectors and matrices.

My aching problem is rounding. If we exclude exact rationals, after division every higher operation (algebraic and transcendental operations) requires rounding. There are two rounding operations which are already implemented: place rounding, setting the exact position of the rounding (rounding down: 2.345 using 0 => 2 / 2.345 using -1 => 2.3) and significant digits rounding by setting the length of the result (rounding down: 2.345 using 1 = 2 / 2.345 using 2 = 2.3).

The approaches:

One ring to rule them all: Only one rounding setting for all available types. Problem: Some operations are exact and should be executed as such; arbitrary precision numbers offer exact addition and exact multiplication. If I define e.g. ADD_EXACT I include a keyword which is not implemented by most datatypes and will be therefore a normal ADD and the danger is that I (or others) forget to use ADD_EXACT when necessary. Another problem is that it is makes sense to use different rounding modes for some operations: place rounding for addition and significant digit rounding for multiplication. I fear to swamp the program with unnecessary switches to set the rounding mode.

Perhaps some more rings....: Several settable rounding modes. Allows adding and multiplication independently. Problem: Much more possibilities (set and retrieve rounding mode, rounding operation and rounding parameter). How many choices do I offer ? Only two and risking that if e.g. FMA cannot be supported or many more and risking to overwhelm the program with much too much rounding bureaucracy ?

Rounding is a crucial operation and once implemented, it cannot be changed easily. This must be solved as good as possible.

What I need is a simple and elegant model and I fear that I have worked so long on it that I simply do not see it and/or need a plan to find out the right solution. Help is very appreciated and I will update this post to clarify some aspects I may have forgotten.

EDIT:
Performance: Is not the design goal. It does not help you to get an incredibly fast wrong answer. It does not help you if two programmers on different machines get a different or (even similar) result if noone knows what is the right answer (or that even both are wrong). The goal of the program is exactly that: Find out when IEEE 754R precision will fail and find indicators and methods to validate numeric results. If you know that double precision and the tool will get you to the solution, by all means use C and FORTRAN.

答:
I couple of notes:

I don't understand your ADD_EXACT problem. If the operation is exact, don't round. Alternatively, if there has to be a rounding step (this includes most FPU operations), it must not introduce error.

FMA should probably be a completely separate operation from both addition and multiplication, since its rounding behavior is fundamentally different: It rounds only once. The two rounding steps of separate-multiply-add would have to be prescient to match FMA rounding, regardless of the exact rounding strategy.

The terms you use to talk about rounding worry me. It sounds like you're unaware of, or departing from, binary floating point and how rounding can actually vary in IEE-754 and in general (round to nearest even, round towards zero, round towards positive infinity, etc.).

You seem inexplicably focused on the aesthetic but largely inconsequential concern of how to name the digit to which one rounds. No mention of the actual rounding strategy (see above).

Design-wise, there should be a default rounding mode, with the option to explicitly use others. Whether to do this choice on an operation-by-operation basis, with a lexically scoped with_rounding mode { ... code ... } block, or dynamically scoped (i.e. set a global or thread-local variable that controls all rounding everywhere) is a very hard question. All options have severe drawbacks and I don't feel qualified to have an opinion on this.

You pitch your design as a potential alternative to FORTRAN, C, etc. for number crunching, but making performance competitive with (occasionally inaccurate) FPUs built in silicon is hard to impossible, and you don't seem worried about it. You will have to deal with binary, fixed-width floating point (i.e., IEEE-754) and the idiosyncrasies of its hardware implementations. (The essentially dynamic typing won't help either.)


问:
Application plugin system - interfaces - adding new features
Imagine I have an application, which have plugin system.

```<code>  public class MyPlugin : Plugin
  {
        public override ExecuteImpl (Context ctx)
        {
              // do something...
        }
  }
</code>```

Now I'm upgrading my application to version 2.0 with better plugin system.

Should I create Plugin2 type, and write adapter which allows to use Plugin as Plugin2,

or can I do something like this:

```<code>  public class MyPlugin : Plugin, IApiNewFeatures
  {
        public override ExecuteImpl (Context ctx)
        {
              // do something...
        }

        public void ExecuteNewApiFeatures () { ... }
  }
</code>```

And in my app:

```<code>  if (myPlugin is IApiNewFeatures) { ... }
</code>```

Is it good architecture? Adding new interfaces is easier I think, especially when application which uses that plugins belongs to someone else, and I dont want to bug his code.

答:
I don't think it is an "either or" question and you can avoid littering your code with

```<code>if (myPlugin is IApiNewFeatures) { ... }
</code>```

Steps:

Define IPlugin with (the essential parts of) the public interface of your current Plugin class.

Put IPlugin its own source file.

Move the Plugin class' source file to a different folder (namespace) so it isn't readily available anymore. Then change your current code to use IPlugin references (instead of Plugin references) and only provide Plugin descendants with access to the Plugin class' source file.

Do this before you start the new plugin system. This will ensure that your old code does not need to be changed unless it really requires functionality from the new plugin system.

For your new plugin system

Define IPlugin2.

Make it a descendant of IPlugin. Add the methods that support the new api features.

Create Plugin2, descending from Plugin and implementing IPlugin2.

Deriving Plugin2 from Plugin ensures that the IPlugin methods (which are part of IPlugin2 by inheritance) are already implemented. Implement the new IPlugin2 methods.

All your new code can work with IPlugin2 references and not pay attention to whether the behavior comes from the new or the old plugin system. After all an IPlugin2 reference is also an IPlugin reference.

Old code that needs functionality from the new plugin system can now simply be changed to use an IPlugin2 reference instead of an IPlugin one. The code using the methods from Plugin/IPlugin will still work - after all (I)Plugin2 is (I)Plugin - and new/changed code now has the new functionality at its fingertips as well.

Body:
I don't think it is an "either or" question and you can avoid littering your code with

if (myPlugin is IApiNewFeatures) { ... }

Steps:

Define IPlugin with (the essential parts of) the public interface of your current Plugin class.

Put IPlugin its own source file.

Move the Plugin class' source file to a different folder (namespace) so it isn't readily available anymore. Then change your current code to use IPlugin references (instead of Plugin references) and only provide Plugin descendants with access to the Plugin class' source file.

Do this before you start the new plugin system. This will ensure that your old code does not need to be changed unless it really requires functionality from the new plugin system.

For your new plugin system

Define IPlugin2.

Make it a descendant of IPlugin. Add the methods that support the new api features.

Create Plugin2, descending from Plugin and implementing IPlugin2.

Deriving Plugin2 from Plugin ensures that the IPlugin methods (which are part of IPlugin2 by inheritance) are already implemented. Implement the new IPlugin2 methods.

All your new code can work with IPlugin2 references and not pay attention to whether the behavior comes from the new or the old plugin system. After all an IPlugin2 reference is also an IPlugin reference.

Old code that needs functionality from the new plugin system can now simply be changed to use an IPlugin2 reference instead of an IPlugin one. The code using the methods from Plugin/IPlugin will still work - after all (I)Plugin2 is (I)Plugin - and new/changed code now has the new functionality at its fingertips as well.


问:
node deep file indexer module cannot go deep
I'm trying to make a file indexer by node.js. The program is supposed to index files and folders in an array and also check inside folders and add all sub folders and files

I wrote:

```<code>fs.readdir(__dirname,index);

function index(err,data){
 for (i in data){
        if(fs.statSync(data[i]).isDirectory()){
            j.folders.push(path.resolve(data[i]));
            fs.readdir(data[i],index);
        }
        else{
            j.files.push(path.resolve(data[i]));
        }
    }
}
</code>```

... this code, but when it passes inside a folder it gives traceback and stops executing.
here my question is how I index files and solve this issue.

ps. please don't comment about walk, I want to write my own module.

答:
An issue with readdir is that it passes in only the filename, without the full path, to the data variable in your index function.  Let's say you are calling the script from C:\main.  The contents of C:\main are

C:\main
C:\main\folder1
C:\main\folder1\subDir1

Once your program enters folder1 and reads subDir1, it will try to call readdir with data[i] = 'subDir1'.  But since the current working directory hasn't changed, which is still C:\main, readdir joins this to its path argument, resulting in C:\main\subDir1, which doesn't exist.

To handle this, we can track the directory that was sent in to readdir, which is asynchronous.  This means that the directory needs to be defined in the callback function before it is invoked.

```<code>var fs = require('fs');
var path = require('path');
var files = [];
var folders = [];

indexDir(__dirname);

function indexDir(d) {fs.readdir(d, function (err,data){
 for (i in data){
        console.log(path.join(d, data[i]));
        if(fs.statSync(path.join(d, data[i])).isDirectory()){
            folders.push(path.resolve(path.join(d, data[i])));
            indexDir(path.join(d, data[i]));
        }
        else{
            files.push(path.resolve(path.join(d, data[i])));
        }
    }
})}
</code>```

If we want to see the results once the directory has been completely traversed, then it might be easier to just use readdirSync, since it is synchronous and will block until all the directories have been visited.  Otherwise, if we want to keep things asynchronous, we can call another function when everything is done by keeping track of the number of asynchronous calls.

```<code>var fs = require('fs');
var path = require('path');
var files = [];
var folders = [];
var calls = 0;
indexDir(__dirname);

function indexDir(d) {
 calls++;
 fs.readdir(d, function (err,data){
   calls--;
   for (i in data){
          if(fs.statSync(path.join(d, data[i])).isDirectory()){
              folders.push(path.resolve(path.join(d, data[i])));
              indexDir(path.join(d, data[i]));
          }
          else{
              files.push(path.resolve(path.join(d, data[i])));
          }
      }
   if (calls == 0){
     present();
   }
 })}

function present(){
 for (i in files){
        console.log(files[i]);
    }
 for (i in folders){
        console.log(folders[i]);
    }
 }
</code>```

Body:
An issue with readdir is that it passes in only the filename, without the full path, to the data variable in your index function.  Let's say you are calling the script from C:\main.  The contents of C:\main are

C:\main
C:\main\folder1
C:\main\folder1\subDir1

Once your program enters folder1 and reads subDir1, it will try to call readdir with data[i] = 'subDir1'.  But since the current working directory hasn't changed, which is still C:\main, readdir joins this to its path argument, resulting in C:\main\subDir1, which doesn't exist.

To handle this, we can track the directory that was sent in to readdir, which is asynchronous.  This means that the directory needs to be defined in the callback function before it is invoked.

var fs = require('fs');
var path = require('path');
var files = [];
var folders = [];

indexDir(__dirname);

function indexDir(d) {fs.readdir(d, function (err,data){
 for (i in data){
        console.log(path.join(d, data[i]));
        if(fs.statSync(path.join(d, data[i])).isDirectory()){
            folders.push(path.resolve(path.join(d, data[i])));
            indexDir(path.join(d, data[i]));
        }
        else{
            files.push(path.resolve(path.join(d, data[i])));
        }
    }
})}

If we want to see the results once the directory has been completely traversed, then it might be easier to just use readdirSync, since it is synchronous and will block until all the directories have been visited.  Otherwise, if we want to keep things asynchronous, we can call another function when everything is done by keeping track of the number of asynchronous calls.

var fs = require('fs');
var path = require('path');
var files = [];
var folders = [];
var calls = 0;
indexDir(__dirname);

function indexDir(d) {
 calls++;
 fs.readdir(d, function (err,data){
   calls--;
   for (i in data){
          if(fs.statSync(path.join(d, data[i])).isDirectory()){
              folders.push(path.resolve(path.join(d, data[i])));
              indexDir(path.join(d, data[i]));
          }
          else{
              files.push(path.resolve(path.join(d, data[i])));
          }
      }
   if (calls == 0){
     present();
   }
 })}

function present(){
 for (i in files){
        console.log(files[i]);
    }
 for (i in folders){
        console.log(folders[i]);
    }
 }


问:
Do you have any team guidelines regarding exceptions?
My team recently inherited a project from a team where the amount of developers dropped so low they had to offload some work. One of the projects we inherited was a project littered with nested code, and awful exception handling (Exceptions were in effect handled as goto statements and thus used as a part of the normal program flow.).

All in all it was a hairy code ball someone had been coughing up for a few years.

Now we've been having a few team guidelines in place for quite some time, but all of the regards to the structures of objects, coding styles and what not. But we haven't covered exception handling.

So I'm wondering if you have any guidelines in your teams regarding exception handling, and if so how you enforce them?

答:
I feel sorry for you that you had to inherit code from people who abuse exceptions to be goto-like statements.

I always attempt to catch them when any user input or something beyond my control can happen (ex: IOExceptions), but anything that could be a coding error (ex: NullPointerException) is something I'd try to catch with asserts early in development.

The performance hit from that kind of coding is a huge negative. I wonder if the company was shrinking due to terrible developers getting themselves into a mess beyond understanding...


答:
Before I start I will add come context to question to highlight the problem. Consider:

```<code>class SUT {
  public function tested(MyInterface $x) {
    $this->hidden($x->myMethod());
  }
  protected function hidden($x) {
    $x->aMethodOfSomeObject()
  }
}

//Somewhere in test:
$sutInstance($myInterfaceMock);
</code>```

Now. Your MyInterface::MyMethod returns SomeObject and your test do its job. But
when you change MyInterface::MyMethod to return SomeOtherObject then your test will still pass (false positive with is wrong)

And there is even worse: if you remove MyMethod from MyInterface then this test will still get pass.

Bad news:

You can't do much about it in your test code.

It must be done on mocking framework level.

I checked PHPUnit and there is a task for mocking non existing methods. It was created in 2010 and still not closed (so from my point of view creators of PHPUnit are not interested in creating this crutial functionality).

Good news:

You can contribute to PHPUnit or whatever you use and fix these problems.
Long time ago when I wasn't overworked I created small mocking library and I tried to solve these problems ( https://github.com/farafiri/Smock ).

The way I did it was parsing PHPDoc and searching for @return annotation.
Every time when mocked method (in this case MyInstace::MyMethod) was called, returned type was checked aganist type from annotation.

In your example, after change $mock->MyMethod result (SomeObject) is type tested (type from annotation is SomeOtherObject) and since SomeObject is not instance of SomeOtherObject test fails. (Example: mocked method returns string when @return integer is defined in method annotation: https://github.com/farafiri/Smock/blob/master/tests/MockTest.php line 1242)

You can try deffensive programing. Check all arguments in methods if the are correct types.

Still, your test will say nothing, but it blow up sooner

(maybe during developer work, testers will find it or behavoiural test will let you know if you use any) and less likely it will blow up in end user face.

Use type hinting whenever possible. During development it will be much easier to find methods (and their test) which you should check.

Improve your testing tools. This is elaboration on my prevoius idea from "Good new" part. You have to invest some time for this and only if you are using annotations for return value (and I belive this is the case). In case of PHPUnit you can replace

```<code>$myInterfaceMock->expects($this->any())
    ->method('myMethod')
    ->will($this->returnValue($someObjectMock));
//with
$myInterfaceMock->expects($this->any())
    ->method('myMethod')
    ->will($this->myReturnValue($someObjectMock, 'MyInterface', 'MyMethod'));

//and in your test class:

protected function myReturnValue($value, $class, $method) {
    if (!checkMethodExists($class, $method)) {
        throw BadTestException();
    }

    $expectedType = getExpectedType($class, $method);

    if (!isTypeOf($value, $expectedType) {
        throw BadTestException();
    }

    return $value;
}
</code>```

Using ready annotation readers implementation for 98% most common scenarios should take you about 2 days.

Extending it for more PHPUnit methods like returnCallback or onConsecutiveCalls and so on should take 1 more day.

Do not rely on mocks to much. Use real object instead of mocks whenever it is possible.
If you would create real $myInstanceObject whitch creates SomeOtherObject instead of SomeObject expected by tested method, test would fail.

I think this problem is a bit beyond unit testing domain. This kind of errors should be handled on functional or behavioural tests level.

Body:
Before I start I will add come context to question to highlight the problem. Consider:

class SUT {
  public function tested(MyInterface $x) {
    $this->hidden($x->myMethod());
  }
  protected function hidden($x) {
    $x->aMethodOfSomeObject()
  }
}

//Somewhere in test:
$sutInstance($myInterfaceMock);

Now. Your MyInterface::MyMethod returns SomeObject and your test do its job. But
when you change MyInterface::MyMethod to return SomeOtherObject then your test will still pass (false positive with is wrong)

And there is even worse: if you remove MyMethod from MyInterface then this test will still get pass.

Bad news:

You can't do much about it in your test code.

It must be done on mocking framework level.

I checked PHPUnit and there is a task for mocking non existing methods. It was created in 2010 and still not closed (so from my point of view creators of PHPUnit are not interested in creating this crutial functionality).

Good news:

You can contribute to PHPUnit or whatever you use and fix these problems.
Long time ago when I wasn't overworked I created small mocking library and I tried to solve these problems ( https://github.com/farafiri/Smock ).

The way I did it was parsing PHPDoc and searching for @return annotation.
Every time when mocked method (in this case MyInstace::MyMethod) was called, returned type was checked aganist type from annotation.

In your example, after change $mock->MyMethod result (SomeObject) is type tested (type from annotation is SomeOtherObject) and since SomeObject is not instance of SomeOtherObject test fails. (Example: mocked method returns string when @return integer is defined in method annotation: https://github.com/farafiri/Smock/blob/master/tests/MockTest.php line 1242)

You can try deffensive programing. Check all arguments in methods if the are correct types.

Still, your test will say nothing, but it blow up sooner

(maybe during developer work, testers will find it or behavoiural test will let you know if you use any) and less likely it will blow up in end user face.

Use type hinting whenever possible. During development it will be much easier to find methods (and their test) which you should check.

Improve your testing tools. This is elaboration on my prevoius idea from "Good new" part. You have to invest some time for this and only if you are using annotations for return value (and I belive this is the case). In case of PHPUnit you can replace

$myInterfaceMock->expects($this->any())
    ->method('myMethod')
    ->will($this->returnValue($someObjectMock));
//with
$myInterfaceMock->expects($this->any())
    ->method('myMethod')
    ->will($this->myReturnValue($someObjectMock, 'MyInterface', 'MyMethod'));

//and in your test class:

protected function myReturnValue($value, $class, $method) {
    if (!checkMethodExists($class, $method)) {
        throw BadTestException();
    }

    $expectedType = getExpectedType($class, $method);

    if (!isTypeOf($value, $expectedType) {
        throw BadTestException();
    }

    return $value;
}

Using ready annotation readers implementation for 98% most common scenarios should take you about 2 days.

Extending it for more PHPUnit methods like returnCallback or onConsecutiveCalls and so on should take 1 more day.

Do not rely on mocks to much. Use real object instead of mocks whenever it is possible.
If you would create real $myInstanceObject whitch creates SomeOtherObject instead of SomeObject expected by tested method, test would fail.

I think this problem is a bit beyond unit testing domain. This kind of errors should be handled on functional or behavioural tests level.


问:
How can I implement an 'if' statement in an interpreter?
If I were writing a compiler (say for a stack-based VM), the code for an if statement:

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

Would be translated to the following psuedo-assembly:

```<code><evaluate expression and push result on stack>
JUMP-IF-TRUE label
<some_instructions>
:label
</code>```

This is easy to implement in a compiler, however I'm not sure how to implement this in an interpreter.

The difference between an interpreter and a compiler, is that a compiler outputs instructions to be performed later, and an interpreter performs right away.

So e.g. instead of outputting the instruction PUSH, an interpreter would simply PUSH on a stack it maintains. And so on.

So regarding JUMP instructions (such as the JUMP-IF-TRUE psuedo-instruction), I guess my question is how are these implemented in interpreters?

More accurately, how can I make an interpreter 'jump' over a piece of code, for example when interpreting an if statement?

答:
Any interpreter worth its salt does not "execute" the source code directly.  Rather, it executes some other internal representation of the source code, like an Abstract Syntax Tree (AST).

When your program is loaded, the parser makes a quick pass through the source code to turn the source into its corresponding internal form.  This can be done very quickly.  Once the source is in an AST, it will already contain jump instructions that point directly to specific addresses.  This alleviates the need to parse the source during execution until you find the target label for the jump.


答:
If your language is truly interpreted (i.e., it executes statements as encountered and doesn't convert the entire program into a data structure once at startup), there are two ways for the interpreter to handle conditions:

Explicit Jump.  Languages like BASIC that aren't much of a step up from assembly require that the program explicitly say where to go next:

```<code>10 REM 1970S-VINTAGE BASIC
20 IF A <> 5 THEN 40
30 PRINT "A IS 5"
40 PRINT "DOING THE NEXT THING"
</code>```

The THEN clause in line 20 is an explicit jump.  The hardware running assembly (well, machine code) would handle this by jumping to an address in memory; interpreted BASIC handles it by searching the program for the destination line number.

You can see this in action in the source code for Applesoft BASIC, where statements are tokenized as they're keyed in but execution still works as if they're being interpreted individually.  The IF statement (handled at address D9C9) evaluates the expression and, if true and the THEN clause is a line number, executes a GOTO (address D9E6).  The GOTO code (at D93E) searches ahead from the current line if the destination line is greater or from the top of the program if not.

Block Skip.  Languages with more structure put a restriction on direct jumps as part of an if statement by requiring that execution continue only in a forward direction* and that there be something to indicate that the end of the statements to be executed if true has been reached.  Some languages do this with block markers (e.g., BEGIN...END or {...}); others, like the Bourne shell, have a marker for identifying the end of the "true" block that's if-statement-specific:

```<code># Bourne Shell
if [ "$A" eq 5 ]
then
  echo "A was 5"
fi
echo "Doing the next thing"
</code>```

If the test result is false, the interpreter will expect and swallow a then statement and then continue reading lines without actually executing any of them until one that has some control significance to the if (anything but else, elsif and fi) is encountered.  Note that while modern versions of the Bourne shell will attempt to interpret the statements within the block for syntactical correctness, a naive implementation could simply ignore the contents until reaching an else, elsif or fi with no effect on how the program executes.

*Backwards is allowed using only language-provided looping constructs or the ever-frowned-upon goto.

Title: How can I implement an 'if' statement in an interpreter?

Body:
If I were writing a compiler (say for a stack-based VM), the code for an if statement:

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

Would be translated to the following psuedo-assembly:

```<code><evaluate expression and push result on stack>
JUMP-IF-TRUE label
<some_instructions>
:label
</code>```

This is easy to implement in a compiler, however I'm not sure how to implement this in an interpreter.

The difference between an interpreter and a compiler, is that a compiler outputs instructions to be performed later, and an interpreter performs right away.

So e.g. instead of outputting the instruction PUSH, an interpreter would simply PUSH on a stack it maintains. And so on.

So regarding JUMP instructions (such as the JUMP-IF-TRUE psuedo-instruction), I guess my question is how are these implemented in interpreters?

More accurately, how can I make an interpreter 'jump' over a piece of code, for example when interpreting an if statement?

Body:
If your language is truly interpreted (i.e., it executes statements as encountered and doesn't convert the entire program into a data structure once at startup), there are two ways for the interpreter to handle conditions:

Explicit Jump.  Languages like BASIC that aren't much of a step up from assembly require that the program explicitly say where to go next:

10 REM 1970S-VINTAGE BASIC
20 IF A <> 5 THEN 40
30 PRINT "A IS 5"
40 PRINT "DOING THE NEXT THING"

The THEN clause in line 20 is an explicit jump.  The hardware running assembly (well, machine code) would handle this by jumping to an address in memory; interpreted BASIC handles it by searching the program for the destination line number.

You can see this in action in the source code for Applesoft BASIC, where statements are tokenized as they're keyed in but execution still works as if they're being interpreted individually.  The IF statement (handled at address D9C9) evaluates the expression and, if true and the THEN clause is a line number, executes a GOTO (address D9E6).  The GOTO code (at D93E) searches ahead from the current line if the destination line is greater or from the top of the program if not.

Block Skip.  Languages with more structure put a restriction on direct jumps as part of an if statement by requiring that execution continue only in a forward direction* and that there be something to indicate that the end of the statements to be executed if true has been reached.  Some languages do this with block markers (e.g., BEGIN...END or {...}); others, like the Bourne shell, have a marker for identifying the end of the "true" block that's if-statement-specific:

# Bourne Shell
if [ "$A" eq 5 ]
then
  echo "A was 5"
fi
echo "Doing the next thing"

If the test result is false, the interpreter will expect and swallow a then statement and then continue reading lines without actually executing any of them until one that has some control significance to the if (anything but else, elsif and fi) is encountered.  Note that while modern versions of the Bourne shell will attempt to interpret the statements within the block for syntactical correctness, a naive implementation could simply ignore the contents until reaching an else, elsif or fi with no effect on how the program executes.

*Backwards is allowed using only language-provided looping constructs or the ever-frowned-upon goto.


问:
MVVM in Photoshop-like application: What object has the responsibility for composing the document?
I'm wondering how an application like Adobe Photoshop, could be architectured to conform to the C+M+V+VM design-pattern, specifically how do you handle the canvas?

There would be a Model system which represents the current document, with its layers (each containing raw pixel data, potentially gigabytes worth), effects applied to layers, and other information about the document state.

Then you would have the ViewModel for the Main Window which would have child-ViewModels for each tool-window, as well as a child-ViewModel for the main canvas area. My question relates to how the ViewModel would represent the current canvas data. It is the View's responsibility to draw the pixels of the composited document to the screen (or some virtual output device for tests), but who has responsibility to compose the document? Is it correct to even compose the document at all? - especially if the View is particularly advanced enough to have the capability to do that itself, such as hardware-accelerated Views. What if composition is done at the ViewModel layer on the GPU, the data would have to be passed back into main-memory and then copied again to the GPU for the View - the optimization of keeping the data in GPU memory cannot happen because the View and ViewModel should be ignorant of each other.

Is there a solution to this problem, or would a different design-pattern be appropriate?

答:
Seems like a viewmodel problem to me. In WPF (the MVVM framework I'm most familiar with), the view handles everything related to rendering and composing view elements in a domain agnostic way. It knows how to render a textbox, or draw a line across a canvas, but it doesnt know that this line is from layer 1 of my document. It knows lots of ways to draw lines, but it doesn't know anything about why. It doesn't know for instance that line one is connected to line 2 and when I move line 1, line 2 should come with it.

So in your example, everything having to do with the final rendering of the document is obviously the view. All the domain information - layers, applied effects etc - is the model. And everything else - all the adapter code to bend your model to fit a particular view - is the viewmodel. The viewmodel is concerned with: how do I prepare my model to be consumed by the view, and how do respond to events from the view.


答:
I'll be honest, you're not painting a good picture of him. Archaic methods, hard-to-maintain software, stubborn to new ways of working, against abstraction etc etc

From what you've said, if he is producing largely bug-free software FASTER than you are without use of reusable libraries and design patterns aimed at rapid application development then it says more about yourself, than him...

..about him..yeh, find a way to NOT work with him and NOT be associated with his work. Seems like he has a typical selfish attitude towards his work. You can't work with someone like that, you can only observe them work and tidy up after them (like you currently are).

Title: Handling my antiquated coworker