问:
Is wrapping a command-line tool (wget, curl) a "good" practice?
I have a background in .NET, specifically in C# WPF and ASP.Net, but now I am going to use more golang and C.
Consider the following situation as an example:

The software I should program should should basically upload data and present that upload-process using a GUI.
Each language used in production has usually (extern) classes/libraries that provide (Network)Stream-I/O, but it's lots of more work to program an abstract "Network-Framework" (because often you have to use TCP/IP-Sockets and other low-level stuff, which is a huge origin of complexity [when your company doesn't provide such functionality already]), adjusted to the needs of my program, than using curl.
The upload-function of my program could only wrap curl, a well tested and widely used and accepted tool for this purpose, which has lots of options.
I know that this "loss of control" is a huge disadvantage, but curl also offers data-output which I can use as communcation-interface between my program and this tool. When they are no acceptable libs out there, that offer such features, is it "legit" to use curl for a professional product?

答:
My take:

Reinventing the wheel is bad. Don't do it. We all know this.

Wrapping a command-line tool is always a bit ugly. Lack of useful integration, lack of flow control, having to worry about all sorts of quoting hell.

However in this case, there's a perfect solution: just use libcurl. It's what makes up the guts of curl anyway and you get to avoid all the nastiness of wrapping a command-line tool.


答:
Wrapping a command line app is not good or bad, its just a technique.

The 'good' vs 'bad' comes into play when you look at the alternative approaches.  Its less likely to be 'good', for example, if you are wrapping a command line executable when a more suitable library is available to you.  On the other hand, there's absolutely nothing wrong with wrapping the command line executable when that's the only available tool for what you are doing.

In your specific case, I'd be very surprised if there weren't many other options available to you beyond wrapping cURL.

ContentLicense: CC BY-SA 3.0

Title: Is wrapping a command-line tool (wget, curl) a "good" practice?

Body:
I have a background in .NET, specifically in C# WPF and ASP.Net, but now I am going to use more golang and C.
Consider the following situation as an example:

The software I should program should should basically upload data and present that upload-process using a GUI.
Each language used in production has usually (extern) classes/libraries that provide (Network)Stream-I/O, but it's lots of more work to program an abstract "Network-Framework" (because often you have to use TCP/IP-Sockets and other low-level stuff, which is a huge origin of complexity [when your company doesn't provide such functionality already]), adjusted to the needs of my program, than using curl.
The upload-function of my program could only wrap curl, a well tested and widely used and accepted tool for this purpose, which has lots of options.
I know that this "loss of control" is a huge disadvantage, but curl also offers data-output which I can use as communcation-interface between my program and this tool. When they are no acceptable libs out there, that offer such features, is it "legit" to use curl for a professional product?


答:
I think it's more a question of whether you want this functionality embedded in your software or not.  No matter how it shakes out, if the functionality is required you're going to end up with a "curl" somewhere.  But I'd caution you that there is complexity either way.

If "curl" is inside your software:

Then you need to code it up yourself and yeah that's a pain but libcurl is pretty damn solid as far a libs go and as long as your code builds you can rest easy that the user is good to go.

If "curl" is external to your software:

Then yes it's easier for you on the coding side but you have in a very real sense converted your low level programming work into system administration work since now you'll,

need to make sure your software can find curl on the system.  (Deployment into different environments gets complicated)

deal with users on systems that don't have curl installed. (How big a deal this is depends on your target platforms but you'll need to make sure people know how to install it if they don't have it already.)

(likely) need to create a general configuration system that allows the user to help the software find curl (or something equivalent) that allows your software to operate when curl is already present but the method you provided failed. A good config file setup can help here...

System administration and robust deployment into different environments can get complex (just like straight up coding) so to me it seems like there are advantages and disadvantages to both.

Choose your poison.


问:
Why are the sizes of programs so large?
If we look at the vintage program Netscape Navigator or an early version of Microsoft Word, those programs were less than 50 MB in size. Now when I install google chrome it is 200 MB and desktop version of Slack is 300 MB. I read about some rule that programs will take all available memory no matter how much it is but why?

Why are the current sizes of programs so large compared to 10 or 15 years ago? The programs are not doing significantly more functions and do not look very different. What is it that is the resource hog now?

答:
Libraries built on objects that are not optimized require more memory to load, install, and more computing cycles to operate.  Object code is for the most part bloat.

Just step through standard C++ code running to see all the assert()ed object calls to make sure they are valid objects.  When you design layer upon layer of objects encapsulating objects the underlayers are bloated and opaque. Programmers get lazy and take on more objects because it's faster than redesigning what is limited to the needed functionality. It's really that simple.

Consider the size of the Linux C kernel, just the kernel, versus the size of bespoke applications. The kernel can run the entire machine. But it wasn't built as quickly as applications, it takes time slowly to make the best functionality.

Title: Why are the sizes of programs so large?


问:
Logging asynchronously - how should it be done?
In many of the services I work on there are a lot of logging being done.
The services are WCF services (mostly) which use the .NET EventLogger class.

I'm in the process of improving these services' performance, and I got to think that logging asynchronously would benefit performance.

I'm unaware of what happens when multiple threads ask to log, and if it creates a bottleneck, but even if it doesn't I still think that it shouldn't interfere with the actual process being executed.

My thoughts are that I should invoke the same log method I call now but do so using a new thread, while continuing with the actual process.

Some questions about that:

Is it ok?

Are there any downsides?

Should it be done in a different way?

Maybe its so fast that it doesn't even worth the effort?

答:
Separate thread for I\O operation sounds reasonable.

For example, it would be not good to log which buttons user has pressed in the same UI thread. Such UI will hang at random and have slow perceived performance.

The solution is to decouple event from its processing.

Here is a lot of information about Producer-Consumer Problem and Event Queue from game development world

Often there is a code like

```<code>///Never do this!!!
public void WriteLog_Like_Bastard(string msg)
{
    lock (_lockBecauseILoveThreadContention)
    {
        File.WriteAllText("c:\\superApp.log", msg);
    }
}
</code>```

This approach will lead to Thread Contention. All processing threads will be fighting to be able to obtain lock and write to the same file at once.

Some may try to remove locks.

```<code>public void Log_Like_Dumbass(string msg)
{
      try
      {  File.Append("c:\\superApp.log", msg); }
        catch (Exception ex)
        {
            MessageBox.Show("Log file may be locked by other process...")
        }
      }
}
</code>```

It is not possible to predict the result if 2 threads will enter method at the same time.

So eventually developers will disable logging at all...

Is it possible to fix?

Yes.

Lets say we have interface:

```<code> public interface ILogger
 {
    void Debug(string message);
    // ... etc
    void Fatal(string message);
 }
</code>```

Instead of waiting for lock and performing blocking file operation every time when ILogger is called we will Add new LogMessage to the Penging Messages Queue and return to more important things:

```<code>public class AsyncLogger : ILogger
{
    private readonly BlockingCollection<LogMessage> _pendingMessages;
    private readonly Type _loggerFor;
    private readonly IThreadAdapter _threadAdapter;

    public AsyncLogger(BlockingCollection<LogMessage> pendingMessages, Type loggerFor, IThreadAdapter threadAdapter)
    {
        _pendingMessages = pendingMessages;
        _loggerFor = loggerFor;
        _threadAdapter = threadAdapter;
    }

    public void Debug(string message)
    {
        Push(LoggingLevel.Debug, message);
    }

    public void Fatal(string message)
    {
        Push(LoggingLevel.Fatal, message);
    }

    private void Push(LoggingLevel importance, string message)
    {
        // since we do not know when our log entry will be written to disk, remember current time
        var timestamp = DateTime.Now;
        var threadId = _threadAdapter.GetCurrentThreadId();

        // adds message to the queue in lock-free manner and immediately returns control to caller
        _pendingMessages.Add(LogMessage.Create(timestamp, importance, message, _loggerFor, threadId));
    }
}
</code>```

We have done with this simple  Asynchronous Logger.

Next step is to process incoming messages.

For the simplicity, lets start new Thread and wait forever until application exits or Asynchronous Logger will add new message to the Pending Queue.

```<code>public class LoggingQueueDispatcher : IQueueDispatcher
{
    private readonly BlockingCollection<LogMessage> _pendingMessages;
    private readonly IEnumerable<ILogListener> _listeners;
    private readonly IThreadAdapter _threadAdapter;
    private readonly ILogger _logger;
    private Thread _dispatcherThread;

    public LoggingQueueDispatcher(BlockingCollection<LogMessage> pendingMessages, IEnumerable<ILogListener> listeners, IThreadAdapter threadAdapter, ILogger logger)
    {
        _pendingMessages = pendingMessages;
        _listeners = listeners;
        _threadAdapter = threadAdapter;
        _logger = logger;
    }

    public void Start()
    {
        //  Here I use 'new' operator, only to simplify example. Should be using interface  '_threadAdapter.CreateBackgroundThread' to allow unit testing
        Thread thread = new Thread(MessageLoop);
        thread.Name = "LoggingQueueDispatcher Thread";
        thread.IsBackground = true;

        thread.Start();
        _logger.Debug("Asked to start log message Dispatcher ");

        _dispatcherThread = thread;
    }

    public bool WaitForCompletion(TimeSpan timeout)
    {
        return _dispatcherThread.Join(timeout);
    }

    private void MessageLoop()
    {
        _logger.Debug("Entering dispatcher message loop...");
        var cancellationToken = new CancellationTokenSource();
        LogMessage message;

        while (_pendingMessages.TryTake(out message, Timeout.Infinite, cancellationToken.Token))
        {
            // !!!!! Now it is safe to use File.AppendAllText("c:\\my.log") without ever using lock or forcing important threads to wait.
            // this is example, do not use in production
            foreach (var listener in _listeners)
            {
                listener.Log(message);
            }
        }

    }
}
</code>```

