千奇百怪

1) linux下printf会缓存

所以,你试试 sleep(1); printf("."); 很长时间也不会输出。还以为是sleep坏了, 添加一个printf("\n")或者fflush(stdout)可以解决。


2) bind到0.0.0.0, 对于新接入的网卡是可以收取到数据的

recv/recvfrom使用的socket句柄如果绑定的是0.0.0.0,那么对于所有的ip都是匹配的,所以说网卡的缓冲去的数据,只要是这个端口的,都可以取出来。另外新网卡插上以后,网卡驱动检查所有ip包,只要是发给自己的,都会放置到自己的缓冲区中。


3) sem_timedwait(arg1, arg2) 第一个参数是绝对时间,第二个时间是差值, 可能会sigsegv。


4) memalign(boudary, size), 第一个参数是对齐,恰恰和window实现的顺序相反。


5) 这段程序会SIGSEGV, 为什么,仔细看

#include <map>
#include <string>
#include <stdio.h>

int main(void)
{
	std::map<std::string, int> testmap;

	testmap["12.0.0.0 1234"] = 1;
	testmap["12.0.0.1 1234"] = 1;

	std::map<std::string, int>::iterator it = testmap.begin();
	char szIp [100]; short sPort = 0; // short or int !?
	sscanf(it->first.c_str(), "%s %d", szIp, &sPort);
	
	++it;
}

6) 绝对时间的事件等待

错误的代码:

	struct timespec abstime = {time(0) + (timeoutMills / 1000), (timeoutMills % 1000) * 1000000};
	if (!sem_timedwait(pSem, &abstime))
		return 0;

正确的代码:

	struct timespec abstime; struct timeval tv;
	gettimeofday(&tv, NULL);
	abstime.tv_sec = tv.tv_sec + ((timeoutMills*1000 + tv.tv_usec)/1000000);
	abstime.tv_nsec = ((timeoutMills*1000 + tv.tv_usec) % 1000000)*1000;
	if (!sem_timedwait(pSem, &abstime))
		return 0;


7)不存在,占个位置


8) 难道a-b > 0, 就可以得到a>b吗?

uint32 a = 1, b=2;
if ( a - b > 0 ) alert("a>b?");
if ( a > b ) alert("a>b!");

9) 单核处理器读写一个字长的对齐的内存是原子的

其他情况不是,小于一个字长,需要先读出一个字长,在写回一个字长。 多核处理器即使是对齐的字长区域也不是原子的,因为其他处理器可能使用自己的缓存,使用lock可以保证原子性。原子整数读写是操作系统所有同步和互斥机制的基础。


10) 有一个代码获取linux下从纪元开始的毫秒数

return (long)(now.tv_sec*1000 + now.tv_usec/1000);
正确的代码是

	long ms = now.tv_sec;
	ms *= 1000;
	ms += now.tv_usec/1000;
	return ms;
有什么差别看出来了吗?

11) 杀毒软件,360会干扰malloc的分配。


12)  64bit字面值

uint64 x = 0x9590BD2B6EF7FE8C; // warning. not long enough!
uint64 y = 0x9590BD2B6EF7FE8Cull;


13) 这样的编译问题:

“was created with an older compiler than other objects;” 请禁用连接时代码生成,否则cl生成的代码会被link程序修改。或者所有依赖的库全部统一参数重新编译, e.g. log4c。


14) NetMeter 永久试用方法1

原理关键在于注册表
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced项下面一个名为ShellExStateN的值,初次运行软件时就会将当前系统日期换算成秒写进这个键值,以后每次打开该软件,都会读取该值与当前时间比较,每隔两天提醒一次,跟上图一样,30天以后就彻底不能用了。
http://bbs.pediy.com/showthread.php?t=102531&viewgoodnees=1&prefixid=phpforce_20

15) win7 x64 使用rundll32.exe调试dll的时候失败,为什么呢?

请使用syswow64下面的rundll32.exe 来启动调试。

16) windbg 启动调试

cd /d %~dp0
set workpath=%cd%
"C:\Program Files (x86)\Debugging Tools for Windows (x86)\windbg.exe" -srcpath "%workpath%\..\src" -y "%workpath%" %SystemRoot%\system32\rundll32.exe "%workpath%\libdecklink.dll" StartPlayback

17) windows时间获取函数精度不够,无法达到毫秒级别。

