小编Amu*_*umu的帖子

控制反转与依赖注入

根据Martin Fowler撰写论文,控制反转是程序控制流程被颠倒的原则:代替程序员控制程序流程,外部源(框架,服务,其他组件)控制它.这就像我们把东西塞进别的东西.他提到了一个关于EJB 2.0的例子:

例如,会话Bean接口定义ejbRemove,ejbPassivate(存储到辅助存储)和ejbActivate(从被动状态恢复).你无法控制何时调用这些方法,只是它们的作用.容器打电话给我们,我们不打电话给它.

这导致框架和库之间的区别:

控制反转是使框架与库不同的关键部分.库本质上是一组可以调用的函数,这些日子通常组织成类.每个调用都会执行一些操作并将控制权返回给客户端.

我认为,DI是IOC的观点,意味着对象的依赖性被颠倒了:相反,它控制着自己的依赖关系,生命周期......还有其他东西为你做.但是,正如你用手告诉我的DI,DI不一定是IOC.我们仍然可以有DI而没有IOC.

然而,在本文中(来自pococapsule,另一个IOC C/C++框架),它表明,由于IOC和DI,IOC容器和DI框架远远优于J2EE,因为J2EE将框架代码混合到组件中因此不能成为普通的旧Java/C++对象(PO​​JO/POCO).

除依赖注入模式之外的控制容器的反转(存档链接)

附加阅读以了解旧的基于组件的开发框架的问题是什么,这导致了上面的第二篇论文:为什么以及什么是控制反转(存档链接)

我的问题:IOC和DI究竟是什么?我很迷惑.基于pococapsule,IOC比仅仅反转对象或程序员和框架之间的控制更重要.

dependency-injection inversion-of-control

467
推荐指数
14
解决办法
26万
查看次数

[N ... M]在C聚合初始化器中的含义是什么?

sys.c第123行:

void *sys_call_table[__NR_syscalls] = 
{
    [0 ... __NR_syscalls-1] = sys_ni_syscall,
#include <asm/unistd.h>
};
Run Code Online (Sandbox Code Playgroud)

sys_call_table是一个指向数组的通用指针,我可以看到.但是符号是什么:

[0 ... __NR_syscalls-1]
Run Code Online (Sandbox Code Playgroud)

什么是...


编辑:
我在这里学到了另一个C技巧:#include <asm/unistd.h>将被预处理并替换为其内容并分配给[0 ... _NR_syscalls-1].

c linux kernel

101
推荐指数
1
解决办法
2850
查看次数

什么是uint_fast32_t以及为什么要使用它来代替常规int和uint32_t?

因此,对于其原因typedef:ED原始数据类型是抽象低级别表示,并使其更容易理解(uint64_t而不是long long类型,这是8个字节).

但是,有uint_fast32_t与之相同typedefuint32_t.使用"快速"版本会使程序更快吗?

c c++ types

99
推荐指数
3
解决办法
4万
查看次数

initrd和initramfs之间的区别?

据我所知,initrd充当块设备,因此需要文件系统驱动程序(如ext2).内核必须至少有一个用于检测文件系统的内置模块initrd.在本文中,介绍了初始RAM磁盘的新模型initramfs,它写成:

但是由于缓存,ramdisks实际上浪费了更多的内存.Linux旨在缓存从块设备读取或写入的所有文件和目录条目,因此Linux将数据复制到ramdisk和从"ramdisk"复制到"页面缓存"(用于文件数据)和"dentry cache"(用于目录条目) .假装是块设备的ramdisk的缺点是它被视为块设备.

什么page cachedentry cache?在段落中,是否意味着数据被复制,因为ramdisk被视为块设备,因此所有数据都被缓存?

相反,ramfs:

几年前,Linus Torvalds有一个很好的想法:如果Linux的缓存可以像文件系统一样挂载怎么办?只是将文件保存在缓存中,永远不要删除它们,直到它们被删除或系统重新启动?Linus在缓存周围写了一个名为"ramfs"的小包装器,其他内核开发人员创建了一个名为"tmpfs"的改进版本(它可以将数据写入交换空间,并限制给定挂载点的大小,以便在消耗之前填满所有可用的内存).Initramfs是tmpfs的一个实例.

这些基于ram的文件系统会自动增长或缩小以适应它们包含的数据大小.将文件添加到ramfs(或扩展现有文件)会自动分配更多内存,删除或截断文件会释放该内存.块设备和缓存之间没有重复,因为没有块设备.缓存中的副本是数据的唯一副本.最重要的是,这不是新代码,而是现有Linux缓存代码的新应用程序,这意味着它几乎不增加任何大小,非常简单,并且基于经过严格测试的基础架构.

总之,ramfs只是文件打开并加载到内存中,不是吗?

二者initrdramfs在编译时拉链,但不同的是,initrd被分解到由在启动内核被安装,而块设备ramfs经由的cpio解压到存储器中.我对么?或者是ramfs一个非常小的文件系统?

最后,直到今天,initrd图像仍然显示在最新的内核中.然而,这initrd实际上是ramfs今天使用的,这个名字只是出于历史目的吗?

linux filesystems boot kernel

56
推荐指数
4
解决办法
4万
查看次数