I'm passing chain of custom listeners. You may probably want to just send call logging framework (log4net, etc...)

Here is the rest of code:

```<code>public enum LoggingLevel
{
    Debug,
    // ... etc
    Fatal,
}

public class LogMessage
{
    public DateTime Timestamp { get; private set; }
    public LoggingLevel Importance { get; private set; }
    public string Message { get; private set; }
    public Type Source { get; private set; }
    public int ThreadId { get; private set; }

    private LogMessage(DateTime timestamp, LoggingLevel importance, string message, Type source, int threadId)
    {
        Timestamp = timestamp;
        Message = message;
        Source = source;
        ThreadId = threadId;
        Importance = importance;
    }

    public static LogMessage Create(DateTime timestamp, LoggingLevel importance, string message, Type source, int threadId)
    {
        return  new LogMessage(timestamp, importance, message, source, threadId);
    }

    public override string ToString()
    {
        return string.Format("{0}  [TID:{4}] {1:h:mm:ss} ({2})\t{3}", Importance, Timestamp, Source, Message, ThreadId);
    }
}

public class LoggerFactory : ILoggerFactory
{
    private readonly BlockingCollection<LogMessage> _pendingMessages;
    private readonly IThreadAdapter _threadAdapter;

    private readonly ConcurrentDictionary<Type, ILogger> _loggersCache = new ConcurrentDictionary<Type, ILogger>();

    public LoggerFactory(BlockingCollection<LogMessage> pendingMessages, IThreadAdapter threadAdapter)
    {
        _pendingMessages = pendingMessages;
        _threadAdapter = threadAdapter;
    }

    public ILogger For(Type loggerFor)
    {
        return _loggersCache.GetOrAdd(loggerFor, new AsyncLogger(_pendingMessages, loggerFor, _threadAdapter));
    }
}

public class ThreadAdapter : IThreadAdapter
{
    public int GetCurrentThreadId()
    {
        return Thread.CurrentThread.ManagedThreadId;
    }
}

public class ConsoleLogListener : ILogListener
{
    public void Log(LogMessage message)
    {
        Console.WriteLine(message.ToString());
        Debug.WriteLine(message.ToString());
    }
}

public class SimpleTextFileLogger : ILogListener
{
    private readonly IFileSystem _fileSystem;
    private readonly string _userRoamingPath;
    private readonly string _logFileName;
    private FileStream _fileStream;

    public SimpleTextFileLogger(IFileSystem fileSystem, string userRoamingPath, string logFileName)
    {
        _fileSystem = fileSystem;
        _userRoamingPath = userRoamingPath;
        _logFileName = logFileName;
    }

    public void Start()
    {
        _fileStream = new FileStream(_fileSystem.Path.Combine(_userRoamingPath, _logFileName), FileMode.Append);
    }

    public void Stop()
    {
        if (_fileStream != null)
        {
            _fileStream.Dispose();
        }
    }

    public void Log(LogMessage message)
    {
        var bytes = Encoding.UTF8.GetBytes(message.ToString() + Environment.NewLine);
        _fileStream.Write(bytes, 0, bytes.Length);
    }
}

public interface ILoggerFactory
{
    ILogger For(Type loggerFor);
}

public interface ILogListener
{
    void Log(LogMessage message);
}

public interface IThreadAdapter
{
    int GetCurrentThreadId();
}

public interface IQueueDispatcher
{
    void Start();
}
</code>```

Entry point:

```<code>public static class Program
{
    public static void Main()
    {
        Debug.WriteLine("[Program] Entering Main ...");

        var pendingLogQueue = new BlockingCollection<LogMessage>();

        var threadAdapter = new ThreadAdapter();
        var loggerFactory = new LoggerFactory(pendingLogQueue, threadAdapter);

        var fileSystem = new FileSystem();
        var userRoamingPath = GetUserDataDirectory(fileSystem);

        var simpleTextFileLogger = new SimpleTextFileLogger(fileSystem, userRoamingPath, "log.txt");
        simpleTextFileLogger.Start();
        ILogListener consoleListener = new ConsoleLogListener();
        ILogListener[] listeners = new [] { simpleTextFileLogger , consoleListener};

        var loggingQueueDispatcher = new LoggingQueueDispatcher(pendingLogQueue, listeners, threadAdapter, loggerFactory.For(typeof(LoggingQueueDispatcher)));
        loggingQueueDispatcher.Start();

        var logger = loggerFactory.For(typeof(Console));

        string line;
        while ((line = Console.ReadLine()) != "exit")
        {
            logger.Debug("you have entered: " + line);
        }

        logger.Fatal("Exiting...");

        Debug.WriteLine("[Program] pending LogQueue will be stopped now...");
        pendingLogQueue.CompleteAdding();
        var logQueueCompleted = loggingQueueDispatcher.WaitForCompletion(TimeSpan.FromSeconds(5));

        simpleTextFileLogger.Stop();
        Debug.WriteLine("[Program] Exiting... logQueueCompleted: " + logQueueCompleted);

    }

    private static string GetUserDataDirectory(FileSystem fileSystem)
    {
        var roamingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        var userDataDirectory = fileSystem.Path.Combine(roamingDirectory, "Async Logging Sample");
        if (!fileSystem.Directory.Exists(userDataDirectory))
            fileSystem.Directory.CreateDirectory(userDataDirectory);
        return userDataDirectory;
    }
}
</code>```

Body:
Separate thread for I\O operation sounds reasonable.

For example, it would be not good to log which buttons user has pressed in the same UI thread. Such UI will hang at random and have slow perceived performance.

The solution is to decouple event from its processing.

Here is a lot of information about Producer-Consumer Problem and Event Queue from game development world

Often there is a code like

///Never do this!!!
public void WriteLog_Like_Bastard(string msg)
{
    lock (_lockBecauseILoveThreadContention)
    {
        File.WriteAllText("c:\\superApp.log", msg);
    }
}

This approach will lead to Thread Contention. All processing threads will be fighting to be able to obtain lock and write to the same file at once.

Some may try to remove locks.

public void Log_Like_Dumbass(string msg)
{
      try
      {  File.Append("c:\\superApp.log", msg); }
        catch (Exception ex)
        {
            MessageBox.Show("Log file may be locked by other process...")
        }
      }
}

It is not possible to predict the result if 2 threads will enter method at the same time.

So eventually developers will disable logging at all...

Is it possible to fix?

Yes.

Lets say we have interface:

 public interface ILogger
 {
    void Debug(string message);
    // ... etc
    void Fatal(string message);
 }

Instead of waiting for lock and performing blocking file operation every time when ILogger is called we will Add new LogMessage to the Penging Messages Queue and return to more important things:

public class AsyncLogger : ILogger
{
    private readonly BlockingCollection<LogMessage> _pendingMessages;
    private readonly Type _loggerFor;
    private readonly IThreadAdapter _threadAdapter;

    public AsyncLogger(BlockingCollection<LogMessage> pendingMessages, Type loggerFor, IThreadAdapter threadAdapter)
    {
        _pendingMessages = pendingMessages;
        _loggerFor = loggerFor;
        _threadAdapter = threadAdapter;
    }

    public void Debug(string message)
    {
        Push(LoggingLevel.Debug, message);
    }

    public void Fatal(string message)
    {
        Push(LoggingLevel.Fatal, message);
    }

    private void Push(LoggingLevel importance, string message)
    {
        // since we do not know when our log entry will be written to disk, remember current time
        var timestamp = DateTime.Now;
        var threadId = _threadAdapter.GetCurrentThreadId();

        // adds message to the queue in lock-free manner and immediately returns control to caller
        _pendingMessages.Add(LogMessage.Create(timestamp, importance, message, _loggerFor, threadId));
    }
}

We have done with this simple  Asynchronous Logger.

Next step is to process incoming messages.

For the simplicity, lets start new Thread and wait forever until application exits or Asynchronous Logger will add new message to the Pending Queue.

public class LoggingQueueDispatcher : IQueueDispatcher
{
    private readonly BlockingCollection<LogMessage> _pendingMessages;
    private readonly IEnumerable<ILogListener> _listeners;
    private readonly IThreadAdapter _threadAdapter;
    private readonly ILogger _logger;
    private Thread _dispatcherThread;

    public LoggingQueueDispatcher(BlockingCollection<LogMessage> pendingMessages, IEnumerable<ILogListener> listeners, IThreadAdapter threadAdapter, ILogger logger)
    {
        _pendingMessages = pendingMessages;
        _listeners = listeners;
        _threadAdapter = threadAdapter;
        _logger = logger;
    }

    public void Start()
    {
        //  Here I use 'new' operator, only to simplify example. Should be using interface  '_threadAdapter.CreateBackgroundThread' to allow unit testing
        Thread thread = new Thread(MessageLoop);
        thread.Name = "LoggingQueueDispatcher Thread";
        thread.IsBackground = true;

        thread.Start();
        _logger.Debug("Asked to start log message Dispatcher ");

        _dispatcherThread = thread;
    }