#ifdef _WIN32
static uint64 getSysTime64once()
{
	uint64 tmNow = 0;
	struct _timeb timebuffer;

	_ftime(&timebuffer);
	tmNow = timebuffer.time;
	tmNow *= 1000;
	tmNow += timebuffer.millitm;
	return tmNow;
}
static uint64 getSysTime64()
{
	static uint64 initmsec = 0;
	static LARGE_INTEGER freq;
	static LARGE_INTEGER now;
	if (initmsec == 0){
		QueryPerformanceFrequency(&freq);
		QueryPerformanceCounter(&now);
		initmsec = getSysTime64once();
		return initmsec;
	}else {
		LARGE_INTEGER testtime;
		QueryPerformanceCounter(&testtime);
		return initmsec + static_cast<uint64>(1.0 * (testtime.QuadPart - now.QuadPart)/freq.QuadPart*1000);
	}
}
#else
static uint64 getSysTime64()
{
	uint64 tmNow = 0;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	tmNow = tv.tv_sec;
	tmNow *= 1000;
	tmNow += tv.tv_usec/1000;
	return tmNow;
}
#endif

18) windows高频计数器api查询系统时间的错误


(1),在多核处理器上,结果不准,可以考虑每次调用前使用线程亲和api指定cpu核。
http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms686247(v=vs.85).aspx
static uint64 getSysTime64()
{
	static DWORD dwProcNum = 0;
	if (dwProcNum == 0){
		SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo);
		dwProcNum = sysInfo.dwNumberOfProcessors;
	}
	if (dwProcNum > 1){
		SetThreadAffinityMask(GetCurrentThread(), 1);
	}
	//...
(2), 另外系统本地时间也是会漂移,不信的话,运行一个ntpd,然后对比上面的cpu计数得到的时间和ntp修正过的本地时间看看。
运行ntp以后,使用系统时间api就可以获取系统时间了。
	uint64 tmNow = 0;
	struct _timeb timebuffer;

	_ftime(&timebuffer);
	tmNow = timebuffer.time;
	tmNow *= 1000;
	tmNow += timebuffer.millitm;
	return tmNow;

19) dumpbin /exports显示dll的导出函数名

如果当前dll目录下有pdb文件,dumpbin会读取并参考导出函数的内部名称。

20) window上的一个脚本,双击就是不执行,能气死司马懿

::test.exe –i %group% –d -f %card%
.\test.exe -i %group% -d -f %card%
用winhex一看,原来-d前面的那个-号是一个中文的减号,编码0xA843,而真正的英文的减号是0x2d。
一定要选择一个能够区分中文和英文输入法的编辑器来写脚本,我用的notepad++结果就是看不出来。


21) udp的系统收取速度和自己统计出来的速度相差很大。

在windows的资源管理的网络便签,以及linux的iftop -i eth0里面都可以看到
linux端的发送已经查过100M了,windows这里的接收也超过100M了,但是代码里面自己收取的字节数除总时间得到的带宽却只有half左右,
原来是系统的udp收取缓冲区太小了,linux默认大概是64K左右吧,windows估计也差不多吧,导致已经进入系统缓冲区udp包不停的被冲掉。
修改代码,设置缓冲区大小:
static int Tvup_SetSockSendBuf(int sockfd, uint32 bufsize)
{
	int sendbuff = bufsize; 
	socklen_t optlen = sizeof(sendbuff);
	return setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sendbuff, sizeof(sendbuff));
}

static int Tvup_SetSockRecvBuf(int sockfd, uint32 bufsize)
{
	int recvbuff = bufsize; 
	socklen_t optlen = sizeof(recvbuff);
	return setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&recvbuff, sizeof(recvbuff));
}

设置成2M基本够用了
	Tvup_SetSockRecvBuf(m_nIncomingUdpSocket, SIZE_1M*2);

22) 创建一个可以被本机其他用户访问的的事件对象

	HANDLE CreateRecordEvent(void){
	#ifdef WIN32
		// Initialize a security descriptor.  
		PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); 
		if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {  
			return NULL;
		}

		// Add the ACL to the security descriptor. 
		if (!SetSecurityDescriptorDacl(pSD, 
			TRUE,     // bDaclPresent flag   
			NULL,     // All Access By EveryOne
			FALSE))   // not a default DACL 
		{  
			return NULL;
		} 

		SECURITY_ATTRIBUTES sa; memset(&sa, 0, sizeof sa);
		sa.nLength = sizeof(sa); sa.bInheritHandle = false; 
		sa.lpSecurityDescriptor = pSD;

		HANDLE hEvt = CreateEventA(&sa, FALSE, FALSE, "\\Global\\DeclinkRecordEvent");

		return hEvt;
	#endif
		return NULL;
	}

