wps实习四个月后

wps 实习四个月后的一些思考和新规划 wps 的实习已经告一段落,玩了一段时间,迷茫了一段时间,整理代码一段时间,现在写一篇思考。 wps 实习内容 在 wps mac 组实习四个月,接手的需求有: 移植 pc 功能 Excel 批量计算 交互功能 空格键进入图片预览 双指滑动(滚轮)移动图片 双指拍&双指捏缩放图片 双指旋旋转 wps 对象 双指/右键拖复制 wps 对象 优化需求 多级窗口 modal 规范 新建文本框默认设置添加选项 复制图片清晰度优化 Excel 单个单元格复制形式改为纯文本 半成品需求 光标 icon 替换为高清图 Excel 底部 sheet 平滑移动 文本框添加只复制文本功能 三指捏需求 感觉这些需求都挺无聊的,所以才交给一个实习生写吧。多级窗口 modal 规范,该需求阅读了大量 qt 源码。触控板扩展需求考察了一堆开源代码,学习了 objective-c 和 swift。也就这两个需求有点意思。 实习过程技术成长 刚入职先学习公司代码规范、工程规范,和一些工作流程。第一次用到心心念念的 mac,也花了点时间来熟悉,用过很多发行版 Linux,上手 mac 也很快。wps 产品由用 qt+c/cpp 完成,技术方面先学习 qt。第一个需求移植 pc 已有的 Excel 批量计算功能,需要添加的代码都在一起,不需要调试,直接上手敲码就好,qt 方面也只需要学习 dialog 的创建,和事件的处理。第二个需求空格键进入图片预览,该有的 api 都有,但需要找到适合修改的代码块,因为不会调试所以花了一个多星期,还是最后组长教会了我调试来定位代码和了解功能的执行流程。后面都是一些调 api 的需求,以及学会 qt 某部分的使用就能写的需求。多级窗口 modal 规范需求,考察了很久才定位到 qt 的 bug(pc 没问题,mac 有问题,应该第一时间就测试一下是不是 qt 的 bug),为解决 bug 阅读了大量 qt 源码,对 qt 的一些特性有了更深了了解,学习框架还是得直接读源码。qt 源码面向对象,以 c++11 为标准(qt6 以 c++17 为标准),范型编程到处都是,可读性很好,比 wps 代码好的多。离职前的需求是 mac 触控板相关的,网上资料很少,只有 github 上有几个项目,为了看懂代码就去学了 objective-c,顺便学了 swift(语法方面 c/cpp yyds,oc 真反人类,swift 也习惯不了)。做了一些考察才知道 apple 有 Private API 这个东西,mac 触控板增强软件都用了这部分 api,wps 不可能用的,产品的一些需求也就得打回了。不用写多指需求了,但多指滑、多指捏在继续考察,应该可以通过触控点的坐标识别手势,但自定义手势多了可能就不能做到精准识别了。...

March 27, 2022 · 1 min · 145 words · xhwhis

后端开发面试题