    public bool WaitForCompletion(TimeSpan timeout)
    {
        return _dispatcherThread.Join(timeout);
    }

    private void MessageLoop()
    {
        _logger.Debug("Entering dispatcher message loop...");
        var cancellationToken = new CancellationTokenSource();
        LogMessage message;

        while (_pendingMessages.TryTake(out message, Timeout.Infinite, cancellationToken.Token))
        {
            // !!!!! Now it is safe to use File.AppendAllText("c:\\my.log") without ever using lock or forcing important threads to wait.
            // this is example, do not use in production
            foreach (var listener in _listeners)
            {
                listener.Log(message);
            }
        }

    }
}

I'm passing chain of custom listeners. You may probably want to just send call logging framework (log4net, etc...)

Here is the rest of code:

public enum LoggingLevel
{
    Debug,
    // ... etc
    Fatal,
}

public class LogMessage
{
    public DateTime Timestamp { get; private set; }
    public LoggingLevel Importance { get; private set; }
    public string Message { get; private set; }
    public Type Source { get; private set; }
    public int ThreadId { get; private set; }

    private LogMessage(DateTime timestamp, LoggingLevel importance, string message, Type source, int threadId)
    {
        Timestamp = timestamp;
        Message = message;
        Source = source;
        ThreadId = threadId;
        Importance = importance;
    }

    public static LogMessage Create(DateTime timestamp, LoggingLevel importance, string message, Type source, int threadId)
    {
        return  new LogMessage(timestamp, importance, message, source, threadId);
    }

    public override string ToString()
    {
        return string.Format("{0}  [TID:{4}] {1:h:mm:ss} ({2})\t{3}", Importance, Timestamp, Source, Message, ThreadId);
    }
}

public class LoggerFactory : ILoggerFactory
{
    private readonly BlockingCollection<LogMessage> _pendingMessages;
    private readonly IThreadAdapter _threadAdapter;

    private readonly ConcurrentDictionary<Type, ILogger> _loggersCache = new ConcurrentDictionary<Type, ILogger>();

    public LoggerFactory(BlockingCollection<LogMessage> pendingMessages, IThreadAdapter threadAdapter)
    {
        _pendingMessages = pendingMessages;
        _threadAdapter = threadAdapter;
    }

    public ILogger For(Type loggerFor)
    {
        return _loggersCache.GetOrAdd(loggerFor, new AsyncLogger(_pendingMessages, loggerFor, _threadAdapter));
    }
}

public class ThreadAdapter : IThreadAdapter
{
    public int GetCurrentThreadId()
    {
        return Thread.CurrentThread.ManagedThreadId;
    }
}

public class ConsoleLogListener : ILogListener
{
    public void Log(LogMessage message)
    {
        Console.WriteLine(message.ToString());
        Debug.WriteLine(message.ToString());
    }
}

public class SimpleTextFileLogger : ILogListener
{
    private readonly IFileSystem _fileSystem;
    private readonly string _userRoamingPath;
    private readonly string _logFileName;
    private FileStream _fileStream;

    public SimpleTextFileLogger(IFileSystem fileSystem, string userRoamingPath, string logFileName)
    {
        _fileSystem = fileSystem;
        _userRoamingPath = userRoamingPath;
        _logFileName = logFileName;
    }

    public void Start()
    {
        _fileStream = new FileStream(_fileSystem.Path.Combine(_userRoamingPath, _logFileName), FileMode.Append);
    }

    public void Stop()
    {
        if (_fileStream != null)
        {
            _fileStream.Dispose();
        }
    }

    public void Log(LogMessage message)
    {
        var bytes = Encoding.UTF8.GetBytes(message.ToString() + Environment.NewLine);
        _fileStream.Write(bytes, 0, bytes.Length);
    }
}

public interface ILoggerFactory
{
    ILogger For(Type loggerFor);
}

public interface ILogListener
{
    void Log(LogMessage message);
}

public interface IThreadAdapter
{
    int GetCurrentThreadId();
}

public interface IQueueDispatcher
{
    void Start();
}

Entry point:

public static class Program
{
    public static void Main()
    {
        Debug.WriteLine("[Program] Entering Main ...");

        var pendingLogQueue = new BlockingCollection<LogMessage>();

        var threadAdapter = new ThreadAdapter();
        var loggerFactory = new LoggerFactory(pendingLogQueue, threadAdapter);

        var fileSystem = new FileSystem();
        var userRoamingPath = GetUserDataDirectory(fileSystem);

        var simpleTextFileLogger = new SimpleTextFileLogger(fileSystem, userRoamingPath, "log.txt");
        simpleTextFileLogger.Start();
        ILogListener consoleListener = new ConsoleLogListener();
        ILogListener[] listeners = new [] { simpleTextFileLogger , consoleListener};

        var loggingQueueDispatcher = new LoggingQueueDispatcher(pendingLogQueue, listeners, threadAdapter, loggerFactory.For(typeof(LoggingQueueDispatcher)));
        loggingQueueDispatcher.Start();

        var logger = loggerFactory.For(typeof(Console));

        string line;
        while ((line = Console.ReadLine()) != "exit")
        {
            logger.Debug("you have entered: " + line);
        }

        logger.Fatal("Exiting...");

        Debug.WriteLine("[Program] pending LogQueue will be stopped now...");
        pendingLogQueue.CompleteAdding();
        var logQueueCompleted = loggingQueueDispatcher.WaitForCompletion(TimeSpan.FromSeconds(5));

        simpleTextFileLogger.Stop();
        Debug.WriteLine("[Program] Exiting... logQueueCompleted: " + logQueueCompleted);

    }

    private static string GetUserDataDirectory(FileSystem fileSystem)
    {
        var roamingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        var userDataDirectory = fileSystem.Path.Combine(roamingDirectory, "Async Logging Sample");
        if (!fileSystem.Directory.Exists(userDataDirectory))
            fileSystem.Directory.CreateDirectory(userDataDirectory);
        return userDataDirectory;
    }
}


问:
Designing my classes with relationships
I need to build a UI for entering values to the database. I am stuck with my class design to achieve it.

I need a UI where I am able to enter the name of the system. Each system can have many options. Each option is associated with a TC(Technical chara). Each TC has another set of values which is described as TCset. For instance, let's say Tcset for a TC (TC1) has values: TC1.1, TC1.2, TC1.3. (There other variables describing each row in the TCset, I have mentioned the name property alone for simplicity. Now again coming back to the system, the option defined in each system can have multiple option values.  For each option value I should be able to enter a value for the name property in TCset associated with the TC of that option.)

What I would like to achieve would be something similar to this.

Adding a system and defining the Options:

Adding Value for Option and value for SetVal:

Based on my understanding I have designed the following class diagram. But still I can't find the exact mapping between the Option and SetVal. I am unable to design a class where I could add values for the Tcset in a particular option

```<code>public class Lsystem
{
    public int LsystemID { get; set; }
    public string LsystemName { get; set; }
    public virtual ICollection<Option> Options { get; set; }
    public int OptionId { get; set; }

}

public class Option
{
    public int OptionID { get; set; }
    public string OptionName { get; set; }
    public int TCID { get; set; }
    public virtual TC tc { get; set; }
    public virtual Lsystem Lsystem { get; set; }
    public int LsystemID { get; set; }
    public virtual ICollection<OptionValue> OptionValues { get; set; }
}

public class OptionValue
{
    public int OptionValueID { get; set; }
    public string ValName { get; set; }
   //public int TCsetID { get; set; }
    public int OptionID { get; set; }
    public int SetValID { get; set; }
    public virtual Option Option { get; set; }
  //public virtual TCset TCset { get; set; }
    public virtual SetVal SetVal { get; set; }
}

public class TC
{
    public int TCID { get; set; }
    public string TCName { get; set; }
    public virtual ICollection<TCset> TCsets { get; set; }
}

public class SetVal
{
    public int SetValId { get; set; }
    public double Value { get; set; }
    public int OptionID { get; set; }
    public int TCsetID { get; set; }
    public virtual OptionValue OptionValue { get; set; }
    public virtual TCset TCset { get; set; }
}

public class TCset
{
    public int TCsetID { get; set; }
    public string TCsetName { get; set; }
    public string PhysicalUnit { get; set; }
    public int TCID { get; set;}
    public virtual TC TC { get; set; }

}
</code>```

Is there something I am missing to get it right. But the current class model doesn't work because foreign key conflicts. That made me add another class SetVal but did not solve my problem. I have tried a lot to get all the relationships right but nothing worked out.

Just for a briefing, the relationships that I have used here:

```<code>  System - Option : One to Many
  Option - OptionValue : One to Many
  Option - TC : Many to One
  TC - TCset : One to many
  OptionValue - SetVal : One to One
  TCset - Setval : One to One
</code>```

Edit

The point where i am stuck is generating a table which would take option value id and give an option to add values for the tcset.

That is Under Option Value Ab1, i need a table to give values like the following

Option Value Ab1

ABC1    -    45
ABC2    -    34

Option Value Pq1

PQR1   -    67
Pqr2   -    34
pqr3   -    56

Option Value Pq2

PQR1  -    67
pqr2  -    34
pqr3  -    67

This connection is what i am missing. i realized this when i was trying to make tables the way it was made in the answer

Edit : 2 Adding example