\Global\Something这样的命名方式,只是让其他进程(包括其他用户的进程)都可以看见,但是只有创建者本身创建的其他进程才可以在其他调用SetEvent等api对这个对象进行修改,其他用户创建的进程没有权限访问。如果希望其他用户可以访问,需要设置DACL,具体的访问控制列表。

23) gentoo 找不到网卡eth0


eth0的设备驱动已经加载,设备以及创建,但是就是找不到eth0,导致net.eth0无法初始化网络。

跟踪dmesg发现那个,udev会把eth0重命名。

从udev v197开始就有这个功能,参考这个:

但是这也有一些不方便。
解决办法,touch一个空的命名规则文件,

touch /etc/udev/rules.d/80-net-name-slot.rules

好了,熟悉的eth0又出现了。

24) windows蓝屏(BSOD, blue screen of death)的原因


1)、运行在内核模式下的设备驱动程序或者操作系统函数引发了一个未被处理的异常,比如内存访问违例(由于企图写一个只读页面或者企图读一个当前未被映射的内存地址(即无效地址)而引起)。

2)、调用一个内核支持例程导致了重新调度,比如当中断请求级别(IRQL)为DPC/Dispatch级别或更高级别时等待一个标记为需要等待的调度对象。

3)、在DPC/Dispatch级别或更高的IRQL级别时由于数据存在于页面文件或内存映射文件中而发生了页面错误(Page Fault)。(这将要求内存管理器必须等待一个I/O操作发生。但正如上面一项所说,在DPC/Dispatch级别或更高IRQL级别上不能够进行等待,因为那将要求一次重新调度)。

4)、当检测到一个内部状态表明数据已遭受破坏或者在保证数据不被破坏的情况下系统无法继续执行时,设备驱动程序或操作系统函数明确地要求系统崩溃(通过调用系统函数KeBugCheckEx)。

5、发生硬件错误,比如处理器的计算机检查异常功能(Machine Check)报告有异常或者发生不可屏蔽中断(NMI)。


25) netmeter v3.6 永久试用


C:\Users\Administrator>reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /f /v ShellExStateN


26)交叉编译的一些故事

./ide/bin/i686-w64-mingw32-gcc  调用  ./ide/i686-w64-mingw32/bin/gcc  完成编译,用户不从从命令行执行后者,所以,一般都是把前者的路径添加的环境变量中。

交叉工具链的命名规则
$ ct-ng list-samples
Status  Sample name
[G.X]   alphaev56-unknown-linux-gnu
[G.X]   alphaev67-unknown-linux-gnu
[G.X]   arm-bare_newlib_cortex_m3_nommu-eabi
[G.X]   arm-cortex_a15-linux-gnueabi
[G..]   arm-cortex_a8-linux-gnueabi
[G..]   arm-davinci-linux-gnueabi
[G..]   armeb-unknown-eabi
[G.X]   armeb-unknown-linux-gnueabi
[G.X]   armeb-unknown-linux-uclibcgnueabi
[G..]   arm-unknown-eabi
[G..]   arm-unknown-linux-gnueabi
[G.X]   arm-unknown-linux-uclibcgnueabi
[G.X]   armv6-rpi-linux-gnueabi
[G.X]   avr32-unknown-none
[G..]   bfin-unknown-linux-uclibc
[G..]   i586-geode-linux-uclibc
[G.X]   i586-mingw32msvc,i686-none-linux-gnu
[G.X]   i686-nptl-linux-gnu
[G.X]   i686-unknown-mingw32
[G.X]   m68k-unknown-elf
[G.X]   m68k-unknown-uclinux-uclibc
[G.X]   mips64el-n32-linux-uclibc
[G.X]   mips64el-n64-linux-uclibc
[G.X]   mips-ar2315-linux-gnu
[G..]   mipsel-sde-elf
[G..]   mipsel-unknown-linux-gnu
[G.X]   mips-malta-linux-gnu
[G..]   mips-unknown-elf
[G.X]   mips-unknown-linux-uclibc
[G..]   powerpc-405-linux-gnu
[G.X]   powerpc64-unknown-linux-gnu
[G..]   powerpc-860-linux-gnu
[G.X]   powerpc-e300c3-linux-gnu
[G.X]   powerpc-e500v2-linux-gnuspe
[G..]   powerpc-unknown_nofpu-linux-gnu
[G..]   powerpc-unknown-linux-gnu
[G..]   powerpc-unknown-linux-uclibc
[G.X]   s390-ibm-linux-gnu
[G.X]   s390x-ibm-linux-gnu
[G..]   sh4-unknown-linux-gnu
[G..]   x86_64-unknown-linux-gnu
[G..]   x86_64-unknown-linux-uclibc
[G.X]   x86_64-unknown-mingw32
 L (Local)       : sample was found in current directory
 G (Global)      : sample was installed with crosstool-NG
 X (EXPERIMENTAL): sample may use EXPERIMENTAL features
 B (BROKEN)      : sample is currently broken

