September 2019

代码一分钟,Debug半小时 之 牛客网在线编程防坑集锦

1. 刚开始做题极容易忽略的一个问题,对极端条件的判定,如果传进来的是空值,如空数组,空指针等如何处理,一般报错栈溢出,段错误除了非法访问,数组越界等,很可能是没有对空值这种极端情况进行处理。

2.测试数据可能有很多组,但是每组之间根本不会有EOF结尾,全部都是连在一起的,导致本地都对,在线测试怎么都错!!所以一般读取是否结束要根据它的数量来判定,最外层才是采用EOF判定。

3.内存超限,可能原因是忘了给函数返回值,导致测试端检查该值时发生非法访问等相关原因。

4.返回变量没有赋初值,导致程序逻辑本身正确,中途正解为没有对返回变量赋任何值,逻辑上是返回空值,但没有初始化导致错误发生,返回随机值。

5.在函数内使用static变量,而且在程序的整个生存周期内没有对其置位清零产生意想不到的结果,解决办法:可以放在类public中做一般变量来解决。

6.题述只说了参数是整数,要注意处理负数时的情况。如3的整数次方,可能是 $3^{-2}$

7.含有链表的题目,记得标记尾部节点

8.链表中,LinkNode *tmp, *x;  tmp = node.next;  tmp = x; 与 node.next = x 代表的意思是完全不同的,第一种表达方式 是tmp先指向node.next,再指向新的链表节点x(而不是让x链接到node的后面,如果要实现这个功能,在此方法下需要使用二级指针),而第二种是让x链接到node的后面。

9.包含数字处理的,注意溢出,如int型范围在-2147483648-2147483647

 

中途发现还有其他问题再来补充,不得不说牛客网的OJ是真的操蛋,让我们专注逻辑不好么,还要操心其他乱七八糟的。

 

 …

Continue reading...

C语言快速排序笔记

复习了一下快速排序的算法,改变了书本上的部分逻辑,顺便加上了注释以备忘

Continue reading...

Gtk窗口在某些情况下无法聚焦窗口的分析与解决办法

(Gtk window focus failed when opened more than one times in one thread)

 

一. 背景:

 

在做Linux取词翻译软件的时候,UI编程使用的是Gtk,翻译界面的逻辑代码被放置于某个线程内,途中会进行多次的创建与销毁,Gtk窗口除了第一次能够成功聚焦,之后就再也无法成功,写了短小的测试用例,发现每次进行进程创建可以保证窗口聚焦。

但是考虑到各个线程中众多的共享数据,另开进程进行数据通信的代价太过于大,主要是进程有独立的地址空间,彼此间通信要借助IPC的方式,而且无论是代码的重构还是之后的调试都将耗费巨大的精力。

 

二. 解决过程:

 

而后开始寻找解决办法,尝试了好几个小时在Gtk内部查找问题,换了或增加了各种各样的窗口聚焦相关代码,仍旧不可行。

接着想到了另一个突破口,平时Alt-tab键可以进行窗口切换,本质就是聚焦窗口的改变,巡着这条路想起xdotool好像有这个功能可以激活特定窗口(亦即聚焦窗口)。

然后在终端尝试了一下,果然,用 xdotool windowactivate <窗口id>可以激活窗口!马上阅读源码,很快找到了相关实现的函数,在里面添加了些log的打印进行进一步定位,或者注释掉一些可能实际起作用的代码后,程序窗口激活功能即刻失效,由此得到几行关键代码:

Continue reading...

Arch Linux下蓝牙无线鼠标有点延迟、有点漂的解决办法

总共尝试了两种办法

 

1.利用nice命令行提高进程的优先级

 

2.采用Arch wiki上的解决办法

Troubleshooting

Mouse lag

If you experience mouse lag you can try to increase the polling rate. See Mouse polling rate for more information.

You can try to set the minimum/maximum latency for the mouse in BlueZ [1]:

Add or modify the following section in /var/lib/bluetooth/<mac-of-your-adapter>/<mac-of-your-mouse>/info (adapt the path accordingly):

 

第一个办法影响不大,加上第二个后效果很明显。