```<code>     +--------------------------+
     |  SystemId  | System Name |
     +------------+-------------+
     |     1      |   DCC - 050 |
     |____________|_____________|
     |     2      |   DCC - 070 |
     |____________|_____________|

     ____________________________
     |  TCID      | TCName      |
     |____________|_____________|
     |    1       | Screw       |
     |____________|_____________|
     |    2       |  Motor      |
     |____________|_____________|

     __________________________________________________________
     | TCSetID   | TCsetname|PhysicalUnit | DataUsage | TCID   |
     |___________|__________|_____________|___________|________|
     |    1      | speed    | m/sec       | Prelimina |   1    |
     |___________|__________|_____________|___________|________|
     |    2      | d_0      | mm          | final     |   1    |
     |___________|__________|_____________|___________|________|
     |    3      | d_1      | m           | final     |   1    |
     |___________|__________|_____________|___________|________|
     |    4      | torque   |  mm         | final     |   2    |
     |___________|__________|_____________|___________|________|

     ____________________________________
     |OptionID | SystemID | TCID |OpName |
     |_________|__________|______|_______|
     |    1    |     1    |  1   |Screw  |
     |_________|__________|______|_______|
     |    2    |     1    |  2   |Motor  |
     |_________|__________|______|_______|

     _______________________________________________
     |OptionvalID | SystemID|OptionID | OptionValue|
     |____________|_________|_________|____________|
     |    1       |    1    |    1    |    01      |
     |____________|_________|_________|____________|
     |    2       |    1    |    1    |    02      |
     |____________|_________|_________|____________|
     |    3       |    1    |    1    |    03      |
     |____________|_________|_________|____________|
     |    4       |    1    |    2    |    01      |
     |____________|_________|_________|____________|
     |    5       |    1    |    2    |    02      |
     |____________|_________|_________|____________|
</code>```

Now the main issue is, i want to give values for the TCsetname in each option. My resulting table would be the following (This is not the database schema)

SCREW

```<code>     __________________________________________
     |TCSet |     01   |    02    |    03     | => Option values for Screw
     |______|__________|__________|___________|
     |speed |    12    |    14    |     16    |
     |______|__________|__________|___________|
     |d_0   |    34    |    56    |     56    |
     |______|__________|__________|___________|
     |d_1   |    2     |     5    |     6     |
     |______|__________|__________|___________|
</code>```

MOTOR

```<code>     ______________________________
     |TCSet |     01   |    02    | => Option Values for the Option Motor
     |______|__________|__________|
     |Torqu |    12    |    14    |
     |______|__________|__________|
</code>```

I am looking to correct the datamodel which accepts the last table

Title: Designing my classes with relationships

Body:
I'm guessing that what you are trying to do is use your model to describe both the metadata and the data for your system(s).

So, System 1 has several options, such as Primary Motor, Secondary Motor, and Transmission
An option has a type (what you are calling TC), so Primary Motor and Secondary Motor would both be Motors, whereas Transmission might be TransmissionType
Each type has characteristics: Motor might have horsepower and torque; Transmission might have the number of speed/ratios and clutches.

Now you want to define the values for each option in System 1:
Primary Motor has 200hp and 180 lb/ft of torque.
Secondary Motor has 80hp and 120 lb/ft of torque.
Transmission is 6 speed 1-clutch.

So:

System
___________________
| ID | System_Name |
|____|_____________|
|  1 | System1     |
|____|_____________|

Option_Type (TC)
_________________________
| ID | Name              |
|____|___________________|
|  1 | Motor Type        |
|____|___________________|
|  2 | Transmission Type |
|____|___________________|

Type_Characteristics (TC_SET)
_____________________________________________
| ID |  TC_ID  | NAME           |  UNIT_TYPE |
|____|_________|________________|____________|
|  1 |  1      | Horsepower     |   HP       |
|____|_________|________________|____________|
|  2 |  1      | Torque         |   lb/ft    |
|____|_________|________________|____________|
|  3 |  2      | Clutch Count   |   clutches |
|____|_________|________________|____________

OPTION
________________________________
| ID | Name            |  TC_ID |
|____|_________________|________|
|  1 | Primary Motor   |   1    |
|____|_________________|________|
|  2 | Secondary Motor |   1    |
|____|_________________|________|
|  3 | Transmission    |   2    |
|____|_________________|________|

Option_Values
_______________________________________
| ID | OPTION_ID |  TC_SET_ID | VALUE  |
|____|___________|_____________________|
|  1 |      1    |      1     |   200  |
|____|___________|____________|________|
|  2 |      1    |      2     |   180  |
|____|___________|____________|________|
|  3 |      2    |      1     |    80  |
|____|___________|____________|________|
|  4 |      2    |      2     |   120  |
|____|___________|____________|________|
|  5 |      3    |      3     |    2   |
|____|___________|____________|________|

What won't happen here is the database enforcing that the Primary Motor option only has values for TC_SET_ID values 1 and 2--that must be enforced in your code instead.  However it does give you the means to build your UI:

The user picks a system, a form gets built out for each option, where it asks for a Option_Value to be entered for each Type_Characteristic associated with the Option_Type associated with that option.