http://www.crifan.com/files/doc/docbook/cross_compile/release/html/cross_compile.html

arch-vendor-kernel-system

27) Women Drivers( sorry, no gender-biase, it's theory about possibility)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: ,且不同类型的括号不能交叉使用。 例如,"()"、"(())"、"()()"、"((()))" 都是合法的括号组合,而"())"、"(()"、"(())(" 都不是合法的括号组合。 输入一个括号组合,判断其是否合法。 输入格式: 共一行,一个字符串,表示需要判断的括号组合,字符串中只包含括号字符。 输出格式: 共一行,一个字符串,"YES" 表示输入的括号组合是合法的,"NO" 表示输入的括号组合是不合法的。 输入样例1: (()) 输出样例1: YES 输入样例2: ())( 输出样例2: NO 输入样例3: ()()() 输出样例3: YES 输入样例4: ((())) 输出样例4: YES 输入样例5: ()()(())((())) 输出样例5: YES 输入样例6: ((()()(())))(((()))) 输出样例6: YES ### 回答2: 括号的组合确实千奇百怪,但是要判断一个括号组合是否合法,它必须满足以下要求:每个同类型的左括号必须有与之对应的同类的右括号以正确的顺序闭合。 举个例子来说,对于括号组合"([])",其中包含了一个"("和一个")",以及一个"["和一个"]",它们是一一对应且正确闭合的。因此,这个括号组合是合法的。 再举个例子,对于括号组合"({)}",其中包含了一个"("和一个")",以及一个"{"和一个"}",但是它们的顺序不能正确闭合,因为"{"后面应该是与之对应的"}",而不是")"。因此,这个括号组合是不合法的。 判断括号组合的合法性可以通过使用栈的数据结构来实现。遍历括号组合,如果遇到左括号,则将其压入栈中;如果遇到右括号,则与栈顶元素进行匹配。如果匹配成功,将栈顶元素出栈。最后,如果栈为空,表示括号组合合法;如果栈不为空,表示括号组合不合法。 需要注意的是,这种方法只适用于只包含括号的简单情况,并且括号的排列顺序是有关系的。对于复杂的表达式,需要将该表达式转化为后缀表达式或者使用递归的方法进行判断。 总之,判断括号组合是否合法需要根据每个同类型的左括号是否有与之对应的同类的右括号以正确的顺序闭合来决定。利用栈的数据结构可以实现这一判断。 ### 回答3: 括号的组合确实是千奇百怪的,但是它们是否合法是有一定规则可循的。合法的括号组合要求每个同类型的左括号必须有与之对应的同类的右括号以正确的顺序闭合。 例如,"()" 组合是合法的。其中左括号 "(" 有与之对应的右括号 ")",且它们以正确的顺序闭合。 再例如,"(())" 也是合法的。在该组合中,两个左括号 "(" 分别有与之对应的右括号 ")",它们同样以正确的顺序闭合。 然而,"())(" 是非法的括号组合,因为第一个右括号 ")" 没有与之对应的左括号 "(",违反了正确的闭合顺序。 同理,"((())" 也是非法的,因为最后一个左括号 "(" 没有与之对应的右括号 ")",同样违反了正确的闭合顺序。 对于更复杂的括号组合,我们可以通过逐个匹配每个左括号和其对应的右括号,检查它们是否以正确的顺序闭合。对于合法的组合,每次匹配都会成功,直到所有的括号都匹配完成。 总之,括号的合法性是根据每个同类型的左括号是否有与之对应的同类的右括号以正确的顺序闭合来判断的。通过仔细的匹配和检查,我们可以确定一个括号组合是否合法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值