Archive for 算法-编程

按照上一篇的流程 Modules/main.c里, pymain_main里pymain_init里的pymain_cmdline,是解析参数的。 初始化一个_PyCmdline,暂存参数的 line464 typedef struct { wchar_t **argv; int nwarnoption; /* Number of -W options */ wchar_t **warnoptions; /* -W options */ int nenv_warnoption; /* Number of PYTHONWARNINGS options */ wchar_t **env_warnoptions; /* PYTHONWARNINGS options */ int print_help; /* -h, -? options */ int print_version; /* -V option */ int bytes_warning; /* Py_BytesWarningFlag, -b */ int debug; /* Py_DebugFlag, -b, PYTHONDEBUG */ int inspect; /* Py_InspectFlag, -i, PYTHONINSPECT */ int interactive; /* Py_InteractiveFlag, -i */ int isolated; /* Py_IsolatedFlag, -I */ int optimization_level; /* Py_OptimizeFlag, -O, PYTHONOPTIMIZE */ int dont_write_bytecode; /* Py_DontWriteBytecodeFlag, -B, PYTHONDONTWRITEBYTECODE */ int no_user_site_directory; /* Py_NoUserSiteDirectory, -I, -s, PYTHONNOUSERSITE */ int no_site_import; /* Py_NoSiteFlag, -S */ int use_unbuffered_io; /* Py_UnbufferedStdioFlag, -u, PYTHONUNBUFFERED */ int verbosity; /* Py_VerboseFlag, -v, PYTHONVERBOSE */ int quiet_flag; /* Py_QuietFlag, -q */ const char *check_hash_pycs_mode; /* --check-hash-based-pycs */ #ifdef MS_WINDOWS int legacy_windows_fs_encoding; /* Py_LegacyWindowsFSEncodingFlag, PYTHONLEGACYWINDOWSFSENCODING */ int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag, PYTHONLEGACYWINDOWSSTDIO */ #endif } _PyCmdline; 然后调用cmdline_get_global_config,设置默认参数,默认参数都在 Python/pylifecycle.c 全为0.后面的cmdline_set_global_config是设置全局值的。两个是一对 然后调用pymain_cmdline_impl,里面调用pymain_read_conf,看了一下,主要在函数pymain_parse_cmdline_impl里面。其他的就不看了。 cmdline_get_env_flags是从环境拿值设置参数的。 pymain_init_core_argv是设置-c-m俩参数 没想到比较简单,没有细看,看的这些基本能达到目的了。有需要再补充

Continue

看Makefile.pre.in文件,入口函数在Programs/python.c文件里,发现main函数。 只调用的Modules/main.c的_Py_UnixMain函数,这里面初始化了_PyMain,用来保存参数,然后调用pymain_main 先调用pymain_init,后调用pymain_run_python,最后调用pymain_free. pymain_init里,初始化_PyCoreConfig,大体看是pyvm的一些参数,先不关心。然后调用pymain_cmdline,大体看是解析参数的,不关心。pymain_init_stdio设置了stdin_is_interactive的值,这个可能有用,先记录。然后调用_Py_InitializeCore,里边调用_Py_InitializeCore_impl,里边各种初始化,不跟进去看了。 里边调用了一个_PyImport_Init,没啥,_PyImportHooks_Init,初始化了几个sys的参数,但是都是空值, sys.meta_path, sys.path_importer_cache,sys.path_hooks,这几个有用。 _Py_InitializeCore_impl最后调用了一个initimport(, sys.modules不知道在哪初始化的,可能有用,先不找了。importlib的导入,然后是_PyImportZip_Init. _PyImportZip_Init在Python/import.c里,导入zipimport,path_hooks里加入了一个zipimport.zipimporter。搞定 回到 pymain_init, 最后调用了 pymain_init_python_main 和pymain_init_sys_path. pymain_init_python_main调用_Py_InitializeMainInterpreter好像仅仅是重新设置了一下参数,这里没看懂,从自己复制了参数设置了args,有设置了一遍。没啥用先不管了。 pymain_init_sys_path这个看名字是要找的了, 第一个是zip或者目录导入,这个有用,记录一下,暂时不会用。从参数中获取sys.path的配置,最后调用pymain_update_sys_path插入到sys.path里边 pymain_run_python中,先调用pymain_header,pymain_import_readline,pymain_run_command,pymain_run_module, pymain_run_filename, pymain_repl. pymain_header,如果是交互模式,打印了版本和操作系统。可以查到版本信息在Include/patchlevel.h pymain_import_readline 为交互模式导入readline模块。pymain_run_command,直接执行的代码。pymain_run_module执行模块的. pymain_run_filename 执行文件的。 pymain_repl 解析器模式 这部分就基本看完了,下边要单独看一下,启动参数解析的地方

Continue

这几天忙着写文档,一直看的线上环境的系统。今天启动本地测试环境,发现登录不成功。排查问题发现登录成功后,之后的请求没有携带cookie。然后我就仔细看了一下登录请求的参数。 发现在chorme header头的cookie里有一个黄色的小叹号,发现问题了。 this set-cookie didn't specify a "SameSite" attribute,然后变成默认Lax。(不能复制,懒得打英文了) 然后我搜索了一下Samesite定义,有三个值,None, Lax,Strict.这个参数是防止跨站攻击用的,因为测试环境,所以最方便就是跨站调试了。 然后我搜了一下flask源码,发现有这个设置,配置了一下发现不管用。然后放弃了。 找了一下怎么关闭chrome的这个选项,虽然别的网站可能有一点风险。自己调试的时候会方便点。 chrome://flags/#same-site-by-default-cookies chrome://flags/#cookies-without-same-site-must-be-secure 这两项设置为Disabled,并重启浏览器

Continue

搞了一个像素游戏,很小的游戏。里边的文字也不多,找个像素字体太费劲,还有版权什么的信息,就想之前看过字体数据转像素矩阵的代码。搜了一下,发现直接有点阵字体,找了代码试了一下,完全可用。 我将字体转成像素矩阵后,可以直接按像素大小把字给画出来,非常方便了,就是计算稍微多一点。 HZK16字库是符合GB2312国家标准的16×16点阵字库,HZK16的GB2312-80支持的汉字有6763个,符号682个。其中一级汉字有 3755个,按声序排列,二级汉字有3008个,按偏旁部首排列。 我们在一些应用场合根本用不到这么多汉字字模,所以在应用时就可以只提取部分字体作为己用。 HZK16字库里的16×16汉字一共需要256个点来显示,也就是说需要32个字节才能达到显示一个普通汉字的目的。 我们知道一个GB2312汉字是由两个字节编码的,范围为0xA1A1~0xFEFE。A1-A9为符号区,B0-F7为汉字区。每一个区有94个字符(注意:这只是编码的许可范围,不一定都有字型对应,比如符号区就有很多编码空白区域)。 下面以汉字「我」为例,介绍如何在HZK16文件中找到它对应的32个字节的字模数据。 前面说到一个汉字占两个字节,这两个中前一个字节为该汉字的区号,后一个字节为该字的位号。其中,每个区记录94个汉字,位号为该字在该区中的位置。所以要找到「我」在hzk16库中的位置就必须得到它的区码和位码。 区码:汉字的第一个字节-0xA0,因为汉字编码是从0xA0区开始的,所以文件最前面就是从0xA0区开始,要算出相对区码 位码:汉字的第二个字节-0xA0 这样我们就可以得到汉字在HZK16中的绝对偏移位置:offset = (94*(区码-1)+(位码-1))*32。 注解: 区码减1是因为数组是以0为开始而区号位号是以1为开始的 (94*(区号-1)+位号-1)是一个汉字字模占用的字节数 最后乘以32是因为汉字库文应从该位置起的32字节信息记录该字的字模信息(前面提到一个汉字要有32个字节显示) #include int main(void) { FILE* fphzk = NULL; int i, j, k, offset; int flag; unsigned char buffer[32]; unsigned char word[3] = "我"; unsigned char key[8] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; fphzk = fopen("hzk16", "rb"); if(fphzk == NULL){ fprintf(stderr, "error hzk16\n"); return 1; } offset = (94*(unsigned int)(word[0]-0xa0-1)+(word[1]-0xa0-1))*32; fseek(fphzk, offset, SEEK_SET); fread(buffer, 1, 32, fphzk); for(k=0; k<32; k++){ printf("%02X ", buffer[k]); } for(k=0; k<16; k++){ for(j=0; j<2; j++){ for(i=0; i<8; i++){ flag = buffer[k*2+j]&key[i]; printf("%s", flag?"●":"○"); } } printf("\n"); } fclose(fphzk); fphzk = NULL; return 0; } 使用Python读取并显示的过程如下: 根据中文字符获取GB2312编码 通过GB2312编码计算该汉字在点阵字库中的区位和码位 通过区位和码位计算在点阵字库中的偏移量 基于偏移量获取该汉字的32个像素存储字节 解析像素字节获取点阵坐标信息 在对应的坐标显示信息位。如该像素点是否显示点亮 #!/usr/bin/python #encoding: utf-8 import binascii BYTE_COUNT_PER_FONT = 32 BYTE_COUNT_PER_ROW = 2 RECT_HEIGHT = 16 RECT_WIDTH = 16 KEYS = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01] class FontRender(object): def __init__(self, font_file="hzk16s", rect_height=RECT_HEIGHT, rect_width=RECT_WIDTH, byte_count_per_row=BYTE_COUNT_PER_ROW): self.font_file = font_file self.rect_height = rect_height self.rect_width = rect_width self.byte_count_per_row = byte_count_per_row self.__init_rect_list__() def __init_rect_list__(self): self.rect_list = [] * RECT_HEIGHT for i in range(RECT_HEIGHT): self.rect_list.append([] * RECT_WIDTH) def get_font_area_index(self, txt, encoding='utf-8'): if not isinstance(txt, unicode): txt = txt.decode(encoding) gb2312 = txt.encode('gb2312') hex_str = binascii.b2a_hex(gb2312) area = eval('0x' + hex_str[:2]) - 0xA0 index = eval('0x' + hex_str[2:]) - 0xA0 return area, index def get_font_rect(self, area, index): offset = (94 * (area-1) + (index-1)) * BYTE_COUNT_PER_FONT btxt = None with open(self.font_file, "rb") as f: f.seek(offset) btxt = f.read(32) return btxt def convert_font_rect(self, font_rect, ft=1, ff=0): for k in range(len(font_rect) / self.byte_count_per_row): row_list = self.rect_list[k] for j in range(self.byte_count_per_row): for i in range(8): asc = binascii.b2a_hex(font_rect[k*2+j]) asc = eval('0x' + asc) flag = asc & KEYS[i] row_list.append(flag and ft or ff) def render_font_rect(self, rect_list=None): if not rect_list: rect_list = self.rect_list for row in rect_list: for i in row: if i: print '●', else: print '○', print def convert(self, text, ft=None, ff=None, encoding='utf-8'): if not isinstance(text, unicode): text = text.decode(encoding) for t in text: area, index = self.get_font_area_index(t) font_rect = self.get_font_rect(area, index) self.convert_font_rect(font_rect, ft=ft, ff=ff) def get_rect_info(self): return self.rect_list if '__main__' == __name__: text = u'图麟' fr = FontRender() fr.convert(text, ft='/static/*', ff=0) # print fr.get_rect_info() fr.render_font_rect()

Continue

查询语句里有个子查询,有个括号,然后就报错 unexpected token:( 发现这个异常没法查问题,就找了找跟JpaRepository子查询相关的。 有两种解决方法: 一种是@Query(value="select * from user where name like %?1" ,nativeQuery=true) 添加一个nativeQuery的参数 第二种方法是支持的是JPQL,但是我写的那个sql是不支持的。害

Continue

Java真特么的坑,一边是对象Interger,一边是int等数据结构。之前感觉还挺有用的。现在我发现基本项目里都只用对象类型,然后我也就都用这个。 想实现的功能就是Date类型的数据的减两分钟,然后把秒置0的操作。 // 日历类型操作,Date的set方法现在都废弃不用了 Calendar calendar = Calendar.getInstance(); //设置秒为0 calendar.set(Calendar.SECOND, 0); // 减去一分钟 calendar.add(Calendar.MINUTE, -1); // 转成Date类型 Date timestamp = calendar.getTime();

Continue

我要做一个东西,在spring boot的@requestBody里传了一个json数据,其中有个timestamp的字段,需要转换称java Date类型。 搞个半天我还以为成功了,然后突然发现是特么的1970年的年份,就感觉可能截断了。 搜了一下发现是需要毫秒的单位,乘了1000还是不行,后来又找了很多方法,以为只能重新写json字段解析的反序列化函数单独搞。 然后发现一个是回答的必须long型的,然后试了一下就成功了。。。 java.util.Date time=new java.util.Date((long)timeStamp*1000); time=new java.util.Date(timeStamp*1000L); Date time = new Date(TimeUnit.MILLISECONDS.convert(unixTimestamp, TimeUnit.SECONDS)); 直接改了set属性的方法就可用了

Continue

刚加完班,想想这几天学的东西挺多的,虽然都是皮毛,但感觉还挺有成就感的。 公司刚走了俩领导,留下一个坑项目,我也是刚知道。三个人开发了一年啥没开发出来,然后现在到了交付时间了。忙的从四川分公司调了俩个人。说是想三个都裁掉,然后产品说那就没人干活了,然后还把我调过去帮忙写。 项目是spring boot的,我想想我用Python写,一个是以后还得我维护,二一个,权限什么的都不好做,开始我就想只做做边角功能就行了。然后发现分给我功能不属于边角,只能Java写了。 分工还有问题,本来应该写方法的,一个流程下边的,分给俩人做,这种技术上不行,工作效率上也不行。 我这几天看了几本Springboot实战的书,基本一掠而过。知道都是什么,然后看了文档里边的几个例子,就上手写代码了。 项目代码也没有太成熟,用了一个什么renren开源的库,我问过我单独写一个模块,就见了一个Springboot 服务,都用的官方默认的模块。注册服务那里用了公用的pom之后,折腾了我一上午没搞定,我就使用官方文档推荐的starters,分分钟搞定了。 Java静态语言,又是成员变量必须private定义,写的真麻烦,发现写Java果然需要ide,能生成代码,静态语言检查语法错误也方便,复制代码,需要导入也可以自动,感觉写起来还不错。 还有一个比较麻烦的就是,解析json和返回json数据的定义。我网上查找,看了几个例子,基本就懂了。 项目里我不需要关心权限相关的,所以感觉还比较简单。 通过这几天学习,感觉Java经过发展,他相关的工具链其实已经相当的成熟了。感觉给我一年的时间熟练开发项目,我这开发效率不会比Python低,现在开发更多的是找Java或者Spring解决方法,完全不需要知道这个是怎么来的。像我用Python判断IP是否是内网IP,我有很高效的方法,可以直接找到或者复制代码,我Java写的时候,我需要看很多,找到差不多的方案,然后写成公用类。如果之前写过,就直接复制就可以了。 还有就是http返回json的封装,我看了一下他们的项目,都没有统一,比如状态码,错误信息,我就定义了自己的。因为没有看过太多代码,也没有之前写过的公司项目借鉴,我竟然从我反编译的非开源的云平台项目里复制了一个文件,搞成我自己的了,还挺好用的,,, 总得来说写增删改查,搭建一个不需要太大定制化的大型公司项目来说,Springboot的一系列产品可以很轻松的搞定。这个是Python目前的环境做不到的。但是如果Python去封装,会比Java好看好写的很多。也许是因为Python做企业开发用的少,没有人去做这个吧,大公司项目迭代的原因也独立不出来了。 我觉得这几天做的东西很了不起了,后边还得帮他们做。感觉也是因为我之前积累导致了学这些东西还是很快的。现在最欠缺的就是相关源代码原理基本不知道,如果你说微服务架构我会知道,但你说Springboot是怎么封装起来的,这个我还是一头雾水,虽然注解我查了一下大体知道了,但是能把很多库统一标准起来,想想就头大。

Continue

emmm,其实从一开始自己学编程就各种研究做游戏,但都是坚持不下来等各种原因,啥没搞出来。 但是游戏框架倒是没少接触,自己脑子里想了好几个游戏,也分不同时间做过,然后每次都经历的过程差不多,选框架,选图片素材。开始的这种工作消耗了我基本好多时间,然后慢慢学框架发现这里不好做,那里不好实现,慢慢就放弃了。 有时候游戏还没开始,就想着跨平台,要搞个跨平台的框架。要做个手机游戏,首先想到的是苹果,安卓都要可以,找跨平台引擎写。时间都浪费在这里了。 期间写过一个微信小游戏,用了cocos creator,然后用了一个预置模板,然后加载特别慢,对这个引擎失望透顶。发现还不如我自己画的快。后来又写了一个小游戏,直接用的js库,ui什么的都自己画了,又快又爽。 用引擎就是会很多照顾新手,页面操作多,繁琐,虽然编程也可以。js的low,唯一好处就是web和微信支持,别的语言懒得学。像unreal,unity之类的搞3d太难了,虽然想搞。用框架就是依赖性太强,想改个东西还得看源代码,太低级的觉得太低级不想用,没啥必要用,太高级的又觉得都是费功能,太慢了。 用python之前考虑不跨平台,不想用。后来觉得去他妈的跨平台,老子先搞一个pc平台把我的想法实现了再说。然后想搞个无限地图的功能,找了一些现成的地图方案,发现缺陷太大,放弃。自己想了想,然后网上查了一下,发现跟我想法一样,自己用python撸了一个无限地图的功能,框架也是python的,发现巨慢无比,三十帧左右。也许是代码有问题可以优化,但是我想想即时把帧数优化上去了,后边加游戏逻辑还得慢,然后一直优化吧,直接放弃。然后找了一个c++写的小众游戏的引擎,功能很合我的意,官方有python绑定,看着例子写了个demo,感觉挺好。然后等我开始写深入功能的时候,发现ui是个问题,官方封装的代码太复杂,我c++不太懂,绑定第三方图像库也不了解。其实python的绑定封装的接口也乱,但是demo里边的东西,我大部分都了解了实现游戏逻辑没啥问题。又找了一圈别的库,又又又一次的放弃了。 折腾的比上边描述的要多的多,想起来写下来的就这些了。 前段时间我突然出来一个想法,想用commonlisp写个游戏,只是一个玩法好玩,想借助cl看看有没有好的发挥cl的特性。突然想明白一个事,我为什么想写游戏却局限于现在的技术栈里边呢。现在写web多,然后多考虑的是python,js之类的,用惯了不想换,但是又不是做这个擅长的事。以前上学学c,c++也都是只写逻辑,没有第三方依赖,最多写写vc,也是集成环境。突然想到,老子要用c写游戏了。 随便一搜就决定了用的技术,因为之前也了解了比较多的了。所以直接选点SDL,一个跨平台,一个c,百分比满意。然后官网找的一个书,一天看完了,发现使用很简单。图片音频这些加载,我又犯了强迫症,不行依赖额外的库。宁可使用第三方的开源代码放到项目里。后来又想通了,纠结这些事不对的。 我下定决心都用官方的,SDL_image mixer ttf,然后自己接触了这么多引擎框架,觉得cocos2d确实作者牛逼,一些游戏概念划分的很好。我参照cocos2d的理念,自己假期抽时间撸了一个c的小游戏框架,已经基本完善。 后边要做的主要就三块,一块是ui,这个也自己写,想了一下,总共用不了几个元素,自己撸还是来的快和爽,想怎么改怎么改,前期就是会丑一些。第二块就是物理,这里目前打算是用第三方的,其实也用不了太多的东西,但是自己撸数学懒得看,数学调试也麻烦,不然还得依赖别人写的库,不如直接用第三方的物理引擎。第三块就是游戏逻辑相关了,这里就是慢慢添加了,难道应该不大,就是消耗时间。 特别写完我的小框架后,就特别觉得之前为什么不用c写呢,陷入了python易用,写得快速的死胡同里了。最近因为写框架,写的c也不少,上班后写python的时候,每写完一行就想加个分号。我发现语言这东西不能一直换,思维什么的定势了不容易转换。 写c也没感觉说效率低多少,最主要的是要考虑内存申请和释放的问题。还有就是不能面向对象设计,每次都要传参数,就想怎么写的容易一点。但是c想写的容易一点就可以容易一点,但是像python,虽然本身设计带了很多设计模式,你想写容易一点,就得更深入挖掘python的知识,其实学起来反而不容易,除非写多了才会容易了。 c还有个问题,就是源码文件目录的设计,第三方库依赖的问题,虽然有ldd,otool之类的工具,但是我不清楚游戏业界都是怎么做的,我以后还得考虑,全源码编译。目前先软件包安装写代码。gcc 等一系列编译工具链也没看,大体功能知道,后边要用再看也来得及,现在主要还是pk代码要紧。 想起个问题就是为什么不用c++,这个写游戏是用的最多的,环境肯定好很多。但是一个就是c比较底层,写熟练了不局限于游戏这一块地方,系统编程用的也很多。c++面向对象确实比c好,但是太复杂了,想起了上学时那些关系什么的,产生了畏惧。其实我自己写自己用的代码,无所谓封装的好不好,但是综合权衡还是用了c,现在还是很满意的。

Continue

先写解决方案:制定dasconfig的failoverLevel = 1,就解决了。 这是一个必传的参数。但是官网特别说明,所有参数都是可选的。All fields are optional. 然后报错“指定的参数不正确:”也没写哪个参数不正确。 我是google搜索找到了解决方案,而且还是六七年前的帖子,也就是说这个问题持续六七年了吗??? vmware文档啥分类没有,我找都是从manager到数据方法,或者dir看到了,直接搜索。太麻烦了。而且返回的数据是关联返回的,虽然可以制定返回的字段。

Continue