问:
What are the key differences between low-level C development and higher level OOP development?
I have been using high-level OOP language (like C# and/or Java) for quite some time. I know patterns like the gang of four, can read and write code reasonably well and am considered a senior by his peers.

I am moving to low-level C development. As a result of my background I am unfamiliar with many of the technologies and skills inherent in lower level development/implementation.

What are the key differences in the technology and approach to development that I need to understand in order to be successful in C development when coming from a higher level OOP background?

答:
Being an experienced C programmer and less experienced with C++ (but I have coded in projects started by other persons, just never built up a C++ project from scratch, myself), I might be traveling the same path in the opposite direction.  We might be meeting in the middle somewhere and I can tell you a little of where I have come from.

Certainly there are OOPsie features of C++ that C doesn't have.  There are namespace issues, templates, etc, that I have not made use of.  All I have done is used and created classes and instantiated objects within the classes.  And modified code in classes that other folks had created.

That said, any C programmer can write structured code that is similar, in many key respects, to fully OOP code.  You have struct, typedef, pointers to struct, the ability to cast the pointer to one kinda struct to another where there are fields in common.  There is also union in which you can explicitly overlay fields that are in common and other fields that are not in common.  This looks a lot like inheritance that you'll find in an OOP language.

Personally, I dislike many specific syntax of C++ that I would rather just program in C where I know precisely what the "right" way to do it is.  I don't know Java or C# or whatever variant.


问:
How do you dive into large code bases?
What tools and techniques do you use for exploring and learning an unknown code base?

I am thinking of tools like grep, ctags, unit-tests, functional test, class-diagram generators, call graphs, code metrics like sloccount, and so on. I'd be interested in your experiences, the helpers you used or wrote yourself and the size of the code base with which you worked.

I realize that becoming acquainted with a code base is a process that happens over time, and familiarity can mean anything from "I'm able to summarize the code" to "I can refactor and shrink it to 30% of the size". But how to even begin?

答:
Do I have to hack till I get the job
  done

To a large extent, yes (sorry).

Approaches you might consider:

Try to find out what the code is supposed to do, in business terms.

Read all the documentation that exists, no matter how bad it is.

Talk to anyone who might know something about the code.

Step through the code in the debugger.

Introduce small changes and see what breaks.

Make small changes to the code to make it clearer.

Some of the things I do to clarify code are:

Run a code prettifier to format the code nicely.

Add comments to explain what I think it might do

Change variable names to make them clearer (using a refactoring tool)

Using a tool that highlights all the uses of a particular symbol

Reducing clutter in the code - commented out code, meaningless comments, pointless variable initializations and so forth.

Change the code to use current code conventions (again using refactoring tools)

Start to extract functionality into meaningful routines

Start to add tests where possible (not often possible)

Get rid of magic numbers

Reducing duplication where possible

... and whatever other simple improvements you can make.

Gradually, the meaning behind it all should become clearer.

As for the place to start? Start with what you do know. I suggest inputs and outputs. You can often get a handle on what these are supposed to be and what they are used for. Follow data through the application and see where it goes and how it is changed.

One of the problems I have with all this is motivation - it can be a real slog. It helps me to think of the whole business as a puzzle, and to celebrate the progress that I'm making, no matter how small.

Title: How do you dive into large code bases?


问:
Sparse set lossy compression algorithm
I am looking for algorithm or idea for the following problem.

Suppose we have a data type, say 64-bit integer. Now we have a relatively small set of such items, say few hundred at most. The simplest way to program that is to have a list of items, that means a sparse set.

Now the problem: I want to compress that list so it is much smaller, possibly losing some information.

Requirements:

There must be a way to check if an item belongs to the set and it must be rather fast.

Generation of the compressed set may be slow.

If an item was present in the uncompressed set, then it must show positive in the compressed set.

If an item was absent from the uncompressed set, then it may be present in the compressed set, however probability of such event must be low.

One idea I had: if we have some pseudorandom number generator, then we look for such seed, so that in the first few thousands of iterations all requested items are present. The seed would be the compressed representation. Another idea: neural networks (description will be the representation).

答:
What you are looking for is called a minimal perfect hash. If you have, say, 256 items out of a data space 1024 bit wide, a hash such as MD5 would map them to 128 bit hashes, possibly with collisions.

If you took the last 8 bits of the MD5, you would still get a hash (of sorts), with a much larger risk of collisions.

A minimal perfect hash is a function that maps your 256 tokens into the numbers from 0 to 255, thereby squeezing out the eight bits of information you need.

A trivial "hash" generator would be

```<code>if (token == token1) { return hash1; }
if (token == token2) { return hash2; }
</code>```

and has complexity O(n). I seem to remember that the ideal generator has a much lower complexity of O(log2(n)).

Random searching is indeed one method of generating such a hash function.

You will probably want to check out tools such as this.

Title: Sparse set lossy compression algorithm

Body:
What you are looking for is called a minimal perfect hash. If you have, say, 256 items out of a data space 1024 bit wide, a hash such as MD5 would map them to 128 bit hashes, possibly with collisions.

If you took the last 8 bits of the MD5, you would still get a hash (of sorts), with a much larger risk of collisions.

A minimal perfect hash is a function that maps your 256 tokens into the numbers from 0 to 255, thereby squeezing out the eight bits of information you need.

A trivial "hash" generator would be

if (token == token1) { return hash1; }
if (token == token2) { return hash2; }

and has complexity O(n). I seem to remember that the ideal generator has a much lower complexity of O(log2(n)).

Random searching is indeed one method of generating such a hash function.

You will probably want to check out tools such as this.


问:
Can encapsulation be implemented by proper types rather than accessors?
Interesting question came up while designing interfaces at work, now resolved, but I want to ask about the theory behind it.

Is it incorrect to say that properly typed data members of a class provide encapsulation? (e.g. a Boost Units type that has conversions well defined between other like units, not a typedef'd/boxed uint64_t)

```<code>struct Ruler
{
    Length length;
    Length tick_size;

    Ruler(Length length, Length tick_size);
    // Why not have helpers immediately related to the class, let's
    // stick in an alternative constructor
    Ruler(Length length, int number_ticks);

    // Accessors for # tick marks, because it needs transformed
    // to/from length and tick_size
    int GetNumberTicks(void);
    // This specific example breaks down with this function,
    // but I don't think it's an inherent issue with the design.
    // I need an overload so it will know which of the two member
    // variables to calculate... problem is both are Length
    void SetNumberTicks(int nticks);
}
</code>```

vs

```<code>struct Ruler
{
    Ruler(Length length, Length tick_size);
    Ruler(Length length, int number_ticks);

    // General accessors
    Length GetLength(void);
    void SetLength(Length length);

    Length GetTickSize(void);
    void SetTickSize(Length length);

    // Calculated accessors, see above
    int GetNumberTicks(void);
    void SetNumberTicks(int nticks);

private:
    Length length;
    Length tick_size;
}
</code>```

IMO the first encourages cleaner design by consumers and doesn't encourage pulling in slightly related, but probably attached to the wrong object member functions (eg CanMachineCreateRuler() ). I don't really have the words to describe this properly and I may be misunderstanding the additional utility that the accessors/private data combination provide.

答: Yes, if the public member variables are independent of each other. It does break a uniform convention of using accessors in other classes when justified, however, which is probably enough reason to stick with accessors with regards to code style.</p>


问:
Designing a ticketing system where the User and Administrator have similar but different functionality
I am designing a simple ticketing system in Laravel 4. The system will simply allow a User to create a ticket, and an Administrator to answer it.

The User will be able to:

View a list of his tickets.

Create a new ticket.

View the replies to one of his own ticket.

Add a reply to a one of his own ticket.

Close a one of his own ticket.

Perform the above tasks via the url www.example.com/support

The Administrator will be able to:

View a list of all tickets.

Cannot create a new ticket.

View the replies to any ticket.

Add a reply to any ticket.

Close any ticket.

Perform the above tasks via the url www.example.com/admin/support

In other words, a User and Administrator can perform very similar, but different functionality. What are ways that I can design this system to reduce the amount of copying and pasting that must be done?

So far, I have came up with two possibilities.

Create two sets of Routes with two Controllers - one for the user and one for the admin. Copy and paste most of the logic between the Controllers, but changing a few variables so that users can only see his own tickets. Both Controllers share the same Views and Model. Add in an additional check in the Views so that the admin do not see a button to create a new ticket.

The down side of this is that I have to put logic in the Views in order to hide certain things from the admin, and other things from the user. I am also copying and pasting code between controllers.

Create two sets of Routes but use the same Controller. Use if statements in the Controller to show different Views depending on whether it is a User or an Administrator.

However, now I am copying and pasting code between views. Having two different set of logic in the same Controller may be a bit confusing as well.

Is there a better way to go about this?

答:
Write two different UIs.

Really.  I work on exactly such a system every day, and the user experience for your User and Administrator personae are completely different.  They're different because the needs of those users are completely different.

Administrators will spend large parts of their day with your ticket list open in front of them, interacting with tickets on and off all day.  The Administrator UI needs to be efficient and powerful, as befits the primary application used by its humans.

Users will go to your site once in a rare while, create a ticket, check a ticket, and leave.  The User UI needs to be simple to understand and navigate, and to require almost no thought to use, as befits a rarely used application.


问:
History of VanillaJS
When did the trend of saying VanillaJS to refer to pure JavaScript come into widespread. Is the website Vanilla-js the discoverer of the term VanillaJS or was this term used even before the launch of this website?</p>

答:
I created the Vanilla JS site.

I didn't coin the term "Vanilla JS" - it's like asking someone if they invented the term "Blue Chair".  Blueness and Chairness have been things for thousands of years, and similarly, "Vanilla" in the software world usually means "plain" - Plain JS.  I remember seeing it used before I created the site.

However:

The Google Trends data for the term "Vanilla JS", which indicates that the term came into widespread use in August 2012, coincides with the registration date of the vanilla-js.com domain name.  So, while I didn't invent the term, I probably popularized it.  This is funny, since I really don't like the term "vanilla" meaning "plain" - but, it's what the software community uses, so in the interest of clarity (and comedy), it's what I chose to use.

Title: History of VanillaJS


答:
It will depend on how "close to the metal" you'll need to get. But a few common things you might find that may not be familiar to you:

Right off the bat, the fist thing you'll have to pay a lot of attention to is resource management. C doesn't run a garbage collector and doesn't have automatic finalizers (AKA destructors), so allocating a chunk of memory or opening a file/socket implies that you have to manually keep track of the lifetime of that resource and free it at some point in the program. That's probably the biggest shift in paradigm, coming from Java/C#, but once you get used to it, it's no big deal. We have very good tools nowadays that help tracking resource leaks, so you don't have to live in fear.

C doesn't provide a safety net. And by that I mean no array bounds checking, no memory guarding whatsoever and very little runtime protection against common programming mistakes. You might have heard that "C is a big gun, but it is very easy to shoot yourself in the foot with it" - and that is true, high execution performance requires making a few tradeoffs, and waving runtime checks is one of those. Any safety mechanisms that your program might need are implemented by you, the language doesn't offer much out-of-the-box.

C is very lightweight, and so is its Standard Library. The Standard Lib consists basically of a handful of IO functions and math functions, that's about it. If you're into embedded C, you might not even get that! No nice containers and generic algorithms. Again, in the spirit of the language, if your application needs a feature, it implements it. The language and library makes no assumptions for you.

Data typing is much more slack in C. This is debatable if good or bad, but it does allows for some interesting things like reinterpreting pointers and data read from files.

You have to be more aware about the hardware where your program is going to run. This is not particularly related to C, but to any flavour of low-level performance-oriented programming. The closer you get to the metal, the more you have to pay attention to things like CPU cache usage, memory footprint, device IO costs and algorithm time complexity. For instance, you might eventually find out after profiling that a plain array and linear search is faster than a binary search tree due to better cache access patterns in the target architecture.

You have to be more aware about the data, not just the code. The purpose of any program is to transform data, but it is easy to get carried away about the code and abstractions when writing high-level interfaces and forget that the code actually has to process some data and output some other data. The more you know your data, the easier it gets to optimize the code, that's data oriented design.

Those are some interesting aspects to consider. Certainly there are more, but that's what I can think of for the moment. I hope that's not too daunting. C is a great language to work with, even though I personally like C++ better ;). And low-level performance-oriented programming can also be a lot of fun. Once you enter it, you'll see programming in a whole new way.

Title: What are the key differences between low-level C development and higher level OOP development?

Body:
I have been using high-level OOP language (like C# and/or Java) for quite some time. I know patterns like the gang of four, can read and write code reasonably well and am considered a senior by his peers.

I am moving to low-level C development. As a result of my background I am unfamiliar with many of the technologies and skills inherent in lower level development/implementation.

What are the key differences in the technology and approach to development that I need to understand in order to be successful in C development when coming from a higher level OOP background?


问:
Object creation: when should I expose a factory vs wrapping class?
I am having some problems trying to figure out when to use a factory or to wrapper class. This question is slightly geared towards C# I guess, so I'm not sure if this is the correct place to ask.

Say there is a library that exposes an interface called IStackExchangeClient, and multiple differing implementations of that interface (private implementations that clients will not know about), HttpStackExchangeClient, UdpStackExchangeClient.

We can allow the object creation of the interface through a factory, like StackExchangeClientFactory.Create(), or we can wrap it up in another class like StackExchangeClient that internally does the same thing, but simply proxies.

In the second instance, clients can write new StackExchangeClient() which feels much more natural to me. So my question is, when do I choose one or the other? What are some of the considerations that I should be taking in?

I've thought hard about it and I can't choose between one style or the other, but clearly some parts of the .NET framework use factories, and some parts don't, even when there are multiple underlying implementations of its interface.

Thank you!

答:
Just use the simple constructor.

In this particular case factory is a more obscure API for no reason.

Add the factory when it's clearly needed.


问:
Need Advice on PHP Search Functionality
I'm coding a Linux/PHP site for an organization. The site has two views, activated by a login $_SESSION variable indicating whether one is logged in as a member or not. I need to provide search functionality for both the public and for members. The members area is private. Note that Google Custom Search can't be used here in that case.

Does anyone have any recommendations on F/OSS scripts (or perhaps cheap scripts I can purchase) that would provide this functionality with two separate indices, one public and one private, and which would provide paginated results and a keyword search form?

Otherwise, I guess I'll have to code one myself. I'm trying to save time, and therefore keep more money in my pocket.

P.S.

Note I can't ask this on StackOverflow because they want programmer questions there. This isn't a "how do I code this?" question, but "what F/OSS scripts or cheap sitescripts would solve this problem?" type of question.

Note also that this won't help me either. I mean, look at the answers of that question.

答:
I would think (depending on the exact structure of your "Linux/PHP" site,) that you essentially have three main options.

Using an existing (non-PHP) IR/search system

You could (as suggested in @Charles's answer) use something like ElasticSearch, or host your own Lucene (https://lucene.apache.org) or Sphinx environment.
Unfortunately, these solutions have some fairly hefty drawbacks (particularly if your site is somewhat small):

You will need to provide these various engines with an index.  Which may (depending on your application), be as simple as munging an RSS-feed of 'posts' or 'pages' etc.  But it could also be fairly complex, if you have a large site with no underlying structure/DB to get index data from.

These search engines will need to be hosted, either on a VPS, other server or (as with ElasticSearch) some SaaS platform.  This would obviously add additional expense to your efforts.

Implement (or plug-in) a tag-based search

Tag based searching (ala SE), may be easier as it allows your users to construct the index for you.  Whenever a member tags something, it gets added to a database which can then be searched for the member search.
The obvious cons here are that:

This burdens your users with the construction of the index, which may harm reliability, etc.

Searching for tags and doing full text search are very different things.  Your members may miss a lot of untagged results which may be relevant.

However, on the plus side this is probably cheaper than the first option, and may be quicker to implement than the next.

Roll-your-own crawler/spider to make an index

As you seem to be eluding to in your comment, you could use wget, curl or PHP's file_get_contents function to retrieve your own website's URL's (with some request flag or cookie to get member's area access).
Although it may seem clunky (fetching your own content), this may be easier than constructing an index yourself if there's no underlying database or model for something like Lucene to use.

Once retrieved you then just need to tokenize the data and store it in something like a database or other form of index.

Title: Need Advice on PHP Search Functionality


答:
The key difference is that:

When doing high level development, you are mainly dealing with how to solve a real world problem.  Your "problem domain" is a real world situation, your entities are real world entities, and your logic is application logic.  (The term "real world" is somewhat flexible, here, since for example you may be developing an MMORPG, like World of Warcraft, in which case the world is anything but real, but still, within that context, that's the world you are treating as real.)

When doing low level development, you are mainly dealing with how to get the machine to perform a specific task as efficiently as possible.  The entities that you are dealing with are most of the time highly technical in nature, like memory blocks, block chains, hash values, etc. and your logic has nothing to do with the real world, and everything to do with the machine.  You are often dealing with concepts that are completely machine-specific, like the endianness of machine words, or the I/O ports through which you can communicate with a specific device, and the sequences of byes that you have to send to it to get it to do its job.

As a matter of fact, when interfacing between high level code and low level code, it is often beneficial to transform the high-level entities into low-level entities (or simply view the former as the latter, without a need for an actual transformation) so that the high level code never needs to deal with machine concerns, and the low level code never needs to deal with application concerns.

So, in your application you may have a collection of, say, customers, and be doing things with it of the kind that we do with customers, like charging them for goods purchased, or sending them newsletters, without caring about the internal representation of the collection.  In your low level code, however, you will be seeing the collection as a fixed length array of pointers to objects, and you may know nothing about these objects other than, perhaps, that they can be invoked to compare themselves to each other or to compute their own hash values.  You are not supposed to know that they are customers, and you are not supposed to send newsletters to them in low-level code.

So, if you find yourself using a low-level language like C, and having to deal with application entities like "customers", you are doing it wrong.  You have been asked to use the wrong language for the job.


问:
Can I whitelist user agents that will execute JavaScript?
I'm building a SPA (single page application) so that when a browser request a page from my server, it only receives a small HTML and a big JavaScript app that then asks the appropriate data from the server, renders the HTML locally and generally drives the local app. Think of apps such as Gmail or Google Maps that never ever reload the page again.

This makes apps feel very snappy but it means that if the user agent doesn't execute JavaScript, then there's no content. This is a problem when the web site is being indexed by search engines or when an app requires a some content for it (think about posting links to Facebook, Twitter, LinkedIn, how you get a snippet of the content).

To circumvent that problem, I'm pre-rendering pages by running the JavaScript part on the server. It is working, but it is rather slow. Since most of the time this execution of JavaScript won't be needed, I'm thinking of whitelisting some browsers, like Chrome, Safari, Firefox, even recent version of IEs to not get pre-render.

Would this work or are most useful bots out there identifying themselves as browsers? How can I gather this information? Any source on user agent of good and bad bots?

答:
I would suggest you take a look at things like AJAX Crawling to influence you here.

The pre-rendering does sound like overkill, but if you need javascript to calculate page content, then better to only run the javascript pre-render when a bot (such as googlebot) has requested a page like http://mySPA/example.net/SPA#That-one-page-with-the-stuff and then return the normal (lite HTML with javascript doing the heavy lifting) page when an actual user requests http://mySPA/example.net/SPA.

Google calls this a "HTML Snapshot", and will abide by it in search results.  Not sure if Facebook play's nice too.


问:
Why some compilers do not synthesize the move operations at all per this paragraph in C++ Primer 5th?

In particular, if a class defines its own copy constructor, copy-assignment operator, or destructor, the move constructor and move-assignment operator are not synthesized.

—— quote from "13.6.2. Move Constructor and Move Assignment"

Why some compilers do not synthesize the move operations at all per this paragraph in C++ Primer 5th?

答:
It is not just some compilers. Under the conditions listed in the quote, compilers are explicitly forbidden to synthesize the move operations.

Move operations were added quite recently to the C++ language, long after it had copy operations and destructors. And one thing that the maintainers of the C++ language standard try to maintain is that new features in the language do not break existing code, especially not if that code is part of the mainstream usage of the language.

If a class has its own copy constructor, copy-assignment operator and/or destructor, then in the large majority of cases those functions are doing some work that the compiler-synthesized version can't or won't do. If the compiler does synthesize move operations for such a class, then it is very likely that those move operations will not do the right thing.

For example, you have a class that maintains a database connection and has all the right copy operations and destructor to ensure that the connection would be closed at the right moment. If the compiler synthesized move operations for such a class, then the moved-from object would close the database connection, while the moved-to object is still using that connection.

There are all kinds of techniques to avoid such problems, but those are not always consistently used in legacy code and to avoid breaking that large body of code it was decided that move operations would not be silently added to classes where it might break the functioning of the class.

If you want move operations in a class that has its own copy constructor, copy-assignment operator or destructor, you have to write the move constructor and move-assignment operator yourself to ensure that they do the right thing.


问:
How to sell an application? Licensing problems
I`ve built a simple but yet effective delphi-7 application that solves sudoku puzzles, and a keygen that produces a unique serial key for each PC. My purpose is not to make money, I want to understand the methods of commercial uses of an application at its simplest form.

I have zero knowledge and experience about licensing. I googled internet for methods of "pay 1$ and receive the serial key by email", however there is no clear information about this, sometimes they explain what kind of licenses there are (GNU etc.), but I do not know how to use them. I need simple instructions, explanations or methods.

When user presses the menu "Register" on the solver, the second form is created, and the user sees the product ID of the application and a windows where purchased serial key should be entered.

Assumptions:

I`m going to set the price for a key as 1$ in this experiment, therefore it is assumed that I will not make enough profit (if any), therefore costly external services are not my case. (Nevertheless, any information is welcomed)

The Product ID of the app is produced using CPU_ID of the clients machine. Therefore, user must be warned that the purchased key will not work if CPU of the PC is replaced. (Warning can be placed as a check near the register button)

My questions:

Do I have to produce individual terms of agreement for this program?

Do I have to submit my .exe file for approval in somewhere in order to be able to sell it?

What is the least costly method to distribute keys to clients?

Is there something I dont understand or do wrong?

Is there a way to automate billing and key distribution?

答:
It has probably never been easier to sell this kind of software, due to the emergence of online app stores for Mobile phones and now Windows.

If you compile your app as a windows store app,
sign up for a windows store account,
fill in various tax forms,
get a PEGI certificate and set up a bank account for them to pay money into. You can upload your app to the store and they will sell it to millions of consumers for a ~30 cut, deal with the Sales tax etc and pay money direct to your bank account.

It's not trivial, but only a couple of days effort and you'll need to setup a company etc anyway for tax purposes.

Another option would be to make you app into a web page and add a signup procedure which includes a payment before the user can access the solver page. You could take the payment via paypal. obvs you have to sign up for a paypal account and then monitor payments and activate peoples accounts.

Again Paypal will take a cut and you will have to do your taxes etc

If you want to keep the app as a binary download, you could use the same site but offer a download link instead.

You also touch on the problem of piracy. This is kind of separate from how you sell you app. In fact you want to sell a licence to use your app and add a technological restriction on the user which enforces the terms of the licence.

Having a serial key that users have to buy and enter is a common solution. Or you could force them to login when they launch the app.


答:
TL;DR Use an app store. They do all the hard stuff for you. All you'll need is a simple website to point to your app in the store.

You have many questions here, and may issues to resolve...

Do I have to produce individual terms of agreement for this program?

You don't have to do anything. To be honest, a $1 sudoku solver will not make much of splash in the app pond, so a license probably won't make or break you. But if you want to have a license so you can decide to go after someone who violates it, you can find one in another app, or search online for samples, and copy it. Read it thoroughly to make sure you understand it, or pay a lawyer to help you understand it, before you adopt it.

Do I have to submit my .exe file for approval in somewhere in order to be able to sell it?

No. But be aware that a random .exe floating around the Internet will be assumed to be a malware delivery bundle. Nobody will touch it. At the very least, you need to deliver your .exe through your website (no website = no trust), and you should provide a SHA-1 hash of your .exe that a user can use to verify that nobody has hacked your .exe and bloated it their garbage. (This assumes you know how to keep your website from being hacked.)

What is the least costly method to distribute keys to clients?

Your costs will vary wildly depending on how you build your e-commerce solution to be able to process payment transactions. You don't want to roll your own solution. There are too many government regulations about data safety and if you're this new, you'll get into trouble fast. Build your website with a content management system (CMS) like Wordpress, Joomla, or Drupal. They all have e-commerce modules you can plug-in, and they support digital media products (such as an app) and license key delivery features.

You'll need to set up a merchant account with a bank if you're going to process transactions.

PayPal has a payment processing feature as well, but to my knowledge, they don't support license key delivery.

No matter what payment processing mechanism you use, you're going to pay a percentage of each transaction to the payment processor. How much depends on which processor you choose.

Is there something I dont understand or do wrong?

Yes. Lots. But you won't know what you don't know until it happens. There are lots of resources on the web about how to build an online business.

Is there a way to automate billing and key distribution?

E-commerce software modules in the popular website platforms do this.

But, by far, the easiest way to distribute a $1 app these days is to use an App Store. The Windows 10 App store will do all the work for you in terms of hosting your app, processing payments, and ensure your app doesn't get bloated up with malware you cannot control. There's a registration process, and they take a commission on each purchase. Android and iOS stores work the same. It's not bad to pay them a commission, since they're taking care of all of the above-mentioned issues for you.

See Alexander's answer for a great list of app stores.

Title: How to sell an application? Licensing problems

Body:
I`ve built a simple but yet effective delphi-7 application that solves sudoku puzzles, and a keygen that produces a unique serial key for each PC. My purpose is not to make money, I want to understand the methods of commercial uses of an application at its simplest form.

I have zero knowledge and experience about licensing. I googled internet for methods of "pay 1$ and receive the serial key by email", however there is no clear information about this, sometimes they explain what kind of licenses there are (GNU etc.), but I do not know how to use them. I need simple instructions, explanations or methods.

When user presses the menu "Register" on the solver, the second form is created, and the user sees the product ID of the application and a windows where purchased serial key should be entered.

Assumptions:

I`m going to set the price for a key as 1$ in this experiment, therefore it is assumed that I will not make enough profit (if any), therefore costly external services are not my case. (Nevertheless, any information is welcomed)

The Product ID of the app is produced using CPU_ID of the clients machine. Therefore, user must be warned that the purchased key will not work if CPU of the PC is replaced. (Warning can be placed as a check near the register button)

My questions:

Do I have to produce individual terms of agreement for this program?

Do I have to submit my .exe file for approval in somewhere in order to be able to sell it?

What is the least costly method to distribute keys to clients?

Is there something I dont understand or do wrong?

Is there a way to automate billing and key distribution?


答:
In 2015 there is no need in making such system by yourselves. Every major platform has its own application market.

Desktop:

On Windows: Microsoft Store

On OS X: Mac App Store

On Ubuntu: Ubuntu Software Centre

Mobile:

On iOS: App Store

On Android: Google Play

On Windows Phone: Microsoft Store

Cross-platform:

Steam (for applications)

This is the easiest way to promote your app and show it to your audience.


问:
Does Mono have a place in the enterprise world?
For enterprise windows-based solutions, .NET is the best choice sometimes. How is Mono looked at by the enterprises who have to use Linux (or rather prefer to use Linux) ? Assuming that the developers aren't a problem and they are familiar with .NET/Mono and other possible competitors such as Java.   </p>

<p>Would a medium/large company run Mono on their servers as opposite to technologies such as Java? Do you know of any such company ? </p>

答:
My company develops a major mostly-.NET desktop application and releases Linux versions running on Mono, so I would say yes, there is definitely a place for Mono in enterprise Windows-based solutions.

We package Mono with the installation of our application, not requiring the users to install it separately (and this way we control the version, too).

ContentLicense: CC BY-SA 2.5


问:
Clustering algorithm based on distance
So, I have a packaging center A.
And I have n points scattered around A. Let's call them i1, i2 ... in.

I have a maximum distance threshold, called D.

My task is to break those n points into groups of at maximum m each points. Each group cannot exceed m points, in such a manner that a person starting from A and going to all points belonging to a particular group is traveling for an optimized distance.

For example, A -> i1 -> i4 -> i10 -> A <= D

What I've described above is a TSP problem. Currently, what I've done is break them into clusters using the K-means algorithm and then manually break them down into more groups such that each group cannot have more than m points.

Is there a better approach to this problem?

In short, I'm looking for a clustering algorithm in which:

Each cluster cannot exceed a particular number of points.

Clustering happens on distance (latitude/longitude in my case).

答:
https://en.wikipedia.org/wiki/K-means_clustering

This is a massive research area, I mean defining whether you want to use centroids versus medoids alone changes the complexity of your algorithms. Simple answer is there are many ways documented. Without data it's hard to opine correctly. If you could start with a graph made on MATLAB or free Octave then you might find a suitable similar approach.

Octave is free and contains a k-means algorithm.

I recall Kurzweil's latest book How To Create a Mind described about his speech recognition clustering if you wanted an application example for context.

Title: Clustering algorithm based on distance


答:
We used it in the large corporation where I work.  We didn't plan on it from the start of the project but it just worked out that way.

We had an internal project that we developed in .NET, once we got into UAT, the business owner wanted to open the app up to some customers as well as the internal staff.  The majority of our external (DMZ) servers are Linux based and the Windows servers that are in the DMZ weren't a good fit (too close to capacity).  Instead of buying new hardware someone suggested running the app on Mono.  We spent a couple of days doing our own testing and then released the app to QA, then UAT.  We had no issues.

If we had been given the requirement at the start of the project, we may not have chosen to write it in .NET, but this was one nice outcome to a very, very late requirement change.  Now we're pretty confident that if it came up again we could successfully deploy to Mono (although I would think eventually we'd have to tweak some code, I think we just got lucky).

Title: Does Mono have a place in the enterprise world?

Body:
For enterprise windows-based solutions, .NET is the best choice sometimes. How is Mono looked at by the enterprises who have to use Linux (or rather prefer to use Linux) ? Assuming that the developers aren't a problem and they are familiar with .NET/Mono and other possible competitors such as Java.   </p>

<p>Would a medium/large company run Mono on their servers as opposite to technologies such as Java? Do you know of any such company ? </p>


问:
Upgrade and downgrade customers subscription
I have been stuck at a requirement for way too long too handle it :(.

Our company is having increased number of customers who wants to upgrade or downgrade their  subscription. For now, the subscription-customer relation is at follows:

Every Customer has its own Combo, like the following:

Every Combo is bind to several packages:

When a customer wanted to upgrade his combo, the IT department had to add manually the upgrading package with the start and end date specifications. Since this was a rare request at a time, nothing has been thought for an automatic solution to it. Now, in Upgrade, I have managed to add another Package which has the missing products. The problem is on Downgrade. My initial thought was to edit the enddate field of the package that has to be cancelled, in order that the application would not read it no more. But, maybe is not a good idea to overwrite the existing data, because in the future, it will be impossible to understand if the enddate field was changed by mistake or on purpose.
Since tha application delivers the product via the package, reading its enddate, how can i manage to cancel the required package without overwritting it?

EDIT:

If the customer needs to renew the services, there are two steps taken:

In the first image is added a new row with the combo and saledate specification

In the second image,

a. if the new combo is equal to the old one, it changes the end-date for each package according to the duration

b. if the new combo is different from the old one, in that case, or the new packages are added, and the old ones do not change (This is the case when the new and old combo have no packages in common), or

c. the packages are edited as mentioned in point a) except one package, which is not included in the new combo . This is the case when only one package does not renew its end-date ( This is the case eligible for an upgrade)

Or should I go on with the "Edit Field" idea?

UPDATE:
As one of the possible solutions, I was thinking about adding a database field, which would activate or deactivate one or more package. Meanwhile, I have created a table which saves the pair of combos and the packages that differs them. I don't know if this is a good approach, in order to keep track of everything that happens in the user's experience

答:
It sounds like you running into issues where you coded past an indirection step in the hopes it would be constant.

From your limited description, you have:

A discrete number of possible combinations

One or zero combinations are active at any given time.

In ordering a combo, a customer specifies a nominal end date.

So you have a a list of combinations, customers with an order history
where each history includes an activation date, the ordered combo, and a
nominal end date.  The latest order history is what the customer has. You then derive a new table of customer id and active services to service the delivery.

My guess is you have more complications you are not sharing, or simply so much code trying to second guess the indirection that you cannot fix it.


答:
There will be many answers along the lines of "use someone's AppStore that handles all the nasty credit cards and taxation issues".  This will elide over the "and sign about sixty pages of rapidly changing agreements that you cannot understand".  (No, you cannot and Intellectual Property licensing lawyers are guessing about what they mean.)

Your aim, however, was to learn.

If you want to learn the AppStore process use an AppStore.

If you want to learn what licenses people will accept, generate different ones for each user.

If you want to learn how an AppStore works, set up an AppStore.

If you want to see who uses your software, replace the payment requirement with a plea for a five line email (no spam!) stating the country and something interesting.

Do not shy away from experimenting just to use the AppStore model.


问:
How are search engines able to search for full strings?
Since search engines don't go through every webpage on the internet when searching for something, how are they able to find an exact string of words? For example, using quotes in Google, like "apples bananas pears" will only show results that contain those three words in that exact order. </p>

答:
Never underestimate how much computing power may be brought to bear on a problem.

A web crawler typically pulls down the entire web page and all linked or included pages and creates indices and rankings several times the original size of the web page.  Somewhere, it keeps a copy of the entire page as well.  Google is known for having the largest backup of the 'deep' webpages for obscure searches.

To do a full text search, a faster service typically does a search without the quotes and then filters the results.  It will not find all hits, but users are usually happy if one of the first two results are relevant.  In some cases, the results are a bit slower as the filtering eliminates a lot of responses.

So power.   And cheating.


答:
Accessors for basic data types generally come from the additional operators available to those types.   While getting and setting variables may be allowed, keeping extra references to those variables is often discouraged.

Some languages also need accessors when the encapsulated program wants to make changes at the time an accessor is used, e.g., computing a lazy value or invalidating a cache.

Much of this can be solved by creating general accessor types, such as "an int, that has been initialized, for which no address can be obtained, which is not a NaN, is signed, and, upon overflow takes the largest absolute value allowed." or "an int, that has been initialized, which is arbitrary meaning no arithmetic operations are allowed, for which references can be taken."   The choice is often to trade off the pain of specialized types versus the pain of dependency injection.

Title: Can encapsulation be implemented by proper types rather than accessors?

Body:
Interesting question came up while designing interfaces at work, now resolved, but I want to ask about the theory behind it.

Is it incorrect to say that properly typed data members of a class provide encapsulation? (e.g. a Boost Units type that has conversions well defined between other like units, not a typedef'd/boxed uint64_t)

```<code>struct Ruler
{
    Length length;
    Length tick_size;

    Ruler(Length length, Length tick_size);
    // Why not have helpers immediately related to the class, let's
    // stick in an alternative constructor
    Ruler(Length length, int number_ticks);

    // Accessors for # tick marks, because it needs transformed
    // to/from length and tick_size
    int GetNumberTicks(void);
    // This specific example breaks down with this function,
    // but I don't think it's an inherent issue with the design.
    // I need an overload so it will know which of the two member
    // variables to calculate... problem is both are Length
    void SetNumberTicks(int nticks);
}
</code>```

vs

```<code>struct Ruler
{
    Ruler(Length length, Length tick_size);
    Ruler(Length length, int number_ticks);

    // General accessors
    Length GetLength(void);
    void SetLength(Length length);

    Length GetTickSize(void);
    void SetTickSize(Length length);

    // Calculated accessors, see above
    int GetNumberTicks(void);
    void SetNumberTicks(int nticks);

private:
    Length length;
    Length tick_size;
}
</code>```

IMO the first encourages cleaner design by consumers and doesn't encourage pulling in slightly related, but probably attached to the wrong object member functions (eg CanMachineCreateRuler() ). I don't really have the words to describe this properly and I may be misunderstanding the additional utility that the accessors/private data combination provide.


问:
Ship of Theseus applied to GPL - Can I relicense my program if I replace all of the derivative parts?
I translated a GPLv2 C program to Python, but found it was hard to extend as designed and rewrote significant portions of it. The program is now structurally completely different, but there are several verbatim translated functions in use.

The Ship of Theseus Paradox (as stated from Wikipedia) "raises the question of whether an object which has had all its components replaced remains fundamentally the same object."

If I did manage to write replacements for the verbatim functions, would I be able to relicense to a license I prefer?

Related, would I be able to pull the evolved architecture out and reuse it with a different license? I think it would be very useful on its own, but do not like the idea that it is now "tainted" with the GPL license.

Followup: I decided to contact the copyright holder and received permission to relicense.  Sometimes the best way is to interact socially rather than programmatically!

答:
The short answer is that you cannot know.

When you talk with Richard, you find he is "crazy like a fox" in many of his implementations.  The GPL is written specifically to have ambiguities and unclear phrasings.  These are generally expressed against the benefit of the license writer but also give your IP lawyer concerns.  Cleverly, it gives your IP lawyer increasing concerns as the company gets bigger.   A small commercial enterprise doing the "reasonable interpretation" of the GPL might be an acceptable risk, but a large software company might find it more prudent to burn an entire team that managed to get a taint of GPL.

There is no answer.  There will not be an answer.  That is the answer.


问:
Sentence Word-Grading Algorithm
I need an algorithm to detect incorrect answers in memorization of sentences. Confused? Let me show you. I need to repeat the following sentence by memorization:

The quick brown fox jumps over the lazy dog.

My memorized version (this is an example, people) is this:

Quick the brown fox jumped over my lazy fat dog.

If YOU compare the following sentences, you would say that out of 10 possible points (number of words), I would miss 4 points (6/10). First, I switched "quick" and "the" around, misspelled "jumps" as "jumped", misspelled "the" as "my", and added the extra word "fat". Now what I am looking for is a sequence, or algorithm, for a computer to do this. At first I though removing each of the words that was found, regardless of their position, and then taking the higher number of words left on the correct and incorrect side, like this. Below would be left after removing the found words.

___ _____ _____ ___ jumps ____ the ____ ___. (correct side)

_____ __ _____ ___ jumped ____ my ____ fat ___. (incorrect side)

This algorithm would tell me I missed 3 points, since the incorrect side had 3 words left. It missed the swap of "quick" and "the".

If I demanded that each word be in the right place, the following would happen:

The quick _____ ___ jumps ____ the ____ dog.

Quick the _____ ___ jumped ____ my ____ fat dog.

I would have lost 6 points for this, instead of 4. Notice how it does not catch the swap of "the" and "quick", as well as the offset of "dog" just because I added a word, I lost 2 points for that one.

A couple more tests for you, if you do find an algorithm: (my answers)

Brown quick foxes jump over the dog. (miss 5)

The quick and fast fox jumps over my incredibly lazy dog. (miss 4)

Dog lazy the over jumps fox brown quick the. (miss 9, I misplaced all except for one of them as the anchor).

As well, if you think there's a better "grading method" when memorizing sentences, make them known.

答:
This will end up being domain specific.  It is likely to be a set of different engines each contributing part of the score.

You can compute weights to "is this misspelled" by Soundex or
double metaphone.  Alternately, look at Norvig's blog.

You then answer questions like "how close is the word order" (Levingston or Hamming), are unusual words present (meaning "lazy" but not "the"), and so on.  Apply a scoring value to the output.  For extra credit, see who then uses the underlying knowledge correctly and feed it back into the weighting algorithm.

The weighting must be domain specific.  For example, in the Nuclear War domain, you want nuclear launch codes to exactly perfect, targeting lat/long needs the several few digits to be accurate, but the target city name just needs to be understood, e.g., "Saint Pete's" is fine for "St. Petersburg, Russia".  The precision needed is what is needed for "success".

Title: Sentence Word-Grading Algorithm


答:
The second one is completely useless- the setters do nothing but allow the user to do what he could already do, namely mutate the instance. He can simply assign a new Ruler to it at any time.

Also, those computed getters don't really mean much as members, they should really be free functions.

Fundamentally, Ruler has no hidden state, so it's just a helper and the design doesn't really matter that much- the interface should just be as clean and simple as possible, so I would favour the first.


问:
What is the bug workflow on your agile/Scrum team?
What is the bug workflow on your agile/Scrum team?

Here is ours:
- If the bug is related to a story in the current sprint, we fix it.
- If the bug is not related to a story in the current sprint and it is not critical, it is sent to the product owner for prioritization.
- If the bug is not related to a story in the sprint and it is critical, we fix it.

答:
We do ongoing defect work. Similar to your setup, if there is a critical issue related to current work, we fix it as part of the work. After all, can't call a story "done" if there's a defect related to it.

For other bugs, we generally fix them as time allows. If there are pressing issues, we pull back some stories and spend time on bug fixes before getting back to normal feature work.


问:
How can we access non static protected method in main{as we cannot access protected members by creating objects} for java?
```<code>package foo;
public  class scj{

protected  void disp()
{
System.out.println("package");
}

}
*********************

import foo.scj;
public class aq extends scj{
public static void main(String args[])
{disp();
}
}
</code>```

If disp is static , then program runs perfectly fine. But for non static it gives error that-non static members cant be referenced from static method.

答:
You can:

Make the member static, or

Make the method non-static, or

Pass the non-static state into your static method via a parameter.