修改配置后需要执行如下命令(最高权限执行):

 …

Continue reading...

记一次Gtk编程遇到问题的解决过程 (GtkSearchEntry绑定新的快捷键,信号发生快捷键)

最近用到GtkSearchEntry的编程,其中一个信号是stop-search,对应绑定的默认快捷键是ESC,一般捕获为退出信号,感觉不顺手,想绑定到Ctrl-C,中途遇到了问题,查看全网没有发现解决方案,但是从StackOverFlow的这篇文章里找到一点灵感 Gtk3 keys bindings in css files。特此记录此问题的解决过程和思路。

查看Gtk开发手册,如下:

The  stop-search signal

The ::stop-search signal is a keybinding signal which gets emitted when the user stops a search via keyboard input.

Applications should connect to it, to implement hiding the search entry in this case.

The default bindings for this signal is Escape.

Parameters

entry the entry on which the signal was emitted
user_data user data set when the signal handler was connected.

Flags: Action

Since: 3.16

通过描述可以看到stop-search是键盘绑定信号,用户输入特定键盘触发后发射出该信号。

点进 keybinding signal ,找到文章开头的一些函数:

void gtk_binding_entry_add_signall ()
GtkBindingSet * gtk_binding_set_new ()
GtkBindingSet * gtk_binding_set_by_class ()
GtkBindingSet * gtk_binding_set_find ()
gboolean gtk_bindings_activate ()
gboolean gtk_bindings_activate_event ()
gboolean gtk_binding_set_activate ()
void gtk_binding_entry_add_signal ()
GTokenType gtk_binding_entry_add_signal_from_string ()
void gtk_binding_entry_skip ()
void gtk_binding_entry_remove ()
void gtk_binding_set_add_path ()

其中看着比较像的是gtk_binding_entry_add_signal (),点进去看函数原型:

gtk_binding_entry_add_signal ()

Override or install a new key binding for  keyval with  modifiers on  binding_set . When the binding is activated,  signal_name will be emitted on the target widget, with  n_args  Varargs used as arguments.

Each argument to the signal must be passed as a pair of varargs: the GType of the argument, followed by the argument value (which must be of the given type). There must be  n_args pairs in total.

 

keyval(键值),modifiers(修饰符),和signal_name(信号名)容易知道,比如我想要绑定到Ctrl-C,那么keyval就是c,modifiers就是control,signal-name就是stop-search,但是写法可能要替换成一些特定的宏,这些问题不大,从gtk的源码中找到规律,keyval一般写成 GDK_KEY_c 这种格式,Control写成 GDK_CONTROL_MASK , signal-name还是原来的字符串不用变。

问题最大的是GtkBindingSet如何获取,它的原型是一个结构体,里面包含很多变量,我们不可能自己定义一个,因为这在Gtk源码中肯定已经定义过了,目的到现在变成了如何获取这个GtkBindingSet。

再细看上面的一些函数,其中有3个返回值都是GtkBindingSet,大概率是从这里入手,通过名称可以排除包含new的函数,因为是获取已有的,而不是new一个新的,剩下两个通过对比确定为如下目标函数:

gtk_binding_set_by_class ()

This function returns the binding set named after the type name of the passed in class structure. New binding sets are created on demand by this function.

Parameters

object_class a valid GObject class

Returns

the binding set corresponding to  object_class .

至于为什么选这个,首先从它的内部传参可以看出,只需要传进一个有效的GObject class 即可。

因此,问题再进一步,变成:如何获取GObject class

到这里,感觉离目标已经越来越接近,但是对于Gtk Class了解不够,且不太懂得该如何获取,其内部机制也不了解。

一个很关键的思路转折出现了,既然GtkSearchEntry是继承自GtkEntry,那么关键突破点不应该只在GtkSearchEntry中找,很有可能在其继承的基类中存在一些我们要的结果。

 

而类名一般与部件widget名相关,即,可能对我们有帮助的类名是GtkSearchEntryClass或者是GtkEntryClass,接着我在Gtk源码根目录输入如下命令:

从输出结果中看到这么一行

Continue reading...

Python生成requirements.txt