后端开发面试题 后端开发面试知识点大纲: 语言类(C++): 关键字作用解释: volatile 作用 Volatile关键词的第一个特性:易变性。所谓的易变性,在汇编层面反映出来,就是两条语句,下一条语句不会直接使用上一条语句对应的volatile变量的寄存器内容,而是重新从内存中读取。 Volatile关键词的第二个特性:“不可优化”特性。volatile告诉编译器,不要对我这个变量进行各种激进的优化,甚至将变量直接消除,保证程序员写在代码中的指令,一定会被执行。 Volatile关键词的第三个特性:”顺序性”,能够保证Volatile变量间的顺序性,编译器不会进行乱序优化。 C/C++ Volatile变量,与非Volatile变量之间的操作,是可能被编译器交换顺序的。C/C++ Volatile变量间的操作,是不会被编译器交换顺序的。哪怕将所有的变量全部都声明为volatile,哪怕杜绝了编译器的乱序优化,但是针对生成的汇编代码,CPU有可能仍旧会乱序执行指令,导致程序依赖的逻辑出错,volatile对此无能为力 针对这个多线程的应用,真正正确的做法,是构建一个happens-before语义。 [C/C++ Volatile关键词深度剖析](http://hedengcheng.com/?p=725) static 控制变量的存储方式和可见性。 (1)修饰局部变量 一般情况下,对于局部变量是存放在栈区的,并且局部变量的生命周期在该语句块执行结束时便结束了。但是如果用static进行修饰的话,该变量便存放在静态数据区,其生命周期一直持续到整个程序执行结束。但是在这里要注意的是,虽然用static对局部变量进行修饰过后,其生命周期以及存储空间发生了变化,但是其作用域并没有改变,其仍然是一个局部变量,作用域仅限于该语句块。 (2)修饰全局变量 对于一个全局变量,它既可以在本源文件中被访问到,也可以在同一个工程的其它源文件中被访问(只需用extern进行声明即可)。用static对全局变量进行修饰改变了其作用域的范围,由原来的整个工程可见变为本源文件可见。 (3)修饰函数 用static修饰函数的话,情况与修饰全局变量大同小异,就是改变了函数的作用域。 (4)C++中的static 如果在C++中对类中的某个函数用static进行修饰,则表示该函数属于一个类而不是属于此类的任何特定对象;如果对类中的某个变量进行static修饰,表示该变量为类以及其所有的对象所有。它们在存储空间中都只存在一个副本。可以通过类和对象去调用。 const 的含义及实现机制 const名叫常量限定符,用来限定特定变量,以通知编译器该变量是不可修改的。习惯性的使用const,可以避免在函数中对某些不应修改的变量造成可能的改动。 (1)const修饰基本数据类型 1.const修饰一般常量及数组 基本数据类型,修饰符const可以用在类型说明符前,也可以用在类型说明符后,其结果是一样的。在使用这些常量的时候,只要不改变这些常量的值便好。 2.const修饰指针变量*及引用变量& 如果const位于星号*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量; 如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。 (2)const应用到函数中, 1.作为参数的const修饰符 调用函数的时候,用相应的变量初始化const常量,则在函数体中,按照const所修饰的部分进行常量化,保护了原对象的属性。 [注意]:参数const通常用于参数为指针或引用的情况; 2.作为函数返回值的const修饰符 声明了返回值后,const按照"修饰原则"进行修饰,起到相应的保护作用。 (3)const在类中的用法 不能在类声明中初始化const数据成员。正确的使用const实现方法为:const数据成员的初始化只能在类构造函数的初始化表中进行 类中的成员函数:A fun4()const; 其意义上是不能修改所在类的的任何变量。 (4)const修饰类对象,定义常量对象 常量对象只能调用常量函数,别的成员函数都不能调用。 http://www.cnblogs.com/wintergrass/archive/2011/04/15/2015020.html extern 在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。 注意extern声明的位置对其作用域也有关系,如果是在main函数中进行声明的,则只能在main函数中调用,在其它函数中不能调用。其实要调用其它文件中的函数和变量,只需把该文件用#include包含进来即可,为啥要用extern?因为用extern会加速程序的编译过程,这样能节省时间。 在C++中extern还有另外一种作用,用于指示C或者C++函数的调用规范。比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规则不同,用此来解决名字匹配的问题。 宏定义和展开、内联函数区别, 内联函数是代码被插入到调用者代码处的函数。如同 #define 宏,内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。 宏定义不检查函数参数,返回值什么的,只是展开,相对来说,内联函数会检查参数类型,所以更安全。 内联函数和宏很类似,而区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。 宏是预编译器的输入,然后宏展开之后的结果会送去编译器做语法分析。宏与函数等处于不同的级别,操作不同的实体。宏操作的是 token, 可以进行 token的替换和连接等操作,在语法分析之前起作用。而函数是语言中的概念,会在语法树中创建对应的实体,内联只是函数的一个属性。 对于问题:有了函数要它们何用?答案是:一:函数并不能完全替代宏,有些宏可以在当前作用域生成一些变量,函数做不到。二:内联函数只是函数的一种,内联是给编译器的提示,告诉它最好把这个函数在被调用处展开,省掉一个函数调用的开销(压栈,跳转,返回) 内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。这样,内联函数就和普通函数执行效率一样 内联函数必须是和函数体申明在一起,才有效。 [宏定义和内联函数区别](http://www.cnblogs.com/chengxuyuancc/archive/2013/04/04/2999844.html) 库函数实现: malloc,strcpy,strcmp 的实现,常用库函数实现,哪些库函数属于高危函数...

March 27, 2022 · 12 min · 2487 words · xhwhis

数据库面试点

数据库面试点 事务 4 个,acid(实现) 隔离操作 binlog、redolog、ondolog innodbe 和 myisim 掌握 三个特性(双次写、插入缓存、自适应) 锁 mvcc(乐观锁、悲观锁) 行锁(行锁、零件锁、间隙锁) 表锁 索引 数据结构(B+树、B 树、Hash 索引、全文本索引) 逻辑结构(主键、唯一、前缀、覆盖、联合、普通) 存储结构(聚集索引(innodbe)、排序索引(myisim))) 索引失效、索引优化、索引下推、索引回表 最左匹配 查询优化 小表匹配大表(in exist) 小表—>大表 order by group by 类型优化 分区分库分表、主从复制

March 27, 2022 · 1 min · 33 words · xhwhis

类和对象1

类和对象 类型与变量 类型 变量 int a long long b char c double d float e 类型 = 类型数据 + 类型操作 类与对象 类 对象 cat garfield dog odie people hug 访问权限 public 公共访问权限 private 私有访问权限 protected 受保护的访问权限 成员属性与方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> using namespace std; struct A { int x, y; void echo() { cout << "hello world a" << endl; return ; } }; struct B { private: int x, y; public: void set_xy(int x, int y) { cout << this << endl; this->x = x, this->y = y; } void echo() { cout << "hello world b" << endl; cout << x << " " << y << endl; return ; } }; int main() { A a; B b; a....

March 27, 2022 · 3 min · 501 words · xhwhis

类和对象2

类和对象 类属性与类方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #include <iostream> using namespace std; class A { public : A(int x) { cout << "class A's constructor" << endl; } }; class Point { public : Point(); Point(int x, int y); int x() const; int y() const; int x_cnt() const; void set_x(int x); void set_y(int y); static int output_cnt(); ~Point(); private : static int point_cnt; int __x, __y; mutable int __x_cnt; A __a; }; int Point::point_cnt = 0; int Point::output_cnt() { return Point::point_cnt; } Point::Point() : __x_cnt(0), __a(2) { Point::point_cnt += 1; } Point::Point(int x, int y) : __x(x), __y(y), __x_cnt(0), __a(4) { Point::point_cnt += 1; } Point::~Point() { Point::point_cnt -= 1; } int Point::x() const { this->__x_cnt += 1; return this->__x; } int Point::y() const { return this->__y; } int Point::x_cnt() const { return this->__x_cnt; } void Point::set_x(int x) { this->__x = x; } void Point::set_y(int y) { this->__x = y; } void func() { Point c, d; cout << "func : " << Point::output_cnt() << endl; return ; } int main() { Point a(2, 3), b; const Point c(3, 4); cout << a....

March 27, 2022 · 4 min · 646 words · xhwhis