国庆大假马上就要来临了,我们聊点轻松的话题,关于假期。
Jerry的成都同事李贝宁(Li Ben), 《SAP成都研究院李三郎:SCP Application Router简介》的作者,有一次11月份的时候和Jerry一起去德国出差,不解地问到:德国好歹也有八千多万人口,怎么街上冷冷清清的几乎看不到人呢?
对于这个问题Jerry也没有答案。而且这种现象在德国的法定节假日里更加突出。
Jerry的文章《Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现》曾经提到,去年我在德国待了三个月,最难熬的就是德国几乎每个月都有那么几天的法定节假日,因为既然放假,SAP总部的员工食堂就不开了,而且商店也全部关门,得提前一天备好干粮。
SAP德国总部员工食堂的伙食是非常非常好的,就在Jerry写这段文字时,仿佛又闻到了中午饭点时走近食堂,从里面散发出食物的香味。
总部员工食堂菜的味道有甜有酸,有些汤的味道稍稍带着苦味,没有辣味,正好Jerry讨厌吃辣,所以口味非常适合我,我一连吃了90天也不觉得腻。
荤素搭配很合理,而且肉和菜吃不够随便加,管饱,对于Jerry这种饭量大的程序猿来说简直是天堂。
这些食物太美味了,每顿饭结束后我都是这个状态:
然而到了德国法定节假日和星期日,这一切都消失了。德国商店的营业时间一直按照20世纪50年代的规定执行的:商店在工作日最晚开到下午六点半,周六最晚下午2点关闭,周日全天不营业。
于是,2017年五一小长假,4月29日~5月1日三天,Jerry只好靠这些干粮充饥,三天一共只花了9欧元。
Jerry是一个程序猿,对吃的不挑剔,Zopf很经饿。什么是Zopf?
我住在德国乡下,平时也难得见到人,更别提节假日了。街上全是这种风格:
要不是耳边传来偶尔驶过的汽车和德国小朋友在自己花园里嬉戏的声音,Jerry还以为自己来到了科幻电影《我是传奇》里的世界。
五一小长假的最后一天,我的同事Liang Simon(梁亚舒)邀请我到他的家中,吃了一顿地道的德国烤肉。在此之前啃了两天Zopf的我,觉得这是我这辈子吃过的最美味的烤肉!烤肉一扫光后,Simon的老婆又端出一个自己动手做的巧克力蛋糕。
Jerry吃完之后,心里遗憾地想:当初这个蛋糕制作的时候,半径再大几厘米就更完美了。
在这种情况下,作为一个程序猿,娱乐的方式就只剩撸代码了。所以本文提到的这些东西都是Jerry在德国节假日里无聊的产物,对于ABAP顾问的实际工作可能帮助不大。不过因为是过节,大家当看看小说消遣好了。
1. Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现
把本科学过的八种排序算法用ABAP逐一实现了一次。
SAP社区上有一位网友Sinai可能觉得我是吃饱了撑着没事干(这倒是事实),毕竟在ABAP里要排序直接使用关键字SORT即可。
不过幸好还有另外的网友跳出来为我辩护,中心思想就四个字:开心就好。
2. 不用四则运算符比较两个整数的大小
看文字描述就能感觉到这又是一个让程序猿感觉很囧的需求。
使用位操作,JavaScript可以很优雅地实现:
Java也没问题:
轮到ABAP就麻烦了。因为ABAP的BIT-XOR这种位操作不支持整型类型。
既然语言层面不支持,就只好自己动手模拟了。
我用一个尺寸为32的ABAP内表存储一个32位整数的每一个bit的值,然后基于这个内表模拟了整数的与或非以及异或操作,还有按位左移,右移。
让ABAP整数也能像上图JavaScript和Java那样支持按位逻辑操作的模拟实现代码在我的博客里:
Bitwise operation ( OR, AND, XOR ) on ABAP Integer
用这种模拟方式实现的ABAP代码比JavaScript和Java足足长了一倍。虽然丑陋,但好歹实现了题目的需求。
3. 给出尽可能多的计算两个整数和的方案
下面的答案可以归纳为:
普通程序员的答案
2B程序员的答案
文艺程序员的答案
闲得蛋疼的程序员的答案
。。。
最后一种解法实际就是本科计算机原理里介绍的加法器:通过按位逻辑与运算(&)判断当前位操作是否有进位产生,用按位逻辑或运算(|)保存当前位进位的值。
最后一种解决方案的ABAP版本:
下面就是一些小工具了。
1. 如果您是一位ABAP顾问,您知道每个月,哪个SAP事务码被自己使用最多次数么?
只需写一个简单的ABAP报表,执行就能知道答案。报表的源代码可以通过点击文末"阅读原文"获得。下图是Jerry在SAP内部的开发系统执行该报表后的结果,排在第一位的SE24,一个月使用了713次不奇怪,令我吃惊的是SAT居然使用了692次。不用说,这个月一定在和各种与性能相关的incident进行苦战。
2. 增强的ABAP代码版本管理功能。
打个比方, 如果我想查找一行注释"* Wave 12 Schema version is 7"最早是在哪一个ABAP代码改动版本引入的,最后发现是第45个版本引入的。
在实际工作中,SAP的开发人员经常需要做类似的事情,比如分析一个bug,最后定位到是引入了某一行代码引起的,然后就需要找到是哪一个请求号对应的版本引入的这行有问题的代码。
但是,这个方法一共有77个版本,难道我要从第一个版本开始,将其和当前版本比较,一直比较到最后一个版本?
这个是纯粹的体力活,时间复杂度o(n)。我们也可以用二分查找的思路,把77个版本中间的版本即版本39和当前版本比较,如果版本39没有出现我们要查找的代码,就对版本40和77这个区间段再次使用二分查找。
这种查找办法只是把时间复杂度降成了对数级别,这种体力活仍然让我心烦意乱。有没有o(1)的解决方案?
当然有。就是把这个方法每个版本的源代码全部下载到本地保存成一个txt文件,里面的版本内容从低到高排序,然后直接按照要查找的关键字进行搜索,瞬间即可得出答案。
有了这个本地文件,我可以用文本编辑器同时打开它两次,然后可以通过鼠标滑动的方式,快捷地比较任意两个版本的差异,而不需要SAPGUI"选择待比较的版本->点击比较按钮->查看比较结果->点回退按钮->选择下一组要比较的版本"这种笨拙的操作,工作效率得到质的提升。
在我心中,重复的鼠标点击对于程序猿来说就是万恶之源。
这个工具的源代码可以通过点击"阅读原文"获得。
3. 增强的SAT功能。
SAP成都研究院CRM开发团队曾经接到一个CRM On HANA的测试项目,就是在两个系统上同时运行一系列相同的ABAP代码,这两个系统底层的数据库分别是非HANA数据库和HANA数据库,通过这种方式评测SAP CRM运行在HANA数据库上的性能。一旦发现某些代码在HANA数据库上运行的性能还不如非HANA数据库,就找出原因,对相应代码做优化。
当时,德国同事给我们的要求就是,在两个系统分别用SAT运行应用,然后手动分析SAT结果,把在数据库为HANA的系统上运行速度慢于非HANA系统的点都找出来,写成文档。
我当时一接到这个项目,心里暗暗叫苦:这不又是纯体力活么。如果待测试的一段代码调用了非常多的API,那岂不是要把这些API在两个系统上执行的时间一个一个找出来手动比较么?就算用双屏,脑袋也要像波浪鼓一样左右晃动,这又不是在练习自由泳的转头换气。
后来Jerry就写了一个工具自动进行比较。下图是工具界面,HN1和Q2U是这两个系统的代号,其中HN1系统后台数据库是HANA,而Q2U后台是非HANA。
Green Threashold指定成50,意思是如果同一个方法,HN1的执行速度比Q2U快50%,则这个方法的比较结果显示成绿灯;Yello Threshold则代表HN1比Q2U快,但只快了20%到50%。如果HN1比Q2U还慢,这就比较糟糕了,是我们需要采取措施的场景。
工具的输出是一个ALV,可以直接导出成excel。
有了这个工具,原本需要填几个小时的excel,现在十秒就能完成。节省下来的时间可以花费到亮红灯的那些结果,即真正需要进行HANA数据库调优的那些代码中去。
后来Jerry把这个工具秀给了德国的项目主管,他很喜欢这个工具,让我在一个内部会议上给SAP全球其他地区的同事讲讲工具怎么用。这也是Jerry在这篇文章里介绍的众多用ABAP搞出来的无聊的东西里唯一被SAP官方认可的工具,囧。
这个工具的完整代码通过点击"阅读原文"获得。
4. 直接用excel执行SAPGUI里的事务码或者函数。
作为一个SAP ABAP开发人员,SAPGUI上的系统清单总是很长很长,这还是我清理过多次,删除了若干很少使用系统之后的清单。有些系统我每天登陆上去只是为了看几个简单的事务码,比如SM04,ST22,SE10这些。为此,每天我都要在SAPGUI里选中某个系统,双击之后进行登录,然后在键盘上输入事务码。
很快我的懒癌又犯了,因为我在这些系统上并不会进行开发工作,那么有没有办法不用SAPGUI登录系统,也能执行事务码并查看结果呢?有,用excel。在excel里做几个按钮,每个按钮的事件处理函数用VB硬编码成对应系统的地址,系统编号,用户名和密码,以及期望执行的函数或者事务码的名称。
这样以前繁琐的操作,现在双击打开excel啪啪啪点几个按钮,然后切去做其他事情,等一会再切回excel查看结果即可。节省下来的时间可以做其他更有意义的事情。
这种VB代码像下面这样写:
5. 直接在SAPGUI里给同系统其他在线用户打招呼。
执行这个工具,会看到当前系统在线用户列表和每个用户正在使用的事务码。
双击某个用户名称,他/她的SAPGUI里就会出现一个弹出框,上面显示一条预先指定好的文本,比如:
这个恶作剧其实就是通过函数TH_POPUP给指定的用户发送一条文本消息,以弹出框的形式显示出来:
6. 项目经理可以使用的查岗工具。
比如项目经理想查看名叫WANGJER的顾问从2017年3月1日到3月25日这些天到底在系统里做了哪些开发,只需要执行这个工具就能得到清单。
其实写这个工具的初衷是为了方便我快速得回忆起任何一个时间段,比如一个月或者一年以前到底做了哪些开发工作。程序猿上了年纪后记忆力就衰减了,必须要通过工具的辅助。
最后一个是恶作剧。
一天我正在上班的时候,微信上一位partner向我求助,说是这根红色标注的分割线可以往左拖拽。
一旦把它拖到最左边的极限位置后,将无法再调整其位置了。如下图这样,因为左边对象列表的宽度实在太窄,此时SE80其实已经没有办法使用了。
当时Jerry看了这位朋友微信上发过来的截图,半信半疑,还有这种操作?
照着试了一下,结果我也杯具了。
好在我知道有这张表的存在:
一行代码即可让SE80的设置回复到初始设置:
DELETE FROM rseumod WHERE uname = ‘WANGJER’.
感谢大家耐心听完我的唠叨,提前祝大家2018年国庆节快乐。
更多阅读
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
本文实例讲述了jquery实现鼠标滑过显示二级下拉菜单效果。分享给大家供大家参考。具体如下:这是一款jquery实现的下拉菜单,当鼠标移在主菜单上的时候,向下滑出二级子菜单,采用UL LI结构,便于修改完善,我觉得是很实用的菜单,希望大家平时能用得上。运行效果截图如下:在线演示地址如下:具体代码如下:jquery下拉菜单* { margin: 0; padding: 0; }body {font-...
一,block是什么?*带有自动变量的匿名函数。 ————引自《iOS与OS X多线程和内存管理》* 1.匿名函数 首先blocks是c语言的扩充功能 c语言中函数是这个样子的:void func() { printf("hello world");}那么,block是一个什么样子的呢?^void () { printf("hello world");}这种不带名的函数就
设置动态IP:1、sudo gedit /etc/network/interfaces2、文件修改如下auto eth0 iface eth0 inet dhcp3、sudo /etc/init.d/networking restart设置动态IP:1、同上2、auto eth0iface eth0 inet static add
你项目中的代码是否越来越难以修改和维护?bug越改越多?想知道如何改进设计吗?不妨来看看这篇文章
淘宝订单测试网址:http://console.open.onebound.cn/console/?i=TurboTrade 数据结构名称 类型 是否隐私 描述 seller_nick String Y 卖家昵称 buyer_nick String Y 买家昵称 title String Y 商品标题 type String Y 交易.
记录一下DDPG/GDDPG训练中出现的问题初始化部分: self.actor_eval = ActorNet(s_dim, a_dim) self.actor_target = ActorNet(s_dim, a_dim) self.critic_eval = CriticNet(s_dim, a_dim) self.critic_target = CriticNet(s_dim, a_dim) # create 2 optimizers for actor and critic self.
相机相关知识记录本文记录一些使用时遇到的相机相关知识,不定期更新。1.相机数据格式mono8,即存储下来的图像为单色,8Bit的图片,一般是bmp,jpeg等。packed mono10,即存储下来的图片为单色,10Bit的图片。packed存储即将10Bit的数据以16Bit的方式填充,剩余的本应填充为0的6个bit被下一帧图片数据填充,这样做可以减少数据量和数据冗余度,节省空间。mo...
文章预览前言一、OkHttp持久化Cookie分析二、例子2.1、效果前言OkHttp持久化Cookie使用的是OkHttp3–CookieJar 持久化Cookie参考文章https://www.jianshu.com/p/f1df12ceaedchttps://www.jianshu.com/p/1a222a9394ceokhttp3依赖:implementation("com.squareup.okhttp3:okhttp:4.9.0")添加网络权限<uses-permiss
错误代码183事故始源系统环境解决方法事故始源安装Adobe illustrator CC 2019。安装到88%后无法安装弹窗显示“错误代码183”系统环境Win10 1803(只装了office 2016)(禁用了些不需要或不用的服务)解决方法最终解决方法:①必须启动的系统服务:“Microsoft Store 安装服务”②在网卡属性内必须开启 Internet 协议版本 6 (TCP/IPv6)结论:(吐槽:安装PS时这两项都是不需要的,而且为啥要开启IPv6这就很不明白了)①启动
转载自: http://ztbls888.blog.163.com/blog/static/1718175982012230102141390/久别重逢是说,自从在教科书上见过它一面之后,这才是第二次碰面。也就是说,在这些年的编程经历中,从来没有遇到过吧——至少在我印象中是这样的。以至于我都开始怀疑在“平常的”程序中,它是否真正存在了。内存分配,C 里的 malloc (或者配套的函
Smarty是由Monte Ohrt和Andrei Zmievski写出的PHP模板引擎。它不同于其他的模板引擎,比如FastTemplate或者patTemplate,其中主要原因就是Smarty会将模板转化成PHP脚本,并剔除每次使用该模板时都会出现在解析环节里的用来控制和错误检验的附加码。这个功能使Smarty在大型应用和高流量网站上有优异的表现。Smarty除了模板编译还有很多其他
模拟题目的恶心真心不是吹的#include #include #include #include #include using namespace std;const int MAXN = 510;ofstream fout("starry.out");struct Tri{ int x,y; int start_x,start_y; int end_x,en