忘了一遍又一遍,写下来吧…

安装

 …

Continue reading...

YCM 安装报错 fatal error: pyconfig.h: No such file or directory

Debian系系统试一下这个命令:

其他系统参考一下,包名可能不一样

 

YouCompleteMe unavailable: unable to load Python.
Press ENTER or type command to continue

 …

Continue reading...

find和其他命令搭配使用

1.find和mv搭配

搜索当前文件夹下的照片并移至文件夹num/下,+号是指plus version of find, 带上这个符号才可使用-exec,{}是find结果自动填充的地方,-t是mv的参数,表示target directory.

 

2.find和file搭配

找出当前文件夹下所有大于10k的文件并显示其文件类型等相关信息,如果是比指定大小要小,用符号减,即-10k

 

3.find和多种命令搭配,删除当前文件夹下同名编译出的c文件

 

4.find中的正则匹配不能直接匹配回车符,会被视为n

解决办法,采用如下输入法:

手动给它真正的回车,这个命令匹配的是文件夹./a  ./b ~  ./z 下中间带有回车符的文件名。

 

5.find查找空文件

Continue reading...

Python编写单词库爬虫解决问题记录

 

序号 问题
1 根据单词词性自动创建字段
2 不同名称但相同功能字段重复创建导致字段冗余
3 同个词性含多个不同位置的中文翻译使sql语句构造时字段重复插入
4 数据存储类型选择不合理导致数据过长无法存储
5 连接超时导致程序退出
6 随机延时访问降低IP被禁几率
7 每隔一定时间休眠程序
8 每次获取到输入后查询单词存在性花费在数据库的时间过长
9 连接错误返回结果为HTML页面,导致音频下载错误

对于1: 获取到单词属性后,比较是否已经创建对应字段,无则创之。

 

对于2: 将相同功能的字段,如 n./adj.    a./ adj.等在获取属性的时候,修改成统一的字符串存储起来,后面进行自动创建工作时才不会创建冗余字段。

 

对于3: 存储已构造sql语句中包含的字段和字段值,之后检测到获取的字段重复,如重复出现翻译的词性是 n. 则忽略此次的sql语句字段添加,并找到上一个重复的字段值,添加回车符后,将此次的翻译结果作为附加的字段值续接在其后进行插入。

 

对于4: 原来用的是varchar,改成text后解决问题

 

对于5: 需捕获超时错误,捕获成功后,重新连接,再次请求数据,为防止网络断开导致死循环,可以添加网络未重连成功的次数,超过一定次数退出程序或者延迟一段时间再进行重连,重连成功后清零该计数值。

 

对于 6 & 7: 用random模块来解决,并计数当前获取的单词数量,超过一定数量,进行长时休眠(10s~30s),然后清零单词数量计数值

 

对于8: 选择一次性获取全部sql数据中的单词,并保存在一个list中,以后每成功写入一个翻译结果,将此新单词附加到list中,用于未来比较。

 

对于9:  用命令 file <filename>检测文件内容是否为HTML,如果是,返回获取音频的函数,进行重新下载,设置最大尝试次数,超过则退出或者放弃本次操作继续执行程序的其他部分。…

Continue reading...

终端快捷键记录

快捷键 移动光标快捷键
ctrl+f 向前移动一个字符
ctrl+b 向后移动一个字符
alt+f 向前移动一个单词
alt+b 向后移动一个单词
ctrl+a 移动到当前行首
ctrl+e 移动到当前行尾
ctrl+l 清屏

 

快捷键 编辑命令行快捷键
ctrl+d 删除当前字符
ctrl+t 交换前后字符
alt+u 把当前单词全变成大写
alt+c 大写当前单词首部

 

快捷键 剪切、粘贴快捷键
ctrl+k 剪切文本直到行的末尾
ctrl+u 剪切文本直到行的起始
ctrl+w 剪切光标前的单词
alt+d 剪切光标后的单词
ctrl+y 粘贴最近剪切的文本
alt+y 回退到先前剪切的文本并粘贴它

 

 

快捷键 撤销操作
Ctrl-7 撤销
Continue reading...