实际上是$ RPM_BUILD_ROOT?

在构建RPM包的过程中,我必须指定BuildRoot,稍后将在%install中使用,它将调用$ RPM_BUILD_ROOT.我一直认为$ RPM_BUILD_ROOT是RPM执行打包的虚假安装.然后,在安装时使用RPM包,它将安装到实际位置.例如:

$RPM_BUILD_ROOT/usr/bin
Run Code Online (Sandbox Code Playgroud)

我认为$ RPM_BUILD_ROOT仅用于打包过程,并且在某些方面RPM可以区分$ RPM_BUILD_ROOT和实际安装位​​置,当用户执行"rpm -ivh package.rpm"时将是/ usr/bin.

但是最近在阅读一些文档时,建议$ RPM_BUILD_ROOT是将要安装的实际位置,并且$ RPM_BUILD_ROOT由用户使用环境变量$ RPM_BUILD_ROOT的设置指定,以便让用户在他们的愿望中安装包位置.否则,$ RPM_BUILD_ROOT将为null,它将安装到默认位置.在上面的例子中,它是/ usr/bin.因此,$ RPM_BUILD_ROOT不仅适用于打包或"虚假安装"过程,而且是用户定义安装位置的一种方式,类似于Windows中的选择文件夹位置.

我不知道我的想法是否正确.有人可以验证吗?提前致谢.

linux packaging rpm

31
推荐指数
2
解决办法
3万
查看次数

如何创建带文件孔的文件?

文件孔是文件中的空白空间,但不占用任何磁盘空间并包含空字节.因此,文件大小大于磁盘上的实际大小.

但是,我不知道如何创建带有文件孔的文件进行试验.

c linux

20
推荐指数
3
解决办法
2万
查看次数

如何在Makefile中隐藏编译消息?

我编译的linux内核只打印消息:

CC  .....
LD [M] ....
Run Code Online (Sandbox Code Playgroud)

如何隐藏由make输出的编译消息并输出我想要的内容?我在哪里可以找到在内核Makefile中执行此操作的代码部分?

linux makefile

19
推荐指数
1
解决办法
1万
查看次数

为什么C++中的缓冲很重要?

我试图打印"Hello World"200,000次,它让我永远,所以我必须停下来.但是在我添加一个char数组作为缓冲区后,它花了不到10秒.为什么?

在添加缓冲区之前:

#include <iostream> 
using namespace std;

int main() {
        int count = 0;
        std::ios_base::sync_with_stdio(false);
        for(int i = 1; i < 200000; i++)
        {       
                cout << "Hello world!\n";
                count++;
        }
                cout<<"Count:%d\n"<<count;
return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是在添加缓冲区之后:

#include <iostream> 
using namespace std;

int main() {
        int count = 0;
        std::ios_base::sync_with_stdio(false);
        char buffer[1024];
        cout.rdbuf()->pubsetbuf(buffer, 1024);
        for(int i = 1; i < 200000; i++)
        {       
                cout << "Hello world!\n";
                count++;
        }
                cout<<"Count:%d\n"<<count;
return 0;
}
Run Code Online (Sandbox Code Playgroud)

这让我想起了Java.使用BufferReader读取文件有什么好处?

c++ buffer

18
推荐指数
2
解决办法
2万
查看次数

如何知道RPM中内置宏的价值?

如何在RPM中查看这些宏的值?我可以猜测%_bindir是/ usr/bin,%_ tmppaht是/ tmp,但是我如何准确地查看它的值并且它的值是否取决于系统?

%_prefix 
%_exec_prefix 
%_bindir 
%_sbindir 
%_libexecdir 
%_datadir 
%_sysconfdir 
%_sharedstatedir 
%_localstatedir 
%_libdir 
%_includedir 
%_oldincludedir o in
%_infodir 
%_mandir 
/usr 
%{_prefix) 
%{_exec_prefixl/bin 
%{_exec_prefix}/sbin 
%{_exec_prefix}/libexec 
%{_prefixJ/share 
%{_prefix}/etc 
%{_prefixJ/com 
%{_prefix}/var 
%{_exec_prefix}/lib 
%{_prefix}/include 
/usr/include 
%{_prefix}/info 
%{_prefixl/man 
Run Code Online (Sandbox Code Playgroud)

linux packaging rpm

18
推荐指数
2
解决办法
8274
查看次数

为什么不允许复制构造函数按值传递?

可能重复:
为什么复制构造函数应该通过C++中的引用接受其参数?
可以将对象作为值传递给复制构造函数

考虑一下这段代码:

class complex{
        private:
                double re, im;
        public:
                complex(double _re, double _im):re(_re),im(_im){}
                complex(complex c):re(c.re),im(c.im){}
};
Run Code Online (Sandbox Code Playgroud)

编译时,我收到一条错误消息: invalid constructor; you probably meant ‘complex (const complex&)’

在书中C++ Programming Language,写道:

复制构造函数定义了复制的含义 - 包括复制参数的含义 - 所以写作

complex:complex(complex c):re(c.re),im(c.im){} //错误

是一个错误,因为任何调用都会涉及无限递归.

为什么这会导致无限递归?这没有意义.

c++ constructor

17
推荐指数
2
解决办法
2万
查看次数