├── 设计模式 ├── 建造者模式.md └── 设计模式导论.md ├── 计算机视觉 ├── 计算机视觉.md └── Medical Imaging │ └── ”Transformers in Medical Imaging:A Survey“ Notes.md ├── Android ├── Android开发艺术探索 │ ├── JNI和NDK编程.md │ └── Activity启动模式.md ├── JNI底层驱动开发相关.md ├── Android面经课.md ├── Android图形图像学习.md ├── Android第一行代码 │ └── 开始启程.md ├── Android框架揭秘 │ ├── init进程.md │ └── Zygote.md ├── Android底层开发技术实战详解 │ └── 11.音频系统驱动.md ├── FOTA开发与热修复.md ├── Android自定义控件.md ├── 生命周期的分析.md ├── App研发录 │ └── 高效App框架设计与重构.md └── AudioSystem相关.md ├── image ├── DOM.png ├── MVC.png ├── QT1.png ├── QT2.png ├── QT3.png ├── Tick.png ├── URL.png ├── XOR.png ├── git.png ├── Binary.png ├── QTTest1.png ├── QTTest2.png ├── QTTest3.png ├── SpinBox.png ├── URL_add.png ├── complex.png ├── duality.png ├── light.png ├── logic.png ├── method.png ├── python.png ├── quick.png ├── table.png ├── ArrayList.png ├── De_Morgan.png ├── Karnaugh.png ├── QTCreate.png ├── QTFinish.png ├── activity.png ├── combo_box.png ├── dateEdit.png ├── implement.png ├── Binary_add.png ├── ClickAfter.png ├── ClickBefore.png ├── Fenwick_tree.jpg ├── Logical_or.png ├── PyCharmAdmin.png ├── QTDesigner.png ├── URL_download.png ├── Web_parser.png ├── c_language.png ├── equivalence.png ├── push_button.png ├── subversion.png ├── using_logic.png ├── BeautifulSoup.png ├── Decimal_system.png ├── QSpinBoxFinish.png ├── TomcatDownload.png ├── URL_processor.png ├── AnacondaMavigator.png ├── PyCharmAddServer.png ├── PyCharmDeployment.png ├── URL_Realization.png ├── TencentServerLogin.png ├── TomcatDownloadNext.png ├── View_to_Controller.png ├── logical_expression.png ├── PyCharmTestConnection.png └── four_type_of_Web_parser.png ├── C&C++ ├── 二进制压缩算法.cpp ├── C++学习.md ├── C_指针.md ├── C++并发编程实战 │ └── 第一章.md ├── 二进制压缩算法.md ├── C++_正则表达式.md └── C语言培训.md ├── 数据结构 ├── 数据结构绪论 │ ├── 抽象数据类型.md │ ├── 数据结构绪论.md │ ├── 数据.md │ └── 数据中的结构.md ├── 线性表 │ ├── Queue.cpp │ ├── LinearTable.o │ ├── 创立单链表结构.cpp │ ├── 创立单链表结构.exe │ ├── LinearTable.cpp │ ├── LinearTable.exe │ ├── Sequence_Stack.cpp │ ├── Sequence_Stack.exe │ ├── 单链表(on_my_own).c │ ├── Arraylist │ │ ├── Queue.java │ │ ├── StackList.java │ │ └── Sequence.java │ ├── LinkedList │ │ ├── linkedDemo.java │ │ └── Linked.java │ ├── 順序表的算法設計.md │ └── 线性表.md ├── 刷题思路报告.md ├── 串 │ └── KMP算法.md ├── 流程控制语句.md ├── 枚举-讨厌的青蛙.md └── 树 │ └── treeDemo │ └── TreeDemo.java ├── LeetCode ├── README.md ├── TwoSum.md └── Add Two Numbers.md ├── JAVA学习 ├── Java使用JDBC连接MySQL数据库DAO模式.md ├── Java集合 │ └── HashMap排序.md ├── 访问控制符详解.md ├── Object类详解.md ├── 泛型的详解.md ├── 面向对象.md ├── String类源代码深析.md ├── 反射 │ ├── Person.java │ └── ReflactDemo.java ├── String类陷阱深度解析.md ├── Java之异常.md ├── java1.5新特性之自动装箱与自动拆箱.md ├── 包与导入语句的剖析.md ├── IDE的详细介绍.md ├── ArrayList与LinkedList.md ├── JAVA学习之接口_static_final等关键字.md ├── Java数组查找方式以及二分查找剖析.md ├── JavaWeb使用教程.md ├── 运算符.md ├── 原生数据类型.md ├── JAVA学习之单例模式.md ├── 垃圾回收器.md ├── 冒泡排序的java实现.md ├── Java EE │ └── Java Design Pattern.md ├── hashCode与equals深度剖析与源码详解.md ├── 深入理解ArrayList.md ├── JAVA之封裝.md ├── Java多线程.md ├── Java线程.md └── JavaIO.md ├── .gitattributes ├── MVC、MVP和MVVM.md ├── 授课 └── OpenGLES.md ├── shell脚本.md ├── 计算机基础 ├── 离散数学及其应用(笔记).md └── 程序员的数学(笔记).md ├── MarkDown用法.md ├── 后端 ├── Django服务器部署.md ├── Java后端学习 │ └── SpringIoc学习.md └── Windows虚拟环境在PyCharm中的使用.md ├── Python编程从入门到实践读书笔记 └── Unit3 │ └── 列表学习.md ├── MATLAB的使用 └── MATLAB概述.md ├── QtDesigner.md ├── how to use git and repo.md ├── QT控件的使用.md ├── 基于Python的简单爬虫结构.md ├── Git.md ├── Ubuntu+Windows双系统安装指南.md ├── README.md └── 前端 ├── HTML.md └── CSS.md /设计模式/建造者模式.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /计算机视觉/计算机视觉.md: -------------------------------------------------------------------------------- 1 | # 计算机视觉 2 | -------------------------------------------------------------------------------- /Android/Android开发艺术探索/JNI和NDK编程.md: -------------------------------------------------------------------------------- 1 | # JNI和NDK编程 2 | 3 | -------------------------------------------------------------------------------- /image/DOM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/DOM.png -------------------------------------------------------------------------------- /image/MVC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/MVC.png -------------------------------------------------------------------------------- /image/QT1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QT1.png -------------------------------------------------------------------------------- /image/QT2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QT2.png -------------------------------------------------------------------------------- /image/QT3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QT3.png -------------------------------------------------------------------------------- /image/Tick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/Tick.png -------------------------------------------------------------------------------- /image/URL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/URL.png -------------------------------------------------------------------------------- /image/XOR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/XOR.png -------------------------------------------------------------------------------- /image/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/git.png -------------------------------------------------------------------------------- /C&C++/二进制压缩算法.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/C&C++/二进制压缩算法.cpp -------------------------------------------------------------------------------- /image/Binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/Binary.png -------------------------------------------------------------------------------- /image/QTTest1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QTTest1.png -------------------------------------------------------------------------------- /image/QTTest2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QTTest2.png -------------------------------------------------------------------------------- /image/QTTest3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QTTest3.png -------------------------------------------------------------------------------- /image/SpinBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/SpinBox.png -------------------------------------------------------------------------------- /image/URL_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/URL_add.png -------------------------------------------------------------------------------- /image/complex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/complex.png -------------------------------------------------------------------------------- /image/duality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/duality.png -------------------------------------------------------------------------------- /image/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/light.png -------------------------------------------------------------------------------- /image/logic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/logic.png -------------------------------------------------------------------------------- /image/method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/method.png -------------------------------------------------------------------------------- /image/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/python.png -------------------------------------------------------------------------------- /image/quick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/quick.png -------------------------------------------------------------------------------- /image/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/table.png -------------------------------------------------------------------------------- /数据结构/数据结构绪论/抽象数据类型.md: -------------------------------------------------------------------------------- 1 | # 抽象数据类型 2 | ## 数据类型 3 | + 数据类型:是指一组性质相同的值得集合及定义在此集合上的一些操作的总称。 4 | -------------------------------------------------------------------------------- /image/ArrayList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/ArrayList.png -------------------------------------------------------------------------------- /image/De_Morgan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/De_Morgan.png -------------------------------------------------------------------------------- /image/Karnaugh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/Karnaugh.png -------------------------------------------------------------------------------- /image/QTCreate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QTCreate.png -------------------------------------------------------------------------------- /image/QTFinish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QTFinish.png -------------------------------------------------------------------------------- /image/activity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/activity.png -------------------------------------------------------------------------------- /image/combo_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/combo_box.png -------------------------------------------------------------------------------- /image/dateEdit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/dateEdit.png -------------------------------------------------------------------------------- /image/implement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/implement.png -------------------------------------------------------------------------------- /数据结构/线性表/Queue.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/Queue.cpp -------------------------------------------------------------------------------- /image/Binary_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/Binary_add.png -------------------------------------------------------------------------------- /image/ClickAfter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/ClickAfter.png -------------------------------------------------------------------------------- /image/ClickBefore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/ClickBefore.png -------------------------------------------------------------------------------- /image/Fenwick_tree.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/Fenwick_tree.jpg -------------------------------------------------------------------------------- /image/Logical_or.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/Logical_or.png -------------------------------------------------------------------------------- /image/PyCharmAdmin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/PyCharmAdmin.png -------------------------------------------------------------------------------- /image/QTDesigner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QTDesigner.png -------------------------------------------------------------------------------- /image/URL_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/URL_download.png -------------------------------------------------------------------------------- /image/Web_parser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/Web_parser.png -------------------------------------------------------------------------------- /image/c_language.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/c_language.png -------------------------------------------------------------------------------- /image/equivalence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/equivalence.png -------------------------------------------------------------------------------- /image/push_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/push_button.png -------------------------------------------------------------------------------- /image/subversion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/subversion.png -------------------------------------------------------------------------------- /image/using_logic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/using_logic.png -------------------------------------------------------------------------------- /数据结构/线性表/LinearTable.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/LinearTable.o -------------------------------------------------------------------------------- /数据结构/线性表/创立单链表结构.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/创立单链表结构.cpp -------------------------------------------------------------------------------- /数据结构/线性表/创立单链表结构.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/创立单链表结构.exe -------------------------------------------------------------------------------- /image/BeautifulSoup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/BeautifulSoup.png -------------------------------------------------------------------------------- /image/Decimal_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/Decimal_system.png -------------------------------------------------------------------------------- /image/QSpinBoxFinish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/QSpinBoxFinish.png -------------------------------------------------------------------------------- /image/TomcatDownload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/TomcatDownload.png -------------------------------------------------------------------------------- /image/URL_processor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/URL_processor.png -------------------------------------------------------------------------------- /数据结构/线性表/LinearTable.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/LinearTable.cpp -------------------------------------------------------------------------------- /数据结构/线性表/LinearTable.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/LinearTable.exe -------------------------------------------------------------------------------- /image/AnacondaMavigator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/AnacondaMavigator.png -------------------------------------------------------------------------------- /image/PyCharmAddServer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/PyCharmAddServer.png -------------------------------------------------------------------------------- /image/PyCharmDeployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/PyCharmDeployment.png -------------------------------------------------------------------------------- /image/URL_Realization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/URL_Realization.png -------------------------------------------------------------------------------- /数据结构/线性表/Sequence_Stack.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/Sequence_Stack.cpp -------------------------------------------------------------------------------- /数据结构/线性表/Sequence_Stack.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/Sequence_Stack.exe -------------------------------------------------------------------------------- /数据结构/线性表/单链表(on_my_own).c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/数据结构/线性表/单链表(on_my_own).c -------------------------------------------------------------------------------- /image/TencentServerLogin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/TencentServerLogin.png -------------------------------------------------------------------------------- /image/TomcatDownloadNext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/TomcatDownloadNext.png -------------------------------------------------------------------------------- /image/View_to_Controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/View_to_Controller.png -------------------------------------------------------------------------------- /image/logical_expression.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/logical_expression.png -------------------------------------------------------------------------------- /image/PyCharmTestConnection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/PyCharmTestConnection.png -------------------------------------------------------------------------------- /image/four_type_of_Web_parser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kentanvictor/STUDY/HEAD/image/four_type_of_Web_parser.png -------------------------------------------------------------------------------- /LeetCode/README.md: -------------------------------------------------------------------------------- 1 | # LeetCode 笔记 2 | 3 | + [两数之和](https://github.com/kentanvictor/STUDY/blob/master/LeetCode/TwoSum.md) 4 | 5 | + [两数相加](https://github.com/kentanvictor/STUDY/blob/master/LeetCode/Add%20Two%20Numbers.md) -------------------------------------------------------------------------------- /JAVA学习/Java使用JDBC连接MySQL数据库DAO模式.md: -------------------------------------------------------------------------------- 1 | # DAO模式 2 | 3 | > + 一个典型的DAO模式主要由以下及部分组成: 4 | 5 | + DAO接口:把对数据库的所有操作定义成抽象方法,可以提供多种实现。 6 | + DAO 实现类: 针对不同数据库给出DAO接口定义方法的具体实现。 7 | + 实体类:用于存放与传输对象数据。 8 | + 数据库连接和关闭工具类: 避免了数据库连接和关闭代码的重复使用,方便修改。 -------------------------------------------------------------------------------- /数据结构/刷题思路报告.md: -------------------------------------------------------------------------------- 1 | # 如何把算法刷透 2 | 3 | ## 总结思路报告 4 | 5 | 可以按照以下的思路报告进行尝试整理: 6 | 7 | + 题目 8 | + 例子 9 | + 题目假设 10 | + 重要问题 11 | + 直觉 12 | + 解决方法可行性 13 | + 解决方案 14 | + 数据结构 15 | + 复杂度 16 | + 代码 17 | 18 | 以上几个维度进行考虑刷过的leetcode的问题 -------------------------------------------------------------------------------- /JAVA学习/Java集合/HashMap排序.md: -------------------------------------------------------------------------------- 1 | # HashMap 2 | 3 | >已知一个HashMap集合,User有Name(String) 和 age(int)属性。请写一个方法实现对HashMap的排序功能,该方法接收HashMap为形参,返回类型为HashMap,要求对HashMap中的User的age倒序进行排序。排序时,key=value键值对不得拆散。 4 | 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | PDF/android开发艺术探索.pdf filter=lfs diff=lfs merge=lfs -text 2 | PDF/深入理解计算机系统[[:space:]]by[[:space:]]Randal[[:space:]]E.[[:space:]]Bryant,[[:space:]]David[[:space:]]R.[[:space:]]O’Hallaron.pdf filter=lfs diff=lfs merge=lfs -text 3 | *.pdf filter=lfs diff=lfs merge=lfs -text 4 | -------------------------------------------------------------------------------- /Android/Android开发艺术探索/Activity启动模式.md: -------------------------------------------------------------------------------- 1 | # Activity 启动模式 2 | 3 | 默认情况下,多次启动同一个activity时,系统会创建多个实例并放进任务栈中,当点击back键后,任务栈通过“后进先出”的栈结构出栈,最终清空栈。 4 | 5 | ## 四种启动模式 6 | 7 | ### standard:标准模式 8 | 9 | ### singleTop:栈顶复用模式 10 | 11 | ### singleTask:栈内复用模式 12 | 13 | ### singleInstance:单实例模式 -------------------------------------------------------------------------------- /MVC、MVP和MVVM.md: -------------------------------------------------------------------------------- 1 | # MVC 2 | 3 | ![](./image/MVC.png) 4 | 5 | **上面的通信都是单向的**
6 | 7 |

MVC的两种互动模式


8 |

第一种


9 | 10 | ***通过View接受指令,传递给Controller*** 11 |
12 | 13 | ![](./image/View_to_Controller.png) 14 |

第二种

15 |
16 | 17 | [MVC、MVP和MVVM](http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html) 18 | -------------------------------------------------------------------------------- /Android/JNI底层驱动开发相关.md: -------------------------------------------------------------------------------- 1 | # 底层驱动开发相关 2 | 3 | ## JNI 开发流程 4 | 5 | + 在Java中声明native方法 6 | 7 | + 编译Java源文件得到class文件,然后通过javah命令导出JNI头文件 8 | 9 | + 实现JNI方法 10 | 11 | + 编译so库并在Java中调用 12 | 13 | ## NDK 开发流程 14 | 15 | + 下载并配置NDK 16 | 17 | + 创建一个android项目,并声明所需的native方法 18 | 19 | + 实现android项目中所声明的native方法 20 | 21 | + 切换到JNI目录的父目录,然后通过ndk-build命令编译产生so库 22 | -------------------------------------------------------------------------------- /JAVA学习/访问控制符详解.md: -------------------------------------------------------------------------------- 1 | # 访问修饰符(access modifier) 2 | java 中的访问修饰符一共有4种: 3 | + 1)public(公共的):被public所修饰的属性和方法可以被所有类去访问。 4 | + 2)protected(受保护的):被protected所修饰的属性和方法可以在类的内部、相同的包下面以及该类的子类所访问。 5 | + 3)private(私有的):被private所修饰的属性和方法只能在该类的内部中使用。 6 | + 4)默认的(不加任何的访问修饰符):在类的内部以及相同的包下面的类所使用。 7 | 8 | ## 关键字:instanceof 9 | instanceof:判断某个对象是否是某个类的实例,语法形式:引用名 instanceof 类名(接口名) 10 | 11 | 返回一个boolean的值 12 | -------------------------------------------------------------------------------- /授课/OpenGLES.md: -------------------------------------------------------------------------------- 1 | ### 如何用OpenGLES创建三维空间旋转 2 | 在这里你能够学习到如何使用OpenGLES创建一个三维空间旋转的界面,你可以直观的理解为,就像是在空间中进行的建模工作,能够进行旋转、放大和拉伸等操作。让你觉得你能够直接在Android上进行建模操作。 3 | 4 | 在这里,你会接触到Android的一些不一样的知识,在Android中如何可以不需要创建layout的方式就能够显示出一个你所绘制的界面。你还会接触到OpenGLES中的知识,会了解到什么是片段着色器,什么是顶点着色器,并且在Android中学会使用它们。 5 | 6 | **学习这门课的前提:** 7 | 8 | * 接触并会简单的使用Android Studio 9 | * 接触并会简单的使用Java进行开发 10 | * 了解一点关于OpenGLES的相关知识 11 | * 最重要的是:求知欲 12 | 13 | -------------------------------------------------------------------------------- /数据结构/数据结构绪论/数据结构绪论.md: -------------------------------------------------------------------------------- 1 | * 在這裡先感謝程杰先生所寫的《大話數據結構》這本書,讓我在這裡面學到了什麼才是數據結構 2 | * 這裡也只是我的一些關於數據結構的學習的感想以及學習的歷程 3 | * 不多說啦,開始學習啦 4 | ## 有關於數據結構的起源 5 | * 關於數據結構的學醫總歸還是需要學習來源的。 6 | * 早期人們都是把計算機理解為數值計算工具,所以計算機解決問題應該是先從具體問題中抽象出一個數據模型,設計出一個數據模型的算法,然後再編寫程序,得到一個實際的軟件 7 | #### 然而現實中,我們更多的不是解決數值計算的問題,而是需要一些更科學的更加有效的手段(比如說表、樹和圖等數據結構)的幫助,才能更好的處理問題。 8 | ### 數據結構是一門研究非數值計算的程序設計問題中的操作對象,以及他們之間的關係和操作等相關問題的學科。 9 | # 數據結構的基本概念和術語 10 | 說到數據結構是什麼,我們得先來談談什麼叫數據 11 | -------------------------------------------------------------------------------- /JAVA学习/Object类详解.md: -------------------------------------------------------------------------------- 1 | # Object详解 2 | ## 相等性的比较(==) 3 | + 1)对于原生数据类型来说,比较的是左右两边的值是否相等。 4 | + 2)对于引用类型来说,比较左右两边的引用是否指向同一个对象,或者说左右两边的引用地址是否相同。 5 | ## java.lang.Object类 6 | java.lang包在使用的时候无需显式导入,编译的时候由编译器自动帮助我们导入。 7 | ## API(Application Programming Interface) 8 | 应用编程接口 9 | #### 当打印引用时,实际上会打印出引用所指对象的toString()方法的返回值,因为每个类都直接或间接的继承自Object,而Object类中定义了toString()方法,所以每一个类中都有toString()这个方法 10 | ## 关于进制的表示: 11 | 16进制(逢16进1),16进制的数字包括0~9,A,B,C,D,E,F -------------------------------------------------------------------------------- /JAVA学习/泛型的详解.md: -------------------------------------------------------------------------------- 1 | ## 泛型 2 | > 泛型是一个定义的通用的通用类型,意味着是我定义一个相同模式的数据访问方式或者是同类别的数据,使用泛型的方式,就可以让每一次写的时候更加简便。 3 | 4 | >下面就是一个泛型的例子 5 | 6 | ```java 7 | public class GenericFoo { 8 | 9 | private T foo; 10 | 11 | public T getFoo() { 12 | return foo; 13 | } 14 | 15 | public void setFoo(T foo) { 16 | this.foo = foo; 17 | } 18 | } 19 | ``` 20 | 21 | > 泛型中的`T`用什么字母都行,这只是一种习惯。 22 | 23 | > `泛型的出现是在java1.5之后` 24 | -------------------------------------------------------------------------------- /shell脚本.md: -------------------------------------------------------------------------------- 1 | # shell概述 2 | 3 | 交互式地解释、执行用户输入的命令,将用户的操作翻译成机器可以识别的语言。`shell是用户和linux内核之间的接口程序。` 4 | 5 | **shell的本质是对内核起到保护作用,只有shell能够识别的命令才能够直接操作内核来控制硬件。** 6 | 7 | + shell脚本是shell命令的有序集合 8 | 9 | shell脚本可以分为两类: 10 | 11 | ## 系统进行调用 12 | 这类脚本无需用户调用,系统会在合适的时候调用,如:/etc/profile、~/.bashrc等。 13 | + /etc/profile 14 | 15 | 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,系统的公共环境变量在这里设置。*自启动一般也在这里设置* 16 | 17 | + ~/.bashrc 18 | 19 | 用户自己的家目录中的.bashrc,登录时会自动调用,打开任意终端时也会自动调用。这个文件一般设置与个人用户有关的环境变量,如交叉编译器的路径等等。 20 | 21 | ## 用户编写,需要手动调用 -------------------------------------------------------------------------------- /C&C++/C++学习.md: -------------------------------------------------------------------------------- 1 | # 输入输出 2 | 3 | + 标准库(standard library)提供IO机制 4 | + iostream库: 5 | + istream(输入流) 6 | + ostream(输出流) 7 | 8 | ## 读取数量不定的输入数据 9 | 10 | ```c++ 11 | 12 | #include 13 | int main() 14 | { 15 | int sum = 0, value = 0; 16 | //读取数据直到遇到文件尾,计算所有读入的值的和 17 | while(std::cin >> value) 18 | { 19 | sum += value;//等价于sum = sum + value 20 | } 21 | std::cout << "Sum is: " << sum << std::endl; 22 | return 0; 23 | } 24 | 25 | ``` 26 | 27 | + 对于Windows系统来说,输入文件结束符的方法是敲Ctrl+Z(按住Ctrl键的同时按Z键) 28 | -------------------------------------------------------------------------------- /JAVA学习/面向对象.md: -------------------------------------------------------------------------------- 1 | + 1,break语句:经常用在循环语句中,用于跳出整个循环,执行循环后面的代码。 2 | 3 | + 2,继续语句:经常用在循环语句中,用于跳出当前的这个循环(或者是跳出本次循环),开始下一次循环的执行。 4 | 5 | + 3,break与continue可以搭配标签使用,在实际开发中,根本没有人转移break与continue搭配标签来使用。 6 | 7 | + 4,面向对象程序设计(Object Oriented Programming,OOP; Object Oriented Design,OOD)。什么是面向对象?在面向对象程序设计中有两个重要的概念:类(class)与对象(object)。 8 | 9 | + 5,类:类是一种抽象的概念,类中包含了数据(通常使用名词来表示)与对数据的操纵(通常使用动词来表示)。年龄,身高等数据,还有吃饭,跑步等操纵数据的动作。 10 | 11 | + 6,对象:对象是一种具体的概念,是类的一种具体表示方式。比如说人是一个类,而张三,李四,王五等具体的人就是对象。 12 | 13 | + 7,类所包含的内容,类一共包含两部分内容: 14 | + a)数据,数据在类中的属性(属性或属性)或叫成员变量(成员变量)。 15 | + b)对数据的操纵,这种操纵在类中的方法(方法)。 -------------------------------------------------------------------------------- /JAVA学习/String类源代码深析.md: -------------------------------------------------------------------------------- 1 | # Object类中equals()方法 2 | * 该方法定义在Object类当中,因此java中的每个类都具有该方法 3 | * 对于Object类中的equals()方法來說,它判斷調用equals()方法的引用與傳進來的引用是否一致,即這兩個引用是否指向的是同一個對象。 4 | * 對於Object類的equals(),它等於“==” 5 | # String類中equals()方法 6 | * 對於String類中的equals()方法來說,它是判斷當前字符串與傳進來的字符串的內容是否一致 7 | * 對於String對象的相等性判斷來說,請使用equals()方法,而不要使用"==" 8 | ### 注 9 | 對於有的時候面試的時候有人問equals()方法到底什麼意思你不能籠統地說“等號表示的是判斷地址是不是”;還有人說equals()方法判斷內容是否相等,然後“==”表示引用的地址內容是否一致的-->這麼說是不準確的 10 | * 應該這樣說: 11 | * 對於Object類中來說,它是判斷兩個對象是否相等的,是否是同一個對象 12 | * 對於繼承了Object類的其他類來說,如果重寫了equals()方法,那才是判斷字符串內容是否相等 13 | * 如果沒有重寫Object類的方法,那麼繼承過來了之後還是判斷地址,而不是判斷內容了 14 | -------------------------------------------------------------------------------- /计算机基础/离散数学及其应用(笔记).md: -------------------------------------------------------------------------------- 1 | # 逻辑和证明 2 | * 命题————逻辑的基本成分 3 | >* 令p和q为命题。p、q的析取用p∨q表示,即命题“p或q”。当p和q均为假得到时候,p∨q命题为假,否则为真。 4 | >#### 注意:连接词“或”在析取中的使用对应于词“或”(or)包含的两种情况之一,即为“同或”(inclusive or)。析取所含两命题之一为真或两者均为真时,析取的真值为真。有的时候我们也按照“异或”的含义使用“或”。 5 | 6 | * 逻辑连接词广泛的应用在大量信息检索中,例如:检索网页索引。 7 | * 比如:布尔检索 8 | 9 | * 模糊逻辑可用于人工智能。————在模糊逻辑中命题的真值是介于0和1(包括0和1)之间的数。以0为真值的命题为假,以1位真值的命题为真。0和1之间的真值表示不同程度的真值。 10 | * 复合命题称为**永真式**(或重言式),如果无论其中出现的**命题**的真值是什么,它的**真值总是真**。**真值永远为假**的复合命题称为**矛盾**。最后,既不是永真式又不是矛盾的命题称为可能式。 11 | 12 | * 下面是逻辑计算中的等价关系的常用计算 13 | 14 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/equivalence.png?raw=true) 15 | -------------------------------------------------------------------------------- /MarkDown用法.md: -------------------------------------------------------------------------------- 1 | # This is an H1 2 | ## This is an H2 3 | ### This is an H3 4 | #### This is an H4 5 | ##### This is an H5 6 | ###### This is an H6 7 |

备注: 行首n个#表示n阶标题,n最大为6

8 |
9 | ## *这是一段斜体* _这也是一段斜体_ 10 | ## **这是一段粗体** 11 | ## ***这是一段加粗斜体*** 12 | ## ~~这是一段删除线~~ 13 |
14 | 这是一个一级标题 15 | =================================== 16 | 这是一个二级标题 17 | ----------------------------------- 18 |
19 | - 无序列表项 一 20 | - 无序列表项 二 21 | - 无序列表项 三 22 |
23 | 1. 有序列表项 一 24 | 2. 有序列表项 二 25 | 3. 有序列表项 三 26 |
27 | >>> 请问 Markdwon 怎么用? - 小白 28 | >> 29 | >> 自己看教程! - 愤青 30 | > 31 | > 教程在哪? - 小白 32 | -------------------------------------------------------------------------------- /JAVA学习/反射/Person.java: -------------------------------------------------------------------------------- 1 | package com.dell.example.reflactDemo; 2 | 3 | /** 4 | * Created by 20304 on 2017/10/31. 5 | */ 6 | public class Person { 7 | private Integer _number; 8 | private String name; 9 | private String address; 10 | 11 | public Integer get_number() { 12 | return _number; 13 | } 14 | 15 | public void set_number(Integer _number) { 16 | this._number = _number; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public String getAddress() { 28 | return address; 29 | } 30 | 31 | public void setAddress(String address) { 32 | this.address = address; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /C&C++/C_指针.md: -------------------------------------------------------------------------------- 1 | # 指针 2 | 3 | ## 内存相关内容 4 | 5 | ### 存储器:存储数据器件 6 | 7 | + 外存 8 | + 外部存储器,长期存放数据。如:硬盘、flash、U盘、光盘、磁带等等 9 | + 内存 10 | + 内部存储器,暂时存储数据,掉电丢失。如:ram、DDR 11 | 12 | #### 物理内存 13 | 14 | 实实在在的存储设备 15 | #### 虚拟内存 16 | 17 | 操作系统虚拟出来的内存,当一个进程被创建的时候,后者程序运行的时候都会被分配虚拟内存,虚拟内存与物理内存又实际的映射关系。 18 | 19 | ### 内存分区 20 | 21 | 在运行程序时,操作系统会将虚拟内存进行分区: 22 | 23 | + 堆: 24 | + 在动态申请内存的时候,在堆内开辟内存。 25 | + 栈: 26 | + 主要存放局部变量(在函数内部,或者复合语句内定义的变量)。 27 | + 静态全局区 28 | + 1、未初始化的静态全局区 29 | + 静态变量(定义的时候,前面加static修饰),或全局变量,没有初始化的,存在此区 30 | + 2、初始化的静态全局区 31 | + 全局变量、静态变量、赋过初值的,存放在此区 32 | + 代码区 33 | + 存放程序代码 34 | + 文字常量区 35 | + 存放常量的 36 | 37 | ## 指针相关概念 38 | 39 | `指针就是地址` 40 | 41 | 在32位平台下,`地址总线`是32位的,所以地址是32位编号,所以指针变量是32位->4字节 42 | 43 | `注:` 44 | + 字符变量 char ch;其中ch占一个字节,它有一个地址编号,这个地址编号就是ch的地址。 45 | + 整型变量 int a; a 占4个字节,它占有4个字节的存储单元,有4个地址编号。 -------------------------------------------------------------------------------- /后端/Django服务器部署.md: -------------------------------------------------------------------------------- 1 | # Django服务器部署到腾讯云 2 | + 配置腾讯云的服务器 3 | + 配置的系统是Ubuntu Server 16.04.1 LTS 64位 4 | + 登录后界面如图: 5 | - ![](../image/TencentServerLogin.png) 6 | - 之后进行django的安装**注意版本号要和你在本地开发的一致** 7 | - 使用screen进行后台的django项目的运行。**注意runserver后设置:0.0.0.0:端口号** 8 | 9 | + 使用PyCharm进行远程连接腾讯云服务器 10 | + Tools-->Deployment-->config呈现下面的界面 11 | - ![](../image/PyCharmAddServer.png) 12 | - 13 | 选择**sftp** 14 | - ![](../image/PyCharmDeployment.png) 15 | - 在这里设置你的IP地址,然后点击`Test SFTP connection` 16 | - ![](../image/PyCharmTestConnection.png) 17 | - 在这里设置你的`用户名`和`密码`**用户名与密码可以在腾讯云的更多中重置与设置** 18 | - 然后这个时候就连接上了 19 | + 此时,在你的PyCharm的右边,会出现服务器上的树目录结构(如图所示) 20 | - ![](../image/PyCharmAdmin.png) 21 | - 进入到home-->ubuntu下,在这里面,你具有权限,此时就可以将你的整个项目拖进去,然后在服务器端进入到项目中**创建screen后台**,运行**manage.py runserver 0.0.0.0:端口号**就可以使你的django一直保持运行的状态了。 22 | -------------------------------------------------------------------------------- /Android/Android面经课.md: -------------------------------------------------------------------------------- 1 | # Android面经老司机 2 | 3 | + 3条职业线: 4 | + 1、进大厂、纯技术;如:阿里P7 5 | + 1-2年 技术沉淀,最好是找比较有名的公司或者产品。 6 | + 进大厂(内推)走内推处理流程会快。 7 | + 走得快的人,4年就能走完,3年就能走完。 8 | + 2、创业/自由职业 9 | + 如:13年左右,上海张江高科,进了一家外包。 当时13k 10 | + 迷茫 2年 1年左右 回家 11 | + 四川 进了一家公司 不著名 主程 1年 12 | + 进军北京 14年 A轮->B轮->C轮->D轮卡住了 3W多月薪 13 | + 认识了很多非常牛逼的人 14 | + 区块链出来了 直接挖他创业 纯技术入股 15 | + 3、转行 16 | 17 | `高级工程师一般几年可以达到?` 18 | >**4年左右** 19 | > 20 | >1-2年 初级 基本公司实际开发经验有了 21 | > 22 | > 能够独立开发功能比较简单的应用 23 | > 24 | > 第3年不但能够独立开发,还能够开发小中型项目,并且有一定管理经验 25 | > 26 | > 第4年开始,就是一个分水岭 27 | 28 | ## 阿里等级划分 29 | > P1、P2一般是空缺,是为非常低端岗位预留的,P3是助理,P4是初级专员,P5是高级工程师,P6是资深工程师,P7是技术专家,P8是高级专家,P9是资深专家,P10是研究员,P11是高级研究员,P12是科学家,P13是首席科学家,P14马云。 30 | > 31 | > 管理岗基础等级划分:P6对应待遇和M1相同,P7对应M2,P8对应M3,P9对应M4,P10对应M5,M5之后属于董事会成员。 32 | > 33 | > P4年薪10-15w,P5大概15-20w,P6为不持股员工,P7为持股员工。 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /JAVA学习/String类陷阱深度解析.md: -------------------------------------------------------------------------------- 1 | # String类陷阱深度解析 2 | `注:` 3 | + 对于String对象的相等性判断,使用equals()方法,而不要用“==” 4 | + String 是常量,其对象一旦创建完毕就无法改变,当使用+凭借字符串的时候会生成新的String对象,而不是向原有的String对象追加内容 5 | ## String 创建对比 6 | `注:`String pool(字符串池) 7 | ### 第一种创建方式 8 | 9 | ```java 10 | string s = "aaa";//(采用字面值方式赋值) 11 | ``` 12 | 13 | + 1、查找**String Pool**中是否有“aaa”这个对象,如果不存在则在**String Pool**中创建一个“aaa”对象并将“aaa”对象地址返回,赋给引用变量s,这样s会指向**String Pool**中的“aaa”对象。 14 | + 2、如果**String Pool**中存在,则不创建对象,直接将**String Pool**中的“aaa”对象地址返回,赋给s引用。 15 | 16 | ### 第二种创建方式 17 | 18 | ```java 19 | String s = new String("aaa"); 20 | ``` 21 | 22 | + 1、首先在**String Pool**中查找有没有“aaa”字符串对象,如果有,则不在**String Pool**中再去创建“aaa”对象,直接在 **堆(heap)** 中创建一个“aaa”字符串对象,然后将堆中的地址返回赋给s引用,导致s指向了堆中的对象。 23 | + 2、如果**String Pool**中没有“aaa”对象,那么会在**String Pool**中创建一个“aaa”对象, 然后再在 **堆(heap)** 中创建一个“aaa”对象,返回的地址是堆中的地址。 24 | 25 | `注:`new出来的对象所指向的都是 **堆(heap)** 中所创建的。 -------------------------------------------------------------------------------- /数据结构/串/KMP算法.md: -------------------------------------------------------------------------------- 1 | # KMP算法 2 | > **前言:**KMP算法是一种模式匹配算法,由D.E.Knuth、J.H.Morris和V.R.Pratt三人发表的一个模式匹配算法【当我看懂之后,对这三位前辈的敬畏之情油然而生】。`最重要的是,可以大大的避免重复遍历的情况的发生!` 3 | 4 | >话不多说,让我们看一看KMP算法的神奇之处。 5 | 6 | ### 朴素的模式匹配算法 7 | + 首先,我们得先知道最简单,最容易想到的朴素的模式匹配算法是如何实现的。 8 | 9 | ``` 10 | private static int MatchingTest(String S,String T) { 11 | for(int i = 0; i < S.length(); i++) 12 | { 13 | int k = i; 14 | for(int j = 0; j < T.length();j++) 15 | { 16 | if(S.charAt(k) != T.charAt(j)) 17 | { 18 | break; 19 | } 20 | else 21 | { 22 | k++; 23 | if(j == T.length()-1) 24 | { 25 | return i; 26 | } 27 | } 28 | } 29 | } 30 | return -1; 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /后端/Java后端学习/SpringIoc学习.md: -------------------------------------------------------------------------------- 1 | # SpringIOC 底层实现原理 2 | 3 | ## 传统方式开发 4 | 5 | ```java 6 | UserService us = new UserService(); 7 | ``` 8 | 9 | + 面向接口编程 10 | 11 | ```java 12 | UserService us = new UserServiceImpl(); 13 | ``` 14 | 15 | + ocp原则:Open-Close远测,对程序扩展是Open的,对修改程序代 码是close的。**尽量做到不修改程序代码,实现对程序的扩展。** 16 | 17 | `工厂模式` 18 | 19 | ![示意图](https://img2020.cnblogs.com/blog/1410558/202103/1410558-20210306175200448-286289027.png) 20 | 21 | 大体实现过程如下: 22 | 23 | ```java 24 | class FactoryBean{ 25 | public static UserService getUs(){ 26 | return new UserServiceImpl(); 27 | } 28 | 29 | …… 30 | } 31 | 32 | 33 | UserService us = FactoryBean(); 34 | ``` 35 | 36 | `工厂 + 反射 + 配置文件` 37 | 38 | ```xml 39 | 40 | ``` 41 | 42 | ```java 43 | class FactoryBean{ 44 | public static Object getBean(String id){ 45 | …… 46 | //反射的方式获取到实例对象 47 | } 48 | } 49 | ``` -------------------------------------------------------------------------------- /JAVA学习/Java之异常.md: -------------------------------------------------------------------------------- 1 | # 异常 2 | + 做运行时异常,java中所有的运行时异常都会直接或间接地继承自RuntimeException 3 | + Java中凡是继承自Exception的类都是非运行时异常 4 | 5 | **** 6 | 7 | ```Java 8 | public static void main(String[] args) 9 | { 10 | int a =3; 11 | int b = 0; 12 | 13 | int c = a/b; 14 | System.out.println("Hello World"); 15 | 16 | System.out.println(c); 17 | 18 | } 19 | ``` 20 | 21 | **** 22 | 23 | 如上面的代码中的c,会默认为是会抛出异常的 24 | + Java中关于抛出异常是有几种严格的规定的 25 | + 第一种:try与catch相结合 26 | 27 | ```Java 28 | int c = 0; 29 | try 30 | { 31 | int a = 3; 32 | int b = 0; 33 | c = a/b; 34 | } 35 | catch(ArithemticException e) 36 | { 37 | 38 | } 39 | System.out.println(c); 40 | ``` 41 | 42 | 上面的代码是可以运行的, 运行结果为0。**在java中,每一个异常就是一个类,当程序执行到某一行,出现了异常的情况,那么Java会在你会产生异常的那一行代码的位置处生成一个关于这个异常的对象,这个对象是由运行的时候动态的生成的** 43 | 44 | 所以上面的c=a/b;这一行代码会自动生成一个对象,而这个对象就是ArithemticException 45 | 46 | **而catch块的意思就是,当我捕获到有这个对象生成,那么就由我的catch块中的代码去执行接下来的步骤** 47 | 48 | `这个是try与catch的关于异常的固定的处理模式` 49 | -------------------------------------------------------------------------------- /JAVA学习/java1.5新特性之自动装箱与自动拆箱.md: -------------------------------------------------------------------------------- 1 | ## 自动装箱 2 | >基本类型自动转为包装类 `int >> Integer` 3 | 4 | >自动装箱是编译器通过自动调用`valueOf()`实现的。 5 | 6 | >***下面的就是将3自动装箱转换成Integer类型并放到集合中*** 7 | 8 | ```java 9 | public class BoxTest { 10 | public static void main(String[] args) { 11 | int a = 3; 12 | Collection c = new ArrayList(); 13 | 14 | c.add(3); //这里就是自动的装箱,将3转换成Integer类型并放到集合中 15 | } 16 | } 17 | ``` 18 | 19 | ## 自动拆箱 20 | > 包装类自动转为基本类型 `Integer >> int` 21 | 22 | 23 | ## 面试常见题目: 24 | > 自动拆箱与自动装箱的问题。 25 | 26 | >Iteger的范围为`[-128,127]`。 27 | 28 | ```java 29 | public class App { 30 | public static void main(String[] args) { 31 | Integer i1 = 127; 32 | Integer i2 = 127; 33 | Integer i3 = 128; 34 | Integer i4 = 128; 35 | 36 | System. out.println(i1 == i2); 37 | System. out.println(i3 == i4); 38 | } 39 | 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /C&C++/C++并发编程实战/第一章.md: -------------------------------------------------------------------------------- 1 | # C++的并发世界 2 | 3 | 主要内容: 4 | + 什么是并发和多线程? 5 | + 为什么用并发和多线程? 6 | + 如何用并发和多线程? 7 | 8 | ## 什么是并发? 9 | 10 | 两个或更多独立的活动同时进行。在计算机领域中表现为:**单个系统中同时执行多个独立的任务。** 11 | 12 | ### 单核任务切换VS多核硬件并发 13 | 14 | + 单核任务切换 15 | 16 | ![单核切换](https://github.com/kentanvictor/STUDY/blob/Image/C%2B%2B%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E5%AE%9E%E6%88%98/%E5%8D%95%E6%A0%B8%E4%BB%BB%E5%8A%A1%E5%88%87%E6%8D%A2.png?raw=true) 17 | 18 | + 多核硬件并发 19 | 20 | ![多核硬件并发](https://github.com/kentanvictor/STUDY/blob/Image/C%2B%2B%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E5%AE%9E%E6%88%98/%E5%A4%9A%E6%A0%B8%E7%A1%AC%E4%BB%B6%E5%B9%B6%E5%8F%91.png?raw=true) 21 | 22 | ### 多进程并发 23 | 24 | 独立进程可通过进程间常规的通信渠道传递信息(信号、套接字、文件、管道等等)。 25 | 26 | 缺点之一:运行进程所需的固定开销:需要时间启动进程,操作系统需要内部资源来管理进程等等。 27 | 28 | 独立进程实现并发的额外优势:可通过远程连接在不同的机器上运行独立的进程。 29 | 30 | ### 多线程并发 31 | 32 | 每个线程相互独立运行,并共享地址空间,因此线程可以通过共享内存进行通信。 33 | 34 | **如果数据要被多个线程访问,那么必须保证每个线程所访问到的数据是一致的** 35 | 36 | ## 为什么用并发 37 | 38 | ### 分离(SOC) 39 | 40 | ### 性能 -------------------------------------------------------------------------------- /C&C++/二进制压缩算法.md: -------------------------------------------------------------------------------- 1 | # 树状数组 2 | 3 | * 这是一个基于二进制的一种线段树搜索算法 4 | 5 | ## 这个的主要思想是“二进制” 6 | 7 | ![树状数组](./image/Fenwick_tree.jpg) 8 | 9 | * 代码如下: 10 | 11 | ```c++ 12 | #include 13 | using namespace std; 14 | int n,m,i,num[100001],t[200001],l,r;//num:原数组;t:树状数组 15 | int lowbit(int x) 16 | { 17 | return x&(-x); 18 | } 19 | void change(int x,int p)//将第x个数加p 20 | { 21 | while(x<=n) 22 | { 23 | t[x]+=p; 24 | x+=lowbit(x); 25 | } 26 | return; 27 | } 28 | int sum(int k)//前k个数的和 29 | { 30 | int ans=0; 31 | while(k>0) 32 | { 33 | ans+=t[k]; 34 | k-=lowbit(k); 35 | } 36 | return ans; 37 | } 38 | int ask(int l,int r)//求l-r区间和 39 | { 40 | return sum(r)-sum(l-1); 41 | } 42 | int main() 43 | { 44 | cin>>n>>m; 45 | for(i=1;i<=n;i++) 46 | { 47 | cin>>num[i]; 48 | change(i,num[i]); 49 | } 50 | for(i=1;i<=m;i++) 51 | { 52 | cin>>l>>r; 53 | cout< 自我学习笔记,从上层layout的加载到HAL的绘制展示。 4 | 5 | ## 大致过程 6 | 7 | 整个显示过程由App、system_server和SurfaceFlinger三个进程共同配合完成: 8 | 9 | + App:负责画图 10 | 11 | + system_server:负责控制图层 12 | 13 | + SurfaceFlinger:负责混合图层并显示 14 | 15 | 这个涉及到画图与合图的过程,App负责画图,SurfaceFlinger负责合成所有图层并展示。 16 | 17 | ### 可以画图的 **"画笔"** : 18 | 19 | + Skia:CPU绘制2D图形 20 | 21 | + OpenGL:GPU绘制3D图形 22 | 23 | ### 可以合图的 **"工具"** : 24 | 25 | + GPU:使用OpenGL来合成图层 26 | 27 | + HWC:使用显示控制器来合成图层 28 | 29 | 30 | ## 详细过程 31 | 32 | + setContentView(@LayoutResint layoutResID) 33 | 34 | 从代码中可以看到,继承的Activity中的setContentView方法以及AppCompatActivity中实现的,代码如下: 35 | 36 | ```java 37 | @Override 38 | public void setContentView(View view) { 39 | getDelegate().setContentView(view); 40 | } 41 | ``` 42 | 43 | 在这上面可以看到一个 **getDelegate()** 这么一个方法,这个方法最终return的是一个AppCompatDelegate对象。AppCompatDelegate类是用来进行AppCompatActivity代理的,AppCompatActivity将大部分生命周期都委托给AppCompatDelegate。 44 | 45 | 通过代码跳转我们可以看到:AppCompatDelegate是一个抽象类,这个抽象类中的抽象方法最终实现的地方是:AppCompatDelegateImpl中。 46 | 47 | -------------------------------------------------------------------------------- /Android/Android第一行代码/开始启程.md: -------------------------------------------------------------------------------- 1 | # 第一章 2 | 3 | ## Android系统架构 4 | 5 | Android系统架构大致可以分为四层: 6 | + Linux内核层 7 | + 主要是提供驱动 8 | + 系统运行库层 9 | + C/C++库提供特性支持,如:SQLite库、OPenGL|ES库、Webkit库等 10 | + Android运行时核心库,如:ART运行环境、Dalvik虚拟机等 11 | + 应用框架层 12 | + 各种API 13 | + 应用层 14 | + 所有安装再手机上的应用程序都属于这一层 15 | 16 | 经典老图: 17 | 18 | ![](https://github.com/kentanvictor/STUDY/blob/Image/Android%E7%AC%AC%E4%B8%80%E8%A1%8C%E4%BB%A3%E7%A0%81/Android%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E5%9B%BE.png?raw=true) 19 | 20 | ## 四大组件 21 | 22 | ### 活动(Activity) 23 | 24 | 凡是应用中所能看到的东西都在Activity中。 25 | 26 | ### 服务(Service) 27 | 28 | 实现程序后台运行的解决方案,非常适合去执行不需要和用户交互而且还要求长期运行的任务。 29 | 30 | ### 广播接收器(Broadcast Receiver) 31 | 32 | 广播接收器用于响应来自其他应用程序或者系统的广播消息。这些消息有时被称为事件或者意图。 33 | 34 | ### 内容提供器(Content Provider) 35 | 36 | 内容提供者组件通过请求从一个应用程序向其他的应用程序提供数据。 37 | 38 | ## 第一个Android程序 39 | 40 | 在目录结构下有很多内容,列举一些做出说明 41 | 42 | + app文件夹 43 | + 项目中的代码、资源等内容几乎都放置在这个目录下 44 | + gradle 45 | + 构建系统工具 46 | + .gitignore 47 | + 版本控制相关,用来将指定的目录或文件排除在版本控制之外 48 | + build.gradle 49 | + 项目全局的gradle构建脚本 50 | + gradle.properties 51 | + 全局gradle配置文件,在这配置的属性会影响到项目中所有的gradle编译脚本 52 | + local.properties 53 | + 指定本机中Android SDK路径 54 | + settings.gradle 55 | + 指定项目中所引入的模块 56 | -------------------------------------------------------------------------------- /JAVA学习/包与导入语句的剖析.md: -------------------------------------------------------------------------------- 1 | # 包(package) 2 | 包的概念:有点类似于硬盘中的文件夹的意思。就好比可以在硬盘中建立好几个目录然后分门别类。 3 | 所以java中也引用了包的概念,将不同的源码进行分门别类。 4 | #### 作用: 5 | 用于将完成不同功能的类分门别类,放在不同的目录(包)下。 6 | #### 包的命名规则: 7 | 将公司域名反转作为包名。比如:com.example(包名) 8 | 对于包名,每个字母都需要小写(只是个约定)。 9 | 包的说法就是在硬盘上呈现一个一个的目录而已,将完成不同功能的类放在不同的目录下面。 10 | 比如完成输入输出处理的放在io这个包下面,完成网络通信的类放在网络通信的包下面。 11 | ### 注: 12 | 在使用package的时候需要将生成好的.class文件放在目录(包)下面。这样才能够运行。包的层次结构与包定义的层次结构要一模一样。 13 | 如果没有定义package的话java就会认为我们所定义的类在默认包(default package)里面。 14 | ### 编译 15 | 编译带有package声明的JAVA源文件有两种方式: 16 | a)直接编译,然后根据类中所定义的包名,逐一手工建立目录结构,最后将生成的.class文件放到该目录结构中(很少使用,非常麻烦)。 17 | b)使用编译参数 -d ,方式为 *java -d.源文件.java* ,这样在编译之后,编译器会自动帮助我们建立好包所对应的目录结构。 18 | #### 注: 19 | 有两个包名,分别是aa.bb.cc 与 aa.bb.cc.dd,那么我们称后者为前者的子包。 20 | ## 导入(import) 21 | 将package分离的各个类导入回来,让编译器能够找到所需要的类。 22 | ### import语法: 23 | ``` 24 | import aa.bb.cc; 25 | ``` 26 | 或者 27 | ``` 28 | import aa.bb.*;//表示导入aa文件夹中的bb文件夹中的所有的类 29 | ``` 30 | #### 注: 31 | ``` 32 | import aa.bb.*;//表示导入aa文件夹中的bb文件夹中的所有的类 33 | ``` 34 | 并不会导入aa.bb.cc包下面的类。也就是说,这样写是没有办法导入子包下面的全部的类的,所以,这时候需要 35 | 进行二次import,也就是说还需要导入子包。 36 | ### 关于package、import、class的顺序问题: 37 | + a)首先定义一个包(package),可选 38 | + b)接下来用import进行导入,可选(只有你想使用的类与你所编译的类不在同一个包下才需要导入) 39 | + c)然后才是class或者是interface的定义。 40 | + d)如果两个类在同一个包下面,那么不需要导入,直接使用就可以。(package.aa.bb) 41 | -------------------------------------------------------------------------------- /JAVA学习/IDE的详细介绍.md: -------------------------------------------------------------------------------- 1 | # IDE的详细介绍 2 | * 对于java中的常量的命名规则: 3 | * 所有单词的字母都是大写,如果有多个单词,那么使用下划线链接即可。比如说: 4 | * public static final int AGE_OF_PERSON = 20; 5 | * 常量起的作用:(代码如下:) 6 | 7 | ```java 8 | public class Authorization 9 | { 10 | public static final int MANAGER = 1; 11 | public static final int DEPARTMENT = 2; 12 | public static final int EMPLOYEE = 3; 13 | 14 | } 15 | public class Test 16 | { 17 | public boolean canAccess(int access) 18 | { 19 | if (access == Authorization.MANAGER) 20 | { 21 | return true;//經理訪問權限 22 | } 23 | if(access == Authorization.DEPARTMENT) 24 | { 25 | return false;//部門經理的訪問權限 26 | } 27 | if (access == Authorization.EMPLOYEE) 28 | { 29 | return false;//普通員工的訪問權限 30 | } 31 | 32 | return false; 33 | } 34 | } 35 | 36 | ``` 37 | 38 | * 在java中声明final常量时通常都会加上static关键字,这样对对象的每个实例都会访问唯一一份的常量值。 39 | ## Java中的集合框架 40 | 41 | ![](../image/implement.png) 42 | 43 | * 上面是集合框架的接口 44 | * 所谓框架就是一個类库的集合。集合框架就是一个用来表示和操作集合的统一架构,包含了实现集合的接口与类。 45 | ## IDE(Integrated Development Environment)(集成开发环境) 46 | * 第一個:NetBeans(https://www.NetBeans.org/) 47 | * 第二個:JBuilder(http://edn.embarcadero.com/cn/jbuilder) 48 | * 第三個:IntelliJ IDEA(https://www.jetbrains.com/idea/) 49 | * 第四個:Eclipse(日蚀、月蚀)(https://www.eclipse.org/downloads/) 50 | -------------------------------------------------------------------------------- /JAVA学习/ArrayList与LinkedList.md: -------------------------------------------------------------------------------- 1 | # ArrayList and LinkList 2 | 3 | ## ArrayList 4 | 5 | ## LinkList 6 | 7 | ## ArrayList与LinkList底层数据存储的区别 8 | 9 | * 当向ArrayList添加一个对象的时候,实际上就是将该对象放置到ArrayList底层所维护的数组当中;当向LinkedList中添加一个对象的时候,实际上LinkedList内部会生成一个Entry对象 10 | 11 | * 而entry中是 12 | 13 | ```java 14 | entry 15 | { 16 | Entry previous; 17 | Object element; 18 | Entry next; 19 | } 20 | ``` 21 | 22 | * 如上面的代码所示,这就直接构成了一个数据元素,然后放到链表中. 23 | 24 | * 其中Object类型的元素element就是向LinkedList中所添加的元素,然后Entry又构造好了向前与向后的引用previous、next,最后生成的这个Entry对象加入到了链表中。换句话说,**LinkedList维护的是一个个的Entry对象。** 25 | 26 | # 队列的实现 27 | 28 | + 队列的实现 29 | 30 | ```java 31 | public class MyQueue 32 | { 33 | private LinkedList LinkedList = new LinkedList; 34 | public void put (Object o){ 35 | list.addLast(o); 36 | } 37 | public Object get(){ 38 | return list.removeFirst(); 39 | } 40 | public boolean isEmpty() 41 | { 42 | return list.isEmpty(); 43 | } 44 | 45 | public static void main(String[] args) { 46 | MyQueue myQueue = new MyQueue(); 47 | myQueue.put("one"); 48 | myQueue.put("two"); 49 | myQueue.put("three"); 50 | System.out.println(myQueue.get()); 51 | System.out.println(myQueue.get()); 52 | System.out.println(myQueue.get()); 53 | System.out.println(myQueue.isEmpty()); 54 | } 55 | } 56 | ``` 57 | -------------------------------------------------------------------------------- /JAVA学习/JAVA学习之接口_static_final等关键字.md: -------------------------------------------------------------------------------- 1 | # Java中的接口 2 | ## 关于Java中的接口中的方法 3 | 用abstract关键字来表示。只要是接口中的方法,全部都是abstract的,即为全部都是抽象的,所以在表示接口中的方法时,是不需要在方法中再写abstract的 4 | ## 关于如何实现接口中的抽象方法 5 | 对于接口中的抽象方法,会有一个类用于继承(implements)然后在继承该接口的类中是实现该接口中的抽象方法 6 | 7 | 一个类可以实现多个接口中的抽象方法,多个接口使用implements+接口名,接口名(用逗号隔开) 8 | 9 | # 多态 10 | 所谓多态指的就是,父类型的引用指向子类型的对象,或者接口类型的引用可以指向实现该接口的类的实例。 11 | 12 | 关于接口与实现接口的类之间的强制类型转换方式与父类和子类之间的强制类型转换方式完全一样 13 | # 一共有两种类型的强制转换 14 | 1、向上类型转换(upcast):比如说,Cat类型转换成Animal类型,即将子类型转换为父类型。对于向上类型转换,不需要显示指定。 15 | 2、向下类型转换(downcast):比如说将Animal类型转换为Cat类型。即将父类型转换为子类型。对于向下类型转换,必须要显示指定(即表现为使用强制类型转换)。 16 | 17 | # static 关键字 18 | 可以用在修饰属性(就是成员变量)上,可以用在修饰方法上,也可以用在修饰类上,就是申明一个类,这个类是一个static class 19 | ## 修饰属性 20 | 无论一个类生成多少个对象,所有的这些对象共同使用唯一一份静态成员变量,其他对象的该静态成员变量的值也会随之发生变化 21 | 可以通过类名.成员变量名的方式使用它(推荐这种方式调用) 22 | ## static修饰方法: 23 | static修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名的方式来访问。 24 | 子类可以继承超类的静态方法但是子类是不可重写超类的方法(即为隐藏了父类的方法) 25 | ## 注 26 | 在子类中要重写超类中的方法需要在前面加上@override就可以重写超类中的方法,但是不可以重写static method(静态方法)只能继承 27 | # final 关键字 28 | final关键字可以修饰属性、方法和类 29 | 30 | ## final 修饰类: 31 | 当一个类被final修饰的时候表示该类是一个终态,即不能被继承。 32 | ## final 修饰方法: 33 | 当一个方法被final修饰时,代表着这个方法是一个终态的方法,即不能再被重写(Override)。 34 | ## final 修饰属性: 35 | 当一个属性被final所修饰时,表示该属性不能被改写。 36 | ## 注 37 | 当final修饰一个原生数据类型时,表示该原声数据类型的值不能发生变化(比如说不能从10变为20);如果final修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。 38 | -------------------------------------------------------------------------------- /数据结构/数据结构绪论/数据中的结构.md: -------------------------------------------------------------------------------- 1 | ## 什麼是數據結構中的結構 2 | * 結構 3 | * 簡單的理解就是關係,比如分子結構,就是組成分子的原子之間的排列方式。嚴格點說,結構是指各個組成部分相互搭配和排列的方式。 4 | * 不同數據元素之間不是相互獨立的,而是存在特定的關係,我們將這些關係稱為結構 5 | # 什麼是數據結構 6 | * 數據結構:是相互之間存在一種或多種特定關係的數據元素的集合 7 | 8 | ## 接下來看一下邏輯結構與物理結構 9 | ### 邏輯結構 10 | * 邏輯結構 11 | * 是指數據對象中數據元素之間的相互關係。其實我們需要關注的問題,邏輯結構主要分為以下四種: 12 | * 集合結構 13 | >**集合結構:集合結構中的數據元素除了同屬於一個集合外,它們之間沒有其他的關係。** 14 | 各個元素是“平等”的,它們的共同屬性是“同屬於一個集合”。數據結構中的集合關係就類似於數學中的集合 15 | * 線性結構 16 | >**線性結構:線性結構中的數據元素之間是一對一的關係** 17 | 18 | ![](http://i1.piimg.com/519918/8409b0f5f4f62d75.jpg) 19 | 20 | * 樹形結構 21 | >**樹形結構:樹形結構中的數據元素之間存在的一種一對多的層次關係** 22 | 23 | ![](http://i1.piimg.com/519918/73ec4ca8941d3a3e.jpg) 24 | 25 | * 圖形結構 26 | >**圖形結構:圖形結構的數據元素是多對多的關係** 27 | 28 | ![](http://p1.bpimg.com/519918/aac51e559365ad53.jpg) 29 | 30 | #### 注意:我們在用示意圖表示數據結構的時候,要注意兩點: 31 | * 將每一個數據元素看做一個節點,並用圓圈表示。 32 | * 元素之間的邏輯關係用節點之間的連線表示,如果這個關係是有方向的,那麼用帶箭頭的連線表示。 33 | ### 物理結構 34 | >說完了邏輯結構,我們再來說說數據的物理結構(**也可以叫做存儲結構**) 35 | 36 | * 物理結構 :是指數據的邏輯結構在計算機中的存儲形式。 37 | * 物理結構實際上就是如何把數據元素存儲到計算機的存儲器中。存儲器主要是針對內存而言,像硬盤、軟盤、光盤等外部存儲器的數據組織通常用文件結構來描述。 38 | #### 數據元素的存儲結構形式有兩種:順序存儲與連式存儲 39 | * 順序存儲結構 40 | * 順序存儲結構是把數據元素存放在地址連續的存儲單元里,其數據間的邏輯關係和物理關係是一致的。 41 | >通俗理解為:排隊佔位 42 | 43 | * 鏈式存儲結構 44 | * 連輸存儲結構:是把數據元素存放在任意的存儲單元里,這組存儲單元可以是連續的也可以是不連續的。 45 | >對於鏈式存儲結構,是不能夠直觀的反映其邏輯關係,因此需要同一個指針存放數據元素的地址(**就相當於用指針進行佔位,通過地址找到相關數據元素的位置**) 46 | -------------------------------------------------------------------------------- /Android/Android框架揭秘/init进程.md: -------------------------------------------------------------------------------- 1 | # init进程 2 | 3 | init进程是Android启动后,由内核启动的第一个用户级进程。 4 | 5 | 1. start_kernel() 6 | 2. init_post() 7 | 3. run_init_process() 8 | 9 | 顺序执行完以上三个步骤就会运行init进程 10 | 11 | ```c 12 | static int moinline init_post(void) 13 | { 14 | if(execute_command){ 15 | run_init_process(execute_command); 16 | } 17 | run_init_process("/sbin/init"); 18 | run_init_process("/etc/init"); 19 | run_init_process("/bin/init"); 20 | run_init_process("/bin/sh"); 21 | } 22 | ``` 23 | 24 | 如果内核在以上的目录以及未指定启动项的情况下找不到init文件,内核就会终止init进程,从而触发`Kernel Panic`。 25 | 26 | ## 四大功能 27 | 28 | Android init进程主要提供了四大功能: 29 | 30 | + 分析及运行init.rc文件 31 | + 分析init.rc和init.{hardware}.rc文件 32 | + 运行early-init动作列表 33 | + 执行init动作列表 34 | 35 | + 生成设备驱动节点 36 | + 生成并装载目录 37 | + 生成设备静态节点 38 | + 注册POLL事件 39 | 40 | + 处理子进程终止 41 | + 注册SIGCHLD信号Handler 42 | + 生成UDS套接字 43 | + 注册POLL事件 44 | 45 | + 属性服务 46 | + 属性初始化 47 | + 属性初始化设置 48 | + 运行属性服务 49 | + 注册POLL事件 50 | 51 | 每个进程在处理其他进程发送的信号时,都要注册程序,此程序被称为`信号处理器`。 52 | 53 | 子进程终止产生SIGCHILD信号时,init进程需要调用信号安装函数**sigaction()** 54 | 55 | init进程的加载是位于init.cpp下的,该cpp文件是位于\**/system/core/init文件夹下的 56 | 57 | 而init.cpp所加载的所有的.rc文件是位于\**/system//core/rootdir文件夹下的 58 | 59 | ## 五大生命类型 60 | 61 | ### Action 62 | 63 | ### Command 64 | 65 | ### Services 66 | 67 | ### Imports 68 | 69 | ### Options 70 | 71 | ## 两种数据类型 -------------------------------------------------------------------------------- /Python编程从入门到实践读书笔记/Unit3/列表学习.md: -------------------------------------------------------------------------------- 1 | # 列表 2 | 3 | ## 列表是什么 4 | 5 | > 一系列按特定顺序排列的元素。 6 | 7 | + 用 **[]** 来表示列表,并用逗号分隔其中的元素。 8 | 9 | ### 访问列表元素 10 | 11 | + 和数组的访问类似,但是列表是 **可以创建一个空列表** 的。 12 | + python为访问最后一个列表元素提供了一种特殊语法。 **索引指定为-1,返回最后一个元素。** 这种负数索引依此类推,-2返回倒数第二个元素,-3返回倒数第三个元素。 13 | 14 | 15 | ```python 16 | bicycles = ['trek','cannondale','redline','specialized'] 17 | print(bicycles[-1]) 18 | print(bicycles[-2]) 19 | ``` 20 | 21 | 运行结果如下: 22 | 23 | ![负数索引](https://github.com/kentanvictor/STUDY/blob/Image/Python%E7%BC%96%E7%A8%8B%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%AE%9E%E8%B7%B5/%E5%88%97%E8%A1%A8%E8%AE%BF%E9%97%AE.png?raw=true) 24 | 25 | ### 列表元素的增删改插 26 | 27 | #### 改 28 | 29 | + 改动方式与数组相似。 30 | 31 | ![](https://github.com/kentanvictor/STUDY/blob/Image/Python%E7%BC%96%E7%A8%8B%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%AE%9E%E8%B7%B5/%E5%88%97%E8%A1%A8%E4%BF%AE%E6%94%B9.png?raw=true) 32 | 33 | #### 增 34 | 35 | + 增加方式与Java中的StringBuffer类似 36 | 37 | ![](https://github.com/kentanvictor/STUDY/blob/Image/Python%E7%BC%96%E7%A8%8B%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%AE%9E%E8%B7%B5/%E5%88%97%E8%A1%A8%E6%B7%BB%E5%8A%A0.png?raw=true) 38 | 39 | #### 插 40 | 41 | + 插入元素方式与Java中的StringBuffer类似 42 | 43 | ![](https://github.com/kentanvictor/STUDY/blob/Image/Python%E7%BC%96%E7%A8%8B%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%AE%9E%E8%B7%B5/%E5%88%97%E8%A1%A8%E6%8F%92%E5%85%A5.png?raw=true) -------------------------------------------------------------------------------- /JAVA学习/Java数组查找方式以及二分查找剖析.md: -------------------------------------------------------------------------------- 1 | # 数组的搜索与查找查询 2 | + 二分查找(Binary Search): 3 | 4 | `注:` 5 | + 需要被查找的数据必须是有序的。 6 | + 按照中间的元素来进行比较: 7 | + 若中间的元素大于的话,就直接将中间数后面的元素全部排除掉 8 | + 然后中间元素前面的元素再取中间的值进行比较 9 | 10 | * …… 11 | 12 | * 不断的取中间的值进行比较 13 | 14 | 15 | + 代码如下: 16 | 17 | ```java 18 | 19 | public class ArraySearchText 20 | { 21 | public static int BinarySearch(int [] Array,int value)//这里直接认为传入方法中的数组就已经是排序好了的 22 | { 23 | int low = 0; 24 | int high = array.length - 1; 25 | int middle; 26 | 27 | while(low <= high) 28 | { 29 | middle = (low + high) / 2; 30 | 31 | for(int i = 0 ; i< array.length; i++) 32 | { 33 | System.out.print(array[i]); 34 | if (i == middle) { 35 | System.out.print("#"); 36 | } 37 | System.out.print(" "); 38 | } 39 | if (array[middle] == value ) { 40 | return middle; 41 | } 42 | if(value < array[middle] ){ 43 | high = middle - 1; 44 | } 45 | if(value > array[middle]){ 46 | low = middle + 1; 47 | } 48 | } 49 | return -1; 50 | } 51 | public static void main(String[] args) { 52 | int [] b = new int []{1,2,3,4,5,6,7,8,9}; 53 | int index2 = BinarySearch(b,10); 54 | 55 | System.out.print(index2); 56 | } 57 | } 58 | 59 | 60 | ``` 61 | -------------------------------------------------------------------------------- /JAVA学习/JavaWeb使用教程.md: -------------------------------------------------------------------------------- 1 | # JavaWeb初尝 2 | 3 | + 前言 4 | > 第一次使用JavaWeb去实现后端的数据库的建立,非常兴奋!(主要原因在于老师同意我一个人写数据库课程设计【斜眼笑】)。话不多说,一起来看看JavaWeb的使用吧! 5 | 6 | ## 环境配置 7 | 8 | ### 准备工作 9 | 10 | + 安装JDK 11 | + web服务器:Tomcat 12 | + IDE集成开发工具 13 | + 数据库:(个人使用的是MySQL) 14 | 15 | ### 开始配置 16 | 17 | #### JDK 18 | 19 | + 安装JDK 20 | > + 在ORACLE官网可以进行JavaJDK的下载,网址为:[JavaJDK下载](http://www.oracle.com/technetwork/java/javase/downloads/index.htmll) 21 | > + 下载后JDK的安装中会自带JRE的安装,一并安装即可。 22 | > + 安装过程中用户可以自定义安装目录等信息。 23 | + 配置环境变量(Mac用户无需配置环境变量) 24 | > + 安装完成后,右击"我的电脑",点击"属性" 25 | > + 选择"高级"选项卡,点击"环境变量" 26 | > + 在"系统变量"中设置3项属性JAVA_HOME | PATH | CLASSPATH(大小写无所谓),若已存在则点击"编辑",不存在则点击"新建"。 27 | > + `变量设置`: 28 | > + 变量名:JAVA_HOME 29 | > + 变量值:C:\Program Files\Java\jdk1.7.0(这里是你JDK的安装路径,可以更换) 30 | > + 变量名:CLASSPATH 31 | > + 变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; 32 | > + 变量名:Path 33 | > + 变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; 34 | 35 | #### Tomcat 36 | 37 | + 下载和安装Tomcat服务器 38 | > + 下载Tomcat安装程序包:[Tomcat安装包](http://tomcat.apache.org/) 39 | > + Tomcat官方站点:[Tomcat官方站点](http://jakarta.apache.org) 40 | > + 如图所示: 41 | 42 | > ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/TomcatDownload.png?raw=true) 43 | 44 | > + 点击【Download】跳转到如下图所示的下载页面 45 | 46 | > ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/TomcatDownloadNext.png?raw=true) 47 | 48 | > + tar.gz文件是Linux操作系统下的安装版本 49 | > + exe文件是Windows系统下的安装版本 50 | > + zip文件是Windows系统下的压缩版本 51 | > + 压缩包解压 52 | + 启动和测试Tomcat服务器 -------------------------------------------------------------------------------- /JAVA学习/运算符.md: -------------------------------------------------------------------------------- 1 | #### 1.当有若干个变量参与运算时,结果类型取决于这些变量中表示范围最大的那个变数类型。比如,参与运算的变量中,有整型 int,有双精度浮点型 double,有短整型 short,那么最后的结果类型就是 double。 2 | 3 | >注:在java的默认情况下,如果存在小数点的浮点类型一般是默认为double,如果要改为float一定要在后面加上f 4 | > 5 | >比如:1.0f 6 | 7 | ```Java 8 | int a = 1; int b = 2; 9 | double c = (double)a / b; 10 | ``` 11 | 12 | 上面的代码中,a 与b 都是整型,但是通过(double)a 这种转换将a 转换为一个匿名的变量,该变量的类型是double,但是要注意:a 本身依旧是int 类型,而不是double 类型,这样,(double)a / b 就是double 类型除以int 类型,结果自然是double 类型。 13 | 14 | #### 2.取模运算符:使用%表示。 15 | 16 | ```Java 17 | int a = 5; int b = 3; 18 | int c = a % b; 19 | ``` 20 | 21 | 上面代码的运行结果是 2,因为 5 除以 3 结果是 1 余 2。 22 | 取模的规律:取模的结果符号永远与被除数的符号相同 23 | 24 | ```Java 25 | int a = 5; int b = 3; 26 | int c = a % b; 27 | ``` 28 | 29 | 被除数是 5,那么取模的结果是 2 30 | 31 | ```Java 32 | int a = -5; int b = 3; 33 | int c = a % b; 34 | ``` 35 | 36 | 被除数是-5,那么取模的结果是-2。 37 | 38 | #### 3.关系运算符:大于(>)、小于(<)、等于(==)、不等于(!=)、大于等于(>=)、小于等于(<=),关系运算的结果是个boolean 值。 39 | 40 | #### 4.逻辑运算符:重点讲解两个,逻辑运算符本身也返回一个 boolean 值。 41 | 42 | + 1) 逻辑与:使用 `&&` 表示,逻辑与是个双目运算符(即有两个运算元的运算符),只有当两个运算元都为真的时候,结果才为真;其余情况结果均为假。逻辑与表示的是并且的意思。 43 | 44 | + 2) 逻辑或:使用 `||` 表示,逻辑或也是个双目运算符,只有当两个运算元都为假的时候,结果才为假;其余情况结果均为真。逻辑或表示或者的意思。 45 | 46 | #### 5.关于逻辑运算符的短路特性。 47 | 48 | + 1) 逻辑与:如果第一个运算元为 false,那么结果肯定就是 false,所以在这种情况下, 49 | 将不会执行逻辑与后面的运算了,即发生了短路。 50 | 51 | + 2) 逻辑或:如果第一个运算元为 true,那么结果肯定就是 true,所在在这种情况下,将不会执行逻辑或后面的运算了,即发生了短路。 52 | 53 | #### 6.关于变量的自增与自减运算。 54 | 55 | + 1) 关于 int b = a++,作用是将 a 的值先赋给 b,然后再让 a 自增 1. 56 | + 2) 关于 int b = ++a,作用是将 a 的值先自增 1,然后将自增后的结果赋给 b。 57 | -------------------------------------------------------------------------------- /MATLAB的使用/MATLAB概述.md: -------------------------------------------------------------------------------- 1 | # MATLAB概述 2 | * 主要包括MATLAB和Simulink两大部分。 3 | >* MATLAB基于矩阵(Matrix)的运算,全称为:MATreix LABoratory 4 | 5 | 6 | * MATLAB主要功能 7 | >* 技术计算-->数学计算、分析、可视化和算法开发 8 | >* 控制系统设计-->控制系统基于模型的设计,包括嵌入式系统仿真、快速原型及代码生成等 9 | >* 信号处理和通信-->信号处理和通信系统基于模型的设计,包括仿真、代码生成和验证等 10 | >* 图像处理-->图像采集、分析、可视化和算法开发 11 | >* 测试和测量-->测试和测量应用中硬件连接性和数据分析 12 | >* 计算你生物学-->生物数据和系统分析、可视化与仿真 13 | >* 计算金融-->金融建模、分析及应用程序开发 14 | 15 | 16 | * MATLAB分析和访问数据 17 | * 数据分析 18 | 19 | >MATLAB提供有一下一些用于数据分析运算的交互式工具和命令行函数 20 | * 内插和抽取 21 | * 抽取数据段、缩放和求平均值 22 | * 阈值和平滑处理 23 | * 相关性、傅里叶分析和筛选 24 | * 一维峰值、谷值以及零点查找 25 | * 基本统计数据和曲线拟合 26 | * 矩阵分析 27 | 28 | * 数据访问 29 | 30 | >可以从各种常用文件格式(如Microsoft Excel)、ASCII文本或者二进制文件、图像、语音和视频文件,以及诸如HDF和HDF5等科学文件中读取数据 31 | 32 | * MATLAB实现数据可视化 33 | * 二维绘图 34 | >使用二维绘图函数将数据向量可视化 35 | >* 线图、区域图、条形图以及饼图 36 | >* 方向图及速率图 37 | >* 直方图 38 | >* 多边形图和曲面图 39 | >* 散点图/气泡图 40 | >* 动画 41 | 42 | * 三维绘图和卷可视化 43 | >提供有将二维矩阵、三维向量和三维标量数据可视化的函数;还可以指定图形特性,例如:相机取景角度、透视图、灯光效果、光源位置以及透明度等等。**三维绘图函数包括:** 44 | >* 曲面图、轮廓图和网状图 45 | >* 成像图 46 | >* 锥形图、切割图、流程图以及等值面图 47 | 48 | * 交互式创建和编译图形 49 | >具有一些设计和修改图形的交互式工具。**可执行的操作有:** 50 | >* 将新的数据集拖放到图形上 51 | >* 更改图形上任意对象的属性 52 | >* 缩放、旋转、平移以及更改相机角度和灯光 53 | >* 添加批注和数据提示 54 | >* 绘制形状 55 | >* 生成可供各种数据重复使用的MATLAB自带函数 56 | 57 | * MATLAB进行数值计算 58 | >MATLAB提供以下类型函数用于数值计算与数值分析: 59 | >* 矩阵操作和线性代数 60 | >* 多项式和内插 61 | >* 傅里叶分析和筛选 62 | >* 数据分析和统计 63 | >* 优化和数值积分 64 | >* 常微分方程(ODE) 65 | >* 偏微分方程(PDE) 66 | >* 稀疏矩阵运算 67 | 68 | ### MATLAB的安装 69 | >感谢百度经验提供的教程 70 | 71 | >[MATLAB安装教程](http://jingyan.baidu.com/article/3d69c551a2dbd7f0cf02d731.html) 72 | -------------------------------------------------------------------------------- /设计模式/设计模式导论.md: -------------------------------------------------------------------------------- 1 | # 设计模式(Design Pattern) 2 | 很多人知道我们有设计模式这个概念,最经典的设计模式有23种。 3 | 设计模式并非一种技术,它只是解决问题的一种方式,任何语言都可以实现这种模式。 4 | 设计模式本身应该算是一种想法,一种解决问题的方式。 5 | 我们在解决问题的时候能够使用多种方式,设计模式给我们提供了更好的解决问题的方法 6 | 这是设计模式的一个初衷,也是设计模式的一个意义。 7 | 但是也并非说,处理事情必须要使用这种模式。 8 | 每个一个设计模式都有一个设计思想,设计理念在其中 9 | 10 | + 23种设计模式 11 | 12 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/23DesignModule.jpg?raw=true) 13 | 14 | ## 设计模式的六大原则 15 | ## 总原则:开闭原则(Open Close Principle) 16 | 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行扩展的时候,不能去修改初始化的代码,而是要扩展初始化代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类等,后面的具体设计中我们会提到这点。 17 | ### 1,单一职责原则 18 | 不要存在多于一个导致类变更的原因,从而每个类应该实现单一的作用,如若不然,就应该把类分解。 19 | ### 2,里氏替换原则(Liskov Substitution Principle) 20 | 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。只有当衍生类类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被替代,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对而“基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化”的实现。的具体步骤的规范。——来自百度百科 21 | 因为父类代表了定义好的结构,通过此规范的接口与外部相互作用,子类不应该随便破坏它。 22 | ### 3,依赖倒转原则(Dependency Inversion Principle) 23 | 这个是开闭原则的基础,具体内容:面向接口编程,依赖于抽象而不依赖于具体。写代码时用到特定类时,不与特定类相互作用,而与具体类的上层接口相互作用。 24 | ### 4,接口隔离原则(接口隔离原则) 25 | 这个原则的意思是:每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用交替接口(多个接口方法集合)到一个的接口)要好。 26 | ### 5,迪米特法则(至少知道原则)(Demeter Principle) 27 | 就是说:一个类对自己依赖的类知道的越少越好。那样无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。 28 | 最小知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有交换关系,就叫朋友关系。交换依赖,关联,聚合,组合等。参数,方法返回值中的类为直接朋友。局部变量,临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。 29 | ### 6,合成替代原则(复合复用原则) 30 | 原则是尝试首先使用合成/聚合的方式,而不是使用继承。 31 | 32 | `当然任何语言当然还指的是针对对象的语言,因为设计模式中主要涉及的还是类,对象等关系,并且设计模式大量的依托于多态。` 33 | -------------------------------------------------------------------------------- /LeetCode/TwoSum.md: -------------------------------------------------------------------------------- 1 | # 两数之和 2 | 3 | ## 题目 4 | 5 | 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 6 | 7 | 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 8 | 9 | 示例: 10 | 11 | 给定 nums = [2, 7, 11, 15], target = 9 12 | 13 | 因为 nums[0] + nums[1] = 2 + 7 = 9 14 | 15 | 所以返回 [0, 1] 16 | 17 | `Related Topics `:**数组** **哈希表** 18 | 19 | 所提供的函数: 20 | ```java 21 | class Solution { 22 | public int[] twoSum(int[] nums, int target) { 23 | 24 | } 25 | } 26 | ``` 27 | 28 | *** 29 | 我是一条正经的分割线 30 | *** 31 | 32 | ## 解题思路 33 | 34 | 通过Related Topics可以知道,在解决这道题时是需要用到哈希表的,那么我们要用到Java中hashmap的性质。 35 | 36 | + hashmap 37 | + HashMap采用key/value存储结构,每个key对应唯一的value,查询和修改的速度都很快,能达到O(1)的平均时间复杂度。它是非线程安全的,且不保证元素存储的顺序。 38 | + 在Java中,HashMap的实现采用了(数组 + 链表 + 红黑树)的复杂结构,数组的一个元素又称作桶。 39 | 40 | 通过上面对hashmap的解析可以看到,hashmap在搜索的过程中时间复杂度为O(1),因此可以通过hashmap中`containkey方法`进行比较。 41 | 42 | 使用target对当前遍历的数字进行减法操作,后比较hashmap中的结果。如果存在值,获取key对应的下标。 43 | 44 | ## 最终结果 45 | 46 | 47 | ```java 48 | class Solution { 49 | public int[] twoSum(int[] nums, int target) { 50 | if (nums == null || nums.length < 2){ 51 | return new int[]{-1,-1}; 52 | } 53 | 54 | int[] res = new int[]{-1,-1}; 55 | HashMap map = new HashMap<>(); 56 | for (int i = 0 ; i < nums.length; i++){ 57 | if (map.containsKey(target - nums[i])){ 58 | res[0] = map.get(target - nums[i]); 59 | res[1] = i; 60 | break; 61 | } 62 | map.put(nums[i],i); 63 | } 64 | 65 | return res; 66 | } 67 | } 68 | ``` -------------------------------------------------------------------------------- /JAVA学习/原生数据类型.md: -------------------------------------------------------------------------------- 1 | # 原生数据类型与表达式 2 | 3 | ## 原生数据类型 4 | 5 | + 1.Java 中的原生数据类型共有 8 种: 6 | 7 | + 1) 整型:使用 int 表示。(32 位) 8 | 9 | + 2) 字节型:使用 byte 表示。(表示-128~127 之间的 256 个整数, 8 位)。 10 | 11 | + 3)短整型:使用 short 表示。(16 位) 12 | + 4)长整型:使用 long 表示。(64 位) 13 | + 5)单精度浮点型:使用 float 表示。所谓浮点型,指的就是小数,也叫做实数,例如 1.2。 14 | + 6)双精度浮点型:使用 double 表示。双精度浮点型表示的数据范围要比单精度浮点型大。 15 | + 7)字符型:使用 char 表示(char 是 character 的缩写)。所谓字符,就是单个的字符表示,比如字母 a,或者中文张,外面用单引号包围上。比如 char a = ‘B’; char b = ‘张’; 16 | + 8)布尔类型,使用 boolean 表示。布尔类型只有两种可能值,分别是 true 与 false。 17 | 18 | + 2.Java 中的所有浮点类型默认情况下都是 double。不能将 double 类型的值赋给 float 类型的变量,即便该 double 类型的值处于 float 类型的范围内也是不可以的。总之,能否成功赋值取决于等号右边的值类型与等号左边的变量类型是否一致。 19 | 20 | + 3.如何将 double 类型的值赋给 float 类型的变量?答案就是(1)强制类型转换,将 double 类型的值强制转换为 float 类型。(2)使用 java 预言的支持。 21 | 22 | `强制转换的语法: 类型 变量名 = (类型)变量值;` 23 | 24 | + 4.变量在使用前必须要赋值;变量必须要声明其类型方可使用;变量在使用前必须要定义,并且只能定义一次。 25 | 26 | + 5.如下代码无法通过编译: 27 | 28 | ```Java 29 | int a = 1; short b = a; 30 | ``` 31 | 32 | a 是 int 类型,b 是 short 类型,int 类型表示的数据范围要比 short 类型大,不能将表示 33 | 范围大的值赋给表示范围小的变量。 34 | 35 | + 6.如下代码可以通过编译: 36 | 37 | ```Java 38 | short a = 1; int b = a; 39 | ``` 40 | 41 | a 是 short 类型,b 是 int 类型,int 类型表示的数据范围要比 short 类型大,可以将表示 42 | 范围小的值赋给表示范围大的变量。 43 | 44 | + 7.总结:可以将表示范围小的值赋给表示范围大的变量;但不能直接将表示范围大的值赋给表示范围小的变量,只能通过强制类型转换实现。 45 | 46 | ## 表达式 47 | 48 | > Java中使用的是`中缀表达式`——其实就是和数学上的函数表达式的道理是一样的。 49 | 50 | **注意:** 51 | 52 | + 在`初级运算`中运算产生的数据的数据类型和参与运算的数据的数据类型是相同的。 53 | 54 | + '+'、'-'、'*'、'/' 都是被重载过的。 55 | 56 | + `逻辑运算符`中,'!'优先级最高,之后是 '&&' ,最后是 '||' 。 57 | 58 | + 相同优先级运算顺序从左往右。 59 | 60 | + 在`类型转换`中,如果不损失信息,数值会自动提升为高等级的数据类型。前提是,你的运算中含有高等级的运算符。当需要向低类型转换时,会**截断取整**,而不是四舍五入。 61 | -------------------------------------------------------------------------------- /计算机视觉/Medical Imaging/”Transformers in Medical Imaging:A Survey“ Notes.md: -------------------------------------------------------------------------------- 1 | # "Transformers in Medical Imaging:A Survey" Notes 2 | 3 | ## Introduction 4 | 5 | + The workhorse in CNNS is the convolution poerator. 6 | 7 | `Drawback with CNNs: ` 8 | 9 | + the local receptive field in convolution operation limits capturing long-range pixel relationships. 10 | 11 | 注释:不能看整体,只能看到局部之间的关系。 12 | 13 | + the convolutional filters have stationary weights that are not adapted for the given input image content at inference time. 14 | 15 | 无法在中途插入输入图像内容。 16 | 17 | `Vision Transformers` 18 | 19 | 将Transformers模块取代CNN中的标准卷积。 20 | 21 | `文章结构顺序:` 22 | 23 | + Section 3 :Segmentation 24 | + Section 4 :Classification 25 | + Section 5 :Detection 26 | + Section 6 :Reconstruction 27 | + Section 7 :Synthesis 28 | + Section 8 :Registration 29 | + Section 9 :Clinical Report Generation 30 | + Section 10 :Other Tasks 31 | 32 | ## Background 33 | 34 | ### Hand-Crafted Approaches 35 | 36 | 成功的模型有: 37 | 38 | + total-variation 39 | 40 | + non-local self-similarity 41 | 42 | + sparsity/structured sparsity 43 | 44 | + Markov-tree models on wavelet coefficients 45 | 46 | + untrained neural networks 47 | 48 | 上面的模型不需要大量有label的数据集进行训练,但是辨别能力差。 49 | 50 | 为了规避可辨别性和通用性差的问题,人们提出了学习手工制作的模型来更好地利用数据,如: 51 | 52 | + optimal directions 53 | 54 | + K-SVD 55 | 56 | + data-driven tight frame 57 | 58 | + low-rank models 59 | 60 | + piece-wise smooth image model 61 | 62 | ### CNN-based methods 63 | 64 | 大多数模型是将CNN和Hand-Crafted Approaches进行结合,使得先验信息引导CNN模型,有以下这些方法: 65 | 66 | + unrolled optimization 67 | 68 | + generative models 69 | 70 | + learned denoiser-based approaches 71 | 72 | ### Transformers -------------------------------------------------------------------------------- /数据结构/流程控制语句.md: -------------------------------------------------------------------------------- 1 | 2 | #### 1.条件运算符(三元表达式),其形式为: type d = a ? b : c; 具体化形式为:int d = 2 < 1 ? 3 : 4; 3 | 4 | #### 2.轻量级的文本编辑器:UltraEdit、Editplus、vi、vim、gvim 5 | 6 | #### 3.流程控制语句 if 的用法为:第一种形式: 7 | ```java 8 | if(布尔表达式) 9 | 10 | { 11 | 12 | //待执行的代码 13 | 14 | } 15 | ``` 16 | 第二种形式: 17 | ```java 18 | if(布尔表达式) 19 | 20 | { 21 | 22 | //待执行的代码 23 | 24 | } 25 | 26 | else 27 | 28 | { 29 | 30 | //待执行的代码 31 | 32 | } 33 | ``` 34 | 第三种形式: 35 | ```java 36 | if(布尔表达式) 37 | 38 | { 39 | 40 | //待执行的代码 41 | 42 | } 43 | 44 | else if(布尔表达式) 45 | 46 | { 47 | 48 | //待执行的代码 49 | 50 | } 51 | 52 | else if(布尔表达式) 53 | 54 | { 55 | 56 | //待执行的代码 57 | 58 | } 59 | 60 | else 61 | 62 | { 63 | 64 | //待执行的代码 65 | 66 | } 67 | ``` 68 | 69 | #### 4.switch 语句,使用形式为: 70 | ```java 71 | switch(变量) //此处的变量类型就目前所学内容来看,只能为 4 种类型:byte, short, int, char。 72 | 73 | { 74 | 75 | case 常量 1: //待执行的代码 break; 76 | 77 | case 常量 2: //待执行的代码 break; 78 | 79 | case 常量 3: //待执行的代码 break; 80 | 81 | default://待执行的代码 82 | 83 | } 84 | ``` 85 | 虽然 case 语句中的 break 是可选的,但在绝大多数情况下,如果没有 break,程序的逻辑就会发生错误,因此,通常情况下都需要加上 break。 86 | 87 | #### 5.Java 中的循环控制语句一共有 3 种,分别是 while,do… while 以及 for 循环。 88 | 89 | #### 6.while 循环,形式为: 90 | ```Java 91 | while(布尔表达式) 92 | { 93 | 94 | //待执行的代码 95 | 96 | } 97 | ``` 98 | #### 7.do…while 循环,形式为: 99 | ```Java 100 | do 101 | { 102 | 103 | //待执行的代码 104 | 105 | } 106 | 107 | while(布尔表达式); 108 | ``` 109 | #### 8.while 与 do…while 之间的区别:如果布尔表达式的第一次判断就为 false,那么 while 循环一次也不执行;do…while 循环则会执行一次。如果布尔表达式第一次判断为 true,那么 while 循环与 do…while 循环等价。 110 | #### 111 | 9.for 循环(使用最多的一种循环),形式为: 112 | ```Java 113 | for(变数初始化; 条件判断; 步进) 114 | { 115 | 116 | //待执行的代码 117 | 118 | } 119 | ``` 120 | for 循环的执行过程: 121 | 122 | 1) 执行变量初始化。 123 | 2) 执行条件判断。如果条件判断结果为假,那么退出 for 循环,开始执行循环后面的 124 | 代码;如果条件判断为真,执行 for 循环里面的代码。 125 | 3) 执行步进。 126 | 4) 重复步骤 2。 127 | -------------------------------------------------------------------------------- /Android/Android框架揭秘/Zygote.md: -------------------------------------------------------------------------------- 1 | # Zygote 2 | 3 | ![flow chart](https://github.com/kentanvictor/STUDY/blob/Image/Android%E6%A1%86%E6%9E%B6%E6%8F%AD%E7%A7%98/initToAppProgress.png?raw=true) 4 | 5 | `问题:` 6 | 7 | + zygote是如何启动的 8 | + zygote主要是负责哪些事情的 9 | + zygote和AndroidRuntime有什么关系 10 | + AndroidRuntime和虚拟机实例对象又是什么关系 11 | + zygote进程是如何从native层进入Java层的(JNI接口) 12 | + 通过zygote fork出来的进程,跟exec开启的进程有什么区别 13 | + zygote和(ZygoteServer) zygoteSocket,UASPSocket有什么关联?或者说使用socket做了什么事情 14 | + zygoteInit(ZygoteInit.java--JNI-->zygoteInit.cpp)中做了什么事情 15 | + zygote进程是如何完成fork子进程的 16 | + zygote是如何启动systemServer(AMS,PMS,WMS……)的 17 | + zygote fork子进程的copy-on-write在源码中的体现 18 | 19 | 先后顺序: 20 | 21 | ~~nit进程 –-> Zygote进程 –> Dalvik VM进程 –> SystemServer进程 –>应用进程~~ 22 | 23 | 在init.rc文件被init.cpp中SecondStageMain函数中进行解析的时候,位于core\/rootdir文件夹下的init.rc文件中有一行:`import /init.${ro.zygote}.rc` 24 | 25 | 从rc文件中可以看到第一行会执行一个app_process的可执行文件,在P中,这个可执行文件所链接到的cpp位置为:`frameworks/base/cmds/app_process/app_process.cpp` 26 | 27 | 在app_process中的main函数中的while中有对应的制定参数针对rc文件的第一行执行命令所传入的参数 28 | 29 | 在Linux中,只有0号进程,又被称为`idle`,不是通过fork()方式进行创建的,其他的进程,包括init进程的创建方式都是通过fork()进行的 30 | 31 | Zygote进程首先fork出“System server”进程,“System server”进程会有PowerManager Service、Sensor Service、Location Service等服务的开启 32 | 33 | `COW:`因为复制内存的开销比较大,因此创建的子进程在引用父进程的内存空间时,不要进行复制,而要直接共享父进程的内存空间。 34 | 35 | ## AppRuntime对象 36 | 37 | AppRuntime类用于初始化并运行Dalvik虚拟机,再在Dalvik上装在ZygoteInit Class。 38 | 39 | ### app_process 40 | 41 | app_process参数形式如下: 42 | 43 | `app_process [java-options] cmd-dir start-class-name[options]` 44 | 45 | + [java-options] : 传给虚拟机的选项,必须以“-” 开始 46 | 47 | + cmd-dir : 所要运行的进程所在的目录 48 | 49 | + start-class-name : 要在虚拟机中运行的类的名称 50 | 51 | + [options] : 要传递给类的选项 52 | 53 | 在zygote的rc文件中,每一行都有一个命令 54 | 55 | `service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote` 56 | 57 | 58 | 由于Zygote是由Java编写的,所以如何要运行Zygote必须得先把Dalvik虚拟机跑起来,而在init.rc中执行这一任务的进程是:`app_process` -------------------------------------------------------------------------------- /Android/Android底层开发技术实战详解/11.音频系统驱动.md: -------------------------------------------------------------------------------- 1 | # 音频系统驱动 2 | 3 | ## Audio系统结构 4 | 5 | 重点了解内容: 6 | + AudioFlinger 7 | + AudioPolicy 8 | + AudioTrack 9 | 10 | 以上三个最好使用Demo形式明确其数据流流动形式。 11 | 12 | 13 | Android音频系统的`核心`是Audio系统 14 | 15 | ![Audio系统框架结构](https://github.com/kentanvictor/STUDY/blob/Image/Android%E5%BA%95%E5%B1%82%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF%E5%AE%9E%E6%88%98%E8%AF%A6%E8%A7%A3/Audio%E7%B3%BB%E7%BB%9F%E6%A1%86%E6%9E%B6%E7%BB%93%E6%9E%84.png?raw=true) 16 | 17 | + Audio Java Part 18 | 19 | 与Audio相关的包是android.media 20 | 21 | + Audio JNI Part 22 | 23 | 生成libandroid_runtime.so 24 | 25 | + Audio 框架 26 | 27 | Media库中的一部分,直接被编译成libmedia.so文件,提供了Audio部分接口。**包括基于Binder的IPC机制** 28 | 29 | + Audio Flinger 30 | 31 | 被编译成 libaudioflinger.so,Audio的本地服务部分 32 | 33 | + Audio硬件抽象层接口 34 | 35 | 作为Audio系统本地框架层和驱动程序接口 36 | 37 | ## Audio系统层次 38 | 39 | + Audio本地框架类 40 | 41 | libmedia.so文件其中一part,为上层提供接口,由下层去实现 42 | 43 | + AudioFlinger 44 | 45 | 继承libmedia接口,提供实现库libaudioflinger.so 46 | 47 | + JNI 48 | 49 | 使用JNI和Java对上层提供接口,JNI通过libmedia库中接口进行实现 50 | 51 | + Audio硬件抽象层 52 | 53 | 提供硬件接口,供AudioFlinger进行调用。 54 | 55 | `注:`Audio系统不涉及编解码环节,只负责软硬件间交互的作用,所以通常以PCM进行数据传输。 56 | 57 | ### Audio框架 58 | 59 | + AudioSystem.h 60 | 61 | 定义了枚举值和set/get一系列接口,最终实现是由下层提供支持。 62 | 63 | + AudioTrack类 64 | 65 | AudioTrack是Audio输出环节的类,最重要接口:`write()` 66 | 67 | + AudioRecord类 68 | 69 | AudioRecord类是Audio输入相关的类,最重要的接口:`read()` 70 | 71 | `注:` 72 | + 在AudioTrack和AudioRecord类中,函数`read()`和`write()`的参数都是内存的指针和大小,指针指向的地址所存储的内容一般为`PCM数据`。 73 | 74 | + 类AudioSystem、AudioTrack和AudioRecord分别调用IAudioFlinger、IAudioTrack和IAudioRecord来实现。 75 | 76 | **AudioFlinger是Audio音频系统的中间层** 77 | 78 | ### AudioFlinger和AudioPolicyService 79 | 80 | #### AudioFlinger 81 | 82 | 策略的执行者 83 | 84 | #### AudioPolicyService 85 | 86 | 策略的制定者 87 | 88 | + 路由功能 89 | 90 | 有权利决定某一个AudioTrack所产生的音频流最终回走向哪个设备 91 | 92 | 在P的代码中,AudioFlinger和AudioPolicyService是在frameworks\/av\/media\/audioserver\/中的`main_audioserver.cpp`中被启动的。 -------------------------------------------------------------------------------- /JAVA学习/JAVA学习之单例模式.md: -------------------------------------------------------------------------------- 1 | # 单例模式(Singleton)详解 2 | 3 | + 1、接口中声明的方法都是抽象方法。并且接口中的方法都是public. 4 | + 2、接口中也可以定义成员变量,但是需要赋值接口中的成员变量都是static public and final的。就因为是final所以需要赋值 5 | + 3、一个类不能既是final,又是abstract的,因为abstract的主要目的是定义一种约定,让子类去实现这种约定,而final表示该类不能被继承,这样abstract希望该类可以被继承而final又明确说明该类不能被继承,两者矛盾。因此,一个类不能既是final又是abstract的。 6 | 7 | 单例模式表示一个类只会生成唯一的一个对象。 (如果生成一个类,那么构造方法一定会被调用,不管类有几个构造方法,肯定有一个会被调用)--> 所以单例模式是从构造方法的方向入手,去建立唯一的一个类。 8 | 9 | ## 第一种的单例模式生成唯一实例的方式 10 | 11 | ```java 12 | public class SingletonTest 13 | { 14 | public static void main(String[] args) 15 | { 16 | Singleton singleton = Singleton.getInstance(); 17 | Singleton singleton2 = Singleton.getInstance(); 18 | System.out.println(singleton == singleton2);//用来判断是否只生成了一个实例,如果返回true,那么证明生成的两个对象所指向的是同一个实例。 19 | } 20 | } 21 | //为保证能够让Main不能够通过Singleton singleton = new Singleton();的方式来生成对象,那么久需要在构造方法前面加上private,而构造出一个静态方法,在类中去生成唯一的一个实例。 22 | class Singleton 23 | { 24 | private static Singleton singleton = new Singleton();//只有静态方法才能够调用静态方法 25 | private Singleton() 26 | { 27 | 28 | } 29 | public static Singleton getInstance() 30 | { 31 | return singleton; 32 | } 33 | } 34 | ``` 35 | 36 | ## 第二种的单例模式生成唯一实例的方式 37 | 38 | ```java 39 | public class SingletonTest 40 | { 41 | public static void main(String[] args) 42 | { 43 | Singleton singleton = Singleton.getInstance(); 44 | Singleton singleton2 = Singleton.getInstance(); 45 | System.out.println(singleton == singleton2);//用来判断是否只生成了一个实例,如果返回true,那么证明生成的两个对象所指向的是同一个实例。 46 | } 47 | } 48 | 49 | class Singleton 50 | { 51 | private static Singleton singleton;//只有静态方法才能够调用静态方法,并且这是一个引用类型的变量,默认初始为null 52 | private Singleton() 53 | { 54 | 55 | } 56 | public static Singleton getInstance() 57 | { 58 | if(singleton == null) 59 | { 60 | singleton = new Singleton(); 61 | } 62 | return singleton; 63 | } 64 | } 65 | ``` 66 | 67 | `注:` 68 | 如果在多线程的环境下,更加推荐使用第一种的方式来写单例模式。而第二种方式在多线程的情况下有可能就不是单例了。 69 | -------------------------------------------------------------------------------- /后端/Windows虚拟环境在PyCharm中的使用.md: -------------------------------------------------------------------------------- 1 | # Anaconda 2 | 3 | > 网上对于Anaconda的安装是教程有很多,这里会为各位提供的是一个我当时安装时候所参考的链接地址。[Anaconda的介绍、安装及使用教程](https://zhuanlan.zhihu.com/p/32925500) 4 | 5 | ## Anaconda中创建虚拟环境(命令行模式) 6 | 7 | > 在Anaconda中创建虚拟环境的方式: 8 | > 9 | > 下面是创建python=3.6版本的环境,取名叫py36 10 | > 11 | > conda create -n py36 python=3.6 12 | > 13 | >删除环境 14 | > 15 | >conda remove -n py36 --all 16 | > 17 | >激活环境 18 | > 19 | >source activate py36 20 | > 21 | >退出环境 22 | > 23 | >source deactivate 24 | 25 | + 在创建虚拟环境的过程中,我遇到了一个问题,这个问题就是:`如果创建了多个python版本的环境,那么我应该如何去管理当中所安装的不同的包呢?并且与本机原本安装的python环境不起到冲突?` 26 | 27 | + 我解决Anaconda与本机办法是这样的: 28 | >+ 解决办法一: 29 | > 30 | >其实python 在安装的时候就为我们提供了两个版本的解决方案 31 | > 32 | >在C盘的windows 目录下有个 py.exe 33 | > 34 | >我们用py.exe 这个工具启动就能分辨出python的版本 35 | > 36 | >启动python2.7的pip 37 | > 38 | >直接在cmd 窗口里输入:py -2 -m pip install XXXX 39 | > 40 | >启动python3.6的pip 41 | > 42 | >直接在cmd 窗口里输入:py -3 -m pip install XXXX 43 | > 44 | >+ 解决办法二: 45 | > 46 | >找到自己本机安装的Python路径(在Path中可以直接找到),然后找到自己的Python.exe文件,然后重命名即可。 47 | > 48 | >如:我对我本机的Python重命名为Python3,然后对Anaconda中安装的Python不重命名。 49 | > 50 | >之后需要对Anaconda中的python进行pip安装的时候,就输入: 51 | > 52 | >python -m pip install XXX 53 | > 54 | >然后对本机的python进行安装的时候,就输入: 55 | > 56 | >python3 -m pip install XXX 57 | 58 | + 我解决Anaconda进入虚拟环境之后与Anaconda自身的Python冲突的问题: 59 | > 60 | >根据上面启动虚拟环境的方法,我们能够启动已经创建的虚拟环境 61 | > 62 | >进入虚拟环境之后,输入: 63 | > 64 | >python -V 65 | > 66 | >就能够看到当前的虚拟环境中的python的版本号 67 | > 68 | >这个时候,输入: 69 | > 70 | >pip list 71 | > 72 | >你所看到的就是你当前环境下的pip所安装的包。 73 | > 74 | >`如果你发现你的list还是Anaconda自带的list的话,就输入:` 75 | > 76 | >`python -m pip list` 77 | 78 | ## Anaconda中创建虚拟环境(GUI模式) 79 | 80 | `当你安装好Anaconda之后,会出现一个Anaconda Mavigator,点击之后在里面也可以创建虚拟环境。` 81 | 82 | ![AnacondaMavigator](https://images2018.cnblogs.com/blog/1410558/201807/1410558-20180715214011743-297214195.png) 83 | 84 | # PyCharm 85 | 86 | + 在PyCharm中的`Settings`中的`Project Interpreter`进行python版本的选择。 87 | 88 | + 找到你的`Anaconda`的`安装路径`。 89 | 90 | + 然后在里面找到一个文件夹叫`envs`。 91 | 92 | + 在这个文件夹里面有你创建的所有的虚拟环境。 93 | 94 | + 选择你需要用到的虚拟环境,然后找到`python.exe`即可。 95 | -------------------------------------------------------------------------------- /QtDesigner.md: -------------------------------------------------------------------------------- 1 | # Qt Designer 2 | ## QT的安装 3 | + 对于QT的安装,个人的推荐是参考[QT5.7+VS2015安装教程](http://blog.csdn.net/liang19890820/article/details/53931813)。这个教程写的很详细,而且也非常的nice。 4 | ## QT在VS2015中的使用 5 | + 现在我们正式在VS2015中去使用QT,使用前,先需要创建一个QT的项目。 6 | + 使用VS2015中文件——>新建——>项目。点击之后,会出现如下界面: 7 | ![](./image/QTCreate.png) 8 | + 模板选择VisualC++下的Qt,选择QT GUI Application,上方的.NET Framework直接选择默认即可。 9 | + 选择之后点击下一步,会出现如下界面: 10 | ![](./image/QT1.png) 11 | + 点击next之后会出现如下界面: 12 | ![](./image/QT2.png) 13 | **这里根据需要可以自己选择,如果是新手可以先直接下一步。** 14 | + 点击next之后会出现如下界面: 15 | ![](./image/QT3.png) 16 | **这里默认直接finish就可以,如果有什么需要的可以自行设置。** 17 | + 当创建好之后就会出现如下画面: 18 | ![](./image/QTFinish.png) 19 | + 上面的画面就是我们需要进行操作的界面了。此时,`双击`QTTest.ui【位于:解决方案资源管理器->Form Files】 20 | + 双击进去之后就是我们需要进行ui设计的界面了(如下图所示): 21 | ![](./image/QTDesigner.png) 22 | + 在这里,你可以进行控件的拖动,直接拖到方框中去,然后再对象查看器(如下图所示)可以看到你控件所对应的类以及生成的对象。 23 | 24 | ![](./image/QTTest1.png) 25 | 26 | ![](./image/QTTest2.png) 27 | + 创建好对象之后,点击左上角的文件->保存(Ctrl+S) 28 | + 然后关闭QT Designer,回到VS2015中,`右键QTTest.ui,选择编译(Ctrl+F7)`,如下图所示: 29 | ![](./image/QTTest3.png) 30 | + 编译成功之后(一般情况下都是会编译成功的),`双击打开QTTest.cpp`,里面的代码是这样的: 31 | 32 | ``` 33 | #include "QTTest.h" 34 | 35 | QTTest::QTTest(QWidget *parent) 36 | : QMainWindow(parent) 37 | { 38 | ui.setupUi(this); 39 | } 40 | ``` 41 | 42 | + 这个时候,在`ui.setupUi下输入ui.pushButton`即可获取到刚刚创建的button的实例。代码如下所示: 43 | 44 | ``` 45 | #include "QTTest.h" 46 | 47 | QTTest::QTTest(QWidget *parent) 48 | : QMainWindow(parent) 49 | { 50 | ui.setupUi(this); 51 | ui.pushButton; 52 | } 53 | ``` 54 | 55 | + **在QT中,控件与控件之间的数据传输是通过`信号与槽`的方式进行的,下面就演示其中一种的数据传输的方式:(代码如下:)** 56 | 57 | ``` 58 | #include "QTTest.h" 59 | 60 | QTTest::QTTest(QWidget *parent) 61 | : QMainWindow(parent) 62 | { 63 | ui.setupUi(this); 64 | connect(ui.pushButton, &QPushButton::clicked, [this] { 65 | ui.label->setText(ui.label->text().replace(QRegExp("\\d+"), "25")); 66 | }); 67 | } 68 | ``` 69 | 70 | + 实现之后的效果为: 71 | + 未点击button之前: 72 | ![](./image/ClickBefore.png) 73 | 74 | + 点击button之后: 75 | ![](./image/ClickAfter.png) 76 | 77 | 78 | [下一节,控件的使用](./QT控件的使用.md) 79 | -------------------------------------------------------------------------------- /LeetCode/Add Two Numbers.md: -------------------------------------------------------------------------------- 1 | # 两数相加 2 | 3 | ## 题目 4 | 5 | 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 6 | 7 | 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 8 | 9 | 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 10 | 11 | 示例: 12 | 13 | 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 14 | 15 | 输出:7 -> 0 -> 8 16 | 17 | 原因:342 + 465 = 807 18 | 19 | `Related Topics `:**链表** **数学** 20 | 21 | 链表的结构: 22 | 23 | ```java 24 | /** 25 | * Definition for singly-linked list. 26 | * public class ListNode { 27 | * int val; 28 | * ListNode next; 29 | * ListNode() {} 30 | * ListNode(int val) { this.val = val; } 31 | * ListNode(int val, ListNode next) { this.val = val; this.next = next; } 32 | * } 33 | */ 34 | ``` 35 | 36 | 所提供的函数: 37 | 38 | ```java 39 | class Solution { 40 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 41 | 42 | } 43 | } 44 | ``` 45 | *** 46 | 我是一条正经的分割线 47 | *** 48 | 49 | ## 解题思路 50 | 51 | + 这里面最核心的内容是:**除法、取模**这两者的正确使用。因为需要返回一个ListNode,那肯定是需要创建一个新的ListNode的对象作为总和的存储。 52 | 53 | + 为了不改变形参传入的链表的内容以及排列方式,可以创建两个新的链表对象进行数据的存储。 54 | 55 | + 其实就是从链表最开头进行相加,如果有进位那就对后一个链表进行相加。因此,在这其中,除法操作以及取余操作十分重要。 56 | 57 | + 当链表1与链表2第一个元素进行相加,存储在sum变量中。将sum对10进行取模操作,如果没有进位操作,那么`sum%10`的结果就为0,反之为1。同样的进行`sum/10`的操作,获取个位数的数值,存储在链表中。 58 | 59 | + 当进行到最后一位的加法操作时,如果还有进位就进行单独的判断。当sum等于1时,在返回的链表最后追加一个1就可以了。 60 | 61 | 62 | 63 | 64 | ## 最终结果 65 | 66 | ```java 67 | 68 | class Solution { 69 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 70 | ListNode dummy = new ListNode(0); //作为output 71 | int sum = 0; 72 | ListNode cur = dummy; 73 | ListNode p1 = l1, p2 = l2; 74 | while (p1 != null || p2 != null){ 75 | if (p1 != null){ 76 | sum += p1.val; 77 | p1 = p1.next; 78 | } 79 | if (p2 != null){ 80 | sum += p2.val; 81 | p2 = p2.next; 82 | } 83 | cur.next = new ListNode( sum % 10); 84 | sum /= 10; 85 | cur = cur.next; 86 | } 87 | if (sum == 1){ 88 | cur.next = new ListNode(1); 89 | } 90 | return dummy.next; 91 | } 92 | } 93 | 94 | ``` -------------------------------------------------------------------------------- /数据结构/线性表/Arraylist/Queue.java: -------------------------------------------------------------------------------- 1 | package com.dell.example.linearlist; 2 | 3 | /* 4 | * Created by JohnnyTan on 2017/10/15. 5 | */ 6 | public class Queue { 7 | } 8 | 9 | class DATA 10 | { 11 | String name; 12 | int age; 13 | } 14 | 15 | class SQType 16 | { 17 | static final int QUEUELENN = 15; 18 | DATA[] data = new DATA[QUEUELENN]; 19 | int head; 20 | int tail; 21 | 22 | SQType Init() //初始化 23 | { 24 | SQType q; 25 | if((q = new SQType()) != null) 26 | { 27 | q.head = 0; 28 | q.tail = 0; 29 | return q; 30 | } 31 | else 32 | { 33 | return null; 34 | } 35 | } 36 | 37 | int SQTypeIsEmpty(SQType q) //判断空队列 38 | { 39 | int temp = 0; 40 | if(q.head == q.tail) 41 | { 42 | temp = 1; 43 | } 44 | return temp; 45 | } 46 | 47 | int SQTypeIsFull(SQType q) //判断满队列 48 | { 49 | int temp = 0; 50 | if(q.tail == QUEUELENN) 51 | { 52 | temp = 1; 53 | } 54 | return temp; 55 | } 56 | 57 | void SQTypeClear(SQType q) //清空队列 58 | { 59 | q.head = 0; 60 | q.tail = 0; 61 | } 62 | 63 | void SQTypeFree(SQType q) //入队列 64 | { 65 | if(q != null) 66 | { 67 | q = null; 68 | } 69 | } 70 | 71 | int InSQType(SQType q,DATA data) 72 | { 73 | if(q.tail == QUEUELENN) 74 | { 75 | System.out.println("队列已满!操作失败!\n"); 76 | return 0; 77 | } 78 | else 79 | { 80 | q.data[q.tail++] = data; //将元素入队列 81 | return 1; 82 | } 83 | } 84 | 85 | DATA OutSQType(SQType q) //出队列 86 | { 87 | if(q.head == q.tail) 88 | { 89 | System.out.println("\n队列已空!操作失败!\n"); 90 | 91 | System.exit(0); 92 | } 93 | else 94 | { 95 | return q.data[q.head++]; 96 | } 97 | return null; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /JAVA学习/反射/ReflactDemo.java: -------------------------------------------------------------------------------- 1 | package com.dell.example.reflactDemo; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.Method; 6 | 7 | /* 8 | * Created by JohnnyTan on 2017/10/31. 9 | */ 10 | public class ReflactDemo { 11 | public static void main(String[] args) { 12 | Person p = new Person(); 13 | Test(p); 14 | Test(); 15 | } 16 | 17 | private static void Test(Object obj) { 18 | //获得一个类的类对象 19 | Class clazz = obj.getClass(); 20 | //获得类传递过来的所有的方法 21 | Method[] methods = clazz.getDeclaredMethods(); 22 | for (Method m : methods) { 23 | System.out.println(m); 24 | } 25 | System.out.println("---------------------------------------"); 26 | //获得所有的属性 27 | Field[] fields = clazz.getDeclaredFields(); 28 | for (Field f : fields) { 29 | System.out.println(f); 30 | } 31 | System.out.println("---------------------------------------"); 32 | //获得所有的构造器 33 | Constructor[] cs = clazz.getDeclaredConstructors(); 34 | 35 | for (Constructor c : cs) { 36 | System.out.println(c); 37 | } 38 | System.out.println("---------------------------------------"); 39 | } 40 | 41 | private static void Test() { 42 | //获得一个类的类对象 43 | Class clazz = Person.class; 44 | //获得类传递过来的所有的方法 45 | Method[] methods = clazz.getDeclaredMethods(); 46 | for (Method m : methods) { 47 | System.out.println(m); 48 | } 49 | System.out.println("---------------------------------------"); 50 | //获得所有的属性 51 | Field[] fields = clazz.getDeclaredFields(); 52 | for (Field f : fields) { 53 | System.out.println(f); 54 | } 55 | System.out.println("---------------------------------------"); 56 | //获得所有的构造器 57 | Constructor[] cs = clazz.getDeclaredConstructors(); 58 | 59 | for (Constructor c : cs) { 60 | System.out.println(c); 61 | } 62 | System.out.println("---------------------------------------"); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /JAVA学习/垃圾回收器.md: -------------------------------------------------------------------------------- 1 | # 垃圾回收 2 | 3 | + 下面是一个垃圾回收所经历的过程 4 | + 在下面的程序中,先创建了许多Chair对象,而且在垃圾收集器开始运行后的某些时候,程序会停止创建Chair。 5 | + 因为不知道什么时候运行,因此,程序用一个名为gcrun的标记来指出垃圾收集器是否已经开始运行 6 | 7 | + 另外两个static变量— —created以及finalized— —分别用于跟踪已创建的对象数量以及垃圾收集器已进行完收尾工作的对象数量。 8 | 9 | ``` java 10 | 11 | //Demonstration of the garbage 12 | //collector and finalization(垃圾收集所经历的过程) 13 | 14 | class Chair 15 | { 16 | static boolean gcrun = false; 17 | static boolean f = false; 18 | static int created = 0; 19 | static int finalized = 0; 20 | int i; 21 | Chair() 22 | { 23 | i = ++created; 24 | if(created==47) 25 | System.out.println("Created 47"); 26 | } 27 | protected void finalize() 28 | { 29 | if(!gcrun) 30 | { 31 | gcrun = true; 32 | System.out.println("Beginning to finalize after" + created + "Chairs have been created"); 33 | } 34 | if(i == 47) 35 | { 36 | System.out.println("Finalizing Chair #47," + "Setting flag to stop Chair creation"); 37 | f = true; 38 | } 39 | finalized++; 40 | if (finalized>created) 41 | { 42 | System.out.println("All" + finalized + "finalized"); 43 | } 44 | } 45 | } 46 | public class Garbage { 47 | public static void main(String[] args) 48 | { 49 | if (args.length == 0) 50 | { 51 | System.out.println("Usage: \n"+"java Garbage before\n of: \n"+"java Garbage after"); 52 | return; 53 | } 54 | while (! Chair.f) 55 | { 56 | new Chair(); 57 | new String("To take up space"); 58 | } 59 | System.out.println("After all Chairs have been created : \n"+ "total created =" + Chair.created + ", total finalized ="+ Chair.finalized); 60 | if(args[0].equals("before")) 61 | { 62 | System.out.println("gc():"); 63 | System.gc(); 64 | System.out.println("runFinalization():"); 65 | System.runFinalization(); 66 | } 67 | System.out.println("bye!"); 68 | if(args[0].equals("after")) 69 | System.runFinalizersOnExit(true); 70 | } 71 | } 72 | 73 | ``` 74 | -------------------------------------------------------------------------------- /JAVA学习/冒泡排序的java实现.md: -------------------------------------------------------------------------------- 1 | ## 冒泡排序的JAVA实现 2 | * 冒泡排序 3 | ```java 4 | public class BUbbleSortTest 5 | { 6 | /* 7 | 一共两层循环 8 | 最外层循环是进行走到哪里了,进行一个循环。从数组两头一直走到中间的元素 9 | 最里面的for循环是用來判断相邻的两个数的大小,进行互换 10 | */ 11 | public static void BUbbleSort(int [] array) 12 | { 13 | for (int i=0;iarray[j+1]) 18 | { 19 | int temp = array[j]; 20 | array[j]= array[j+1]; 21 | array[j+1]=temp; 22 | } 23 | } 24 | System.out.println("第"+(i+1)+"趟排序"); 25 | for (int k = 0;i **整体的实现逻辑是基于冒泡排序,直接可以将关键字较大的记录从前面直接移动到后面,关键字较小的记录从后面直接移动到前面,从而减少了总的比较次数与移动次数.** 42 | > 43 | >![](../image/quick.png) 44 | * 代碼如下: 45 | ```java 46 | public class QuickSort { 47 | public static void sort(int a[], int low, int hight) { 48 | int i, j, index; 49 | if (low > hight) { 50 | return; 51 | } 52 | i = low; 53 | j = hight; 54 | index = a[i]; // 用子表的第一个记录做基准 55 | while (i < j) { // 从表的两端交替向中间扫描 56 | while (i < j && a[j] >= index) 57 | j--; 58 | if (i < j) 59 | a[i++] = a[j];// 用比基准小的记录替换低位记录 60 | while (i < j && a[i] < index) 61 | i++; 62 | if (i < j) // 用比基准大的记录替换高位记录 63 | a[j--] = a[i]; 64 | } 65 | a[i] = index;// 将基准数值替换回 a[i] 66 | sort(a, low, i - 1); // 对低子表进行递归排序 67 | sort(a, i + 1, hight); // 对高子表进行递归排序 68 | 69 | } 70 | 71 | public static void quickSort(int a[]) { 72 | sort(a, 0, a.length - 1); 73 | } 74 | 75 | public static void main(String[] args) { 76 | 77 | int a[] = { 49, 38, 65, 97, 76, 13, 27, 34 }; 78 | quickSort(a); 79 | System.out.println(Arrays.toString(a)); 80 | } 81 | } 82 | ``` 83 | -------------------------------------------------------------------------------- /Android/FOTA开发与热修复.md: -------------------------------------------------------------------------------- 1 | # OTA开发与热修复 2 | 3 | > 注:`FOTA(Firmware Over the Air)`专门指的是使用`OTA(Over the Air)`技术进行的远程无线固件升级。因此,以下所涉及的`OTA`技术开发流程专门可以用于`FOTA`开发。 4 | 5 | ## OTA开发流程 6 | 7 | 所谓`OTA(Over-the-Air Technology)`是指手机终端通过无线网下载远程服务器上的升级包,对系统或应用进行升级的技术。进一步说,就是将升级包(update.zip压缩包)写入到(手机)系统存储区。 8 | 9 | + 整包:包含整个system分区中的数据文件;`相当于`**重装系统** 10 | 11 | + 差分包:仅包含新旧两个版本之间的改动部分。只对其中部分存储段的内容进行重写。 12 | 13 | 生成方式有: 14 | 15 | 1、`ota_from_target_files`脚本生成制作完整更新软件包(整包)和增量更新软件包(差分包) 16 | 17 | 2、DIY制作OTA差分包 18 | 19 | ### OTA升级原理图如下: 20 | 21 | ![OTA升级原理图](https://s2.ax1x.com/2020/01/07/lcgNrV.png) 22 | 23 | 1、获取update.zip文件 24 | 25 | 2、验证签名文件 26 | 27 | 3、通过installPackage接口升级 28 | 29 | 4、系统重新启动进入recovery界面(判断/cache/recovery 是否有cmd文件) 30 | 31 | 5、try_update_binary执行升级脚本 32 | 33 | 6、finish_recovery 重启 34 | 35 | ## 热修复 36 | 37 | 优点有:无需重新发版,即使修复问题;无感知修复、无需下载新应用,代价小;修复成功率高,将损失降到最低。 38 | 39 | 缺点:热修复因为大量涉及android底层知识,又因为android本身开源,华为vivo小米几大厂商都可能修改底层相关代码,兼容性困难,所以热修复技术开发维护难度巨大,人力和时间投入不菲。目前主要有腾讯,阿里等几家互联网大厂因自身刚性需求,实现此功能。 40 | 41 | ### 热修复方案 42 | 43 | + 阿里系:AndFix、Dexposed、阿里百川、Sophix:`原理`:从底层二进制入手(c语言) 44 | 45 | #### 底层替换原理 46 | 47 | 底层替换就是直接通过Native层类实现即时的更新,但是由于是在Native层类原有上更改,所以有很多修改的`限制`,比如`不能`增减方法、字段,只能修改方法内的结果内容,过程如下图。 48 | 49 | ![底层替换原理图](https://s2.ax1x.com/2020/01/07/lcb1mQ.png) 50 | 51 | 底层替换方案和反射的原理有些关联,ArtMethod结构体就是反射invoke()方法Native中的调用,`AndFix`采用的是替换ArtMethod结构体中的字段,这样会有兼容问题,因为厂商可能会修改ArtMethod结构体,导致方法替换失败。`Sophix`采用的是替换整个ArtMethod结构体,这样不会存在兼容问题。 52 | 53 | + 腾讯系:微信的Tinker、QQ空间的超级补丁、手机QQ的QFix:`原理`:从java加载机制入手。 54 | 55 | #### 类加载机制原理 56 | 57 | 在for循环中,首先遍历出来的是dex文件,然后再是从dex文件中获取class,所以,我们只要让修复好的class打包成一个dex文件,放于Element数组的第一个元素,这样就能保证获取到的class是最新修复好的class了(当然,有bug的class也是存在的,不过是放在了Element数组的最后一个元素中,所以没有机会被拿到而已)。 58 | 59 | 简单原理图: 60 | 61 | ![简单原理图](https://s2.ax1x.com/2020/01/07/lcHIJ0.png) 62 | 63 | 深层原理图: 64 | 65 | ![类加载机制原理图](https://s2.ax1x.com/2020/01/07/lcHOeJ.png) 66 | 67 | #### 对比 68 | 69 | 热修复技术有三种,这里通过表格的方式进行对比: 70 | 71 | ![热修复技术对比](https://s2.ax1x.com/2020/01/07/lcbHht.jpg) 72 | 73 | ## OTA开发与Android热修复技术的相同与差异分析 74 | 75 | ### 相同 76 | 77 | + 解决紧急修复场景 78 | 79 | + 用户无感知。冷/热启动,生效所耗时长及资源(性能),patch体积 80 | 81 | + apk无感知。对原有项目侵入性低 82 | 83 | ### 差异 84 | 85 | + OTA技术针对的是**底层系统更新**,方式:`生成整包`或`差分包`进行`增量升级`。 86 | 87 | + 热修复技术针对的是系统上`应用`的更新。 88 | -------------------------------------------------------------------------------- /Android/Android自定义控件.md: -------------------------------------------------------------------------------- 1 | # Android自定义控件 2 | 3 | ## Android属性动画的分类 4 | 5 | + View Animation(补间) 6 | + Drawable Animation(帧动画) 7 | + Property Animation(Android3.0新引入) 8 | 9 | ### View Animation 10 | 11 | + 基于view的渐变动画,只改变view的绘制效果,而实际属性值未该改变。 12 | + 比如:动画移动一个按钮位置,但按钮点击的实际位置仍未改变。 13 | + 代码中定义动画,可以参考`AnimationSet`类和`Animation`的子类。 14 | + 而如果使用XML,可以在res/anim/文件夹中定义XML文件。 15 | + 下面是一个实例 16 | 17 | ```java 18 | TranslateAnimation animation = new TranslateAnimation(0,iv_animation.getWidth(),0,iv_animation.getHight()); 19 | /* 20 | iv_animation是需要移动的图片的id 21 | 使用TranslateAnimation的构造方法,将图片从0(原始位置)移动图片长度的长度(iv_animation.getWidth); 22 | 高度的移动也是同样的道理 23 | */ 24 | animation.setDuration(3000);//设置延迟效果 25 | animation.setFillAfter(true);//使得view不再复位 26 | iv_animation.startAnimation(animation);//开始移动 27 | ``` 28 | 29 | ### Drawable Animation 30 | 31 | + 加载一系列Drawable资源来创建动画,这种传统动画某种程度上就是创建不同图片序列,顺序播放,就像电影胶片。 32 | + 在代码中定义动画帧,使用`AnimationDrawable`类。 33 | + XML文件能更简单的组成动画帧,在`res/drawable`文件夹,使用``采用``来定义不同的帧。 34 | + 注:感觉只能设置的属性是动画间隔时间。 35 | 36 | ### Property Animation(属性动画) 37 | 38 | + 动画的对象除了传统的view对象,还可以是Object对象,动画之后,Object对象的属性值就实实在在的改变了。 39 | + Property Animation能够通过改变view对象的实际属性来实现view动画。 40 | + 任何时候view属性的改变,view能够自动调用invalidate()来试试刷新。 41 | + 下面是一个实例 42 | 43 | ```java 44 | ObjectAnimator animator = ObjectAnimator.ofFloat(iv_animation,"translationX",0,iv_animation.getWidth()); 45 | /* 46 | 使用ObjectAnimator的ofFloat进行平移 47 | ofFloat(平移的id,“如何平移,如:(水平->translationX)”,初始位置,平移距离); 48 | */ 49 | ObjectAnimator animator2 = ObjectAnimator.ofFloat(iv_animation,"translationY",0,iv_animation.getHight()); 50 | AnimatorSet animatorSet = new AnimatorSet(); 51 | AnimatorSet.setDuration(2000); 52 | AnimatorSet.setInterpolator(new BounceInterpolator()); 53 | //两个动画一起播放 54 | animatorSet.playTogether(animator,animator2); 55 | //开始播放 56 | animatorSet.start(); 57 | ``` 58 | 59 | + 另一种写法 60 | 61 | ```java 62 | iv_animation.animate() 63 | .translationXBy(iv_animation.getWidth()) 64 | .translationYBy(iv_animation.getHight()) 65 | .setDuration(2000) 66 | .setInterpolator(new BounceInterpolator()) 67 | .start(); 68 | ``` 69 | 70 | ### ViewPager(广告条效果) 71 | 72 | + ViewPager的使用 73 | + 广告条的基本功能 74 | + ViewPager拓展 75 | + 改进成引导页面 76 | 77 | #### ViewPager的使用 78 | 79 | + 第一:使用`android.support.v4.view.ViewPager`在布局文件中定义 80 | + 第二:在代码中实例化ViewPager 81 | + 第三:准备数据 82 | + 第四:设置适配器(PagerAdapter)-item-布局-绑定数据 83 | -------------------------------------------------------------------------------- /how to use git and repo.md: -------------------------------------------------------------------------------- 1 | # how to use git and repo 2 | 3 | ## git中常见的指令 4 | 5 | ### 新建一个仓库 6 | 7 | + git init 8 | 9 | + git clone \ 10 | 11 | ### 对仓库内内容的保存与判断 12 | 13 | git中使用的判断条件是:`SHA-1校验和` 14 | 15 | ### 仓库中文件转换 16 | ![File Status Lifecycle](https://github.com/kentanvictor/STUDY/blob/Image/File%20Status%20Lifecycle.png?raw=true) 17 | 18 | + git add \ 19 | 20 | ![Untracked](https://github.com/kentanvictor/STUDY/blob/Image/Untracked.png?raw=true) 21 | 22 | 使用add命令能够将untracked文件track,而通过reset命令能够将tracked转换成untracked 23 | 24 | add之后再查看文件状态 25 | 26 | ![tracked](https://github.com/kentanvictor/STUDY/blob/Image/tracked.png?raw=true) 27 | 28 | ### git fetch and pull 29 | 30 | ![指令示意图](https://github.com/kentanvictor/STUDY/blob/Image/%E6%8C%87%E4%BB%A4%E7%A4%BA%E6%84%8F%E5%9B%BE.png?raw=true) 31 | 32 | + git fetch:将远程主机的最新内容拉取到本地,用户在检查了以后决定是否合并到工作本机分支当中 33 | 34 | + git pull:将远程主机的最新内容拉取下来直接合并。`即:git pull = git fetch + git merge` 35 | 36 | + git reset 37 | 38 | git reset会把指定的提交的所有修改回滚,并同时生成一个新的提交。 39 | 40 | git reset 会修改HEAD到指定的状态,用法为: 41 | 42 | ``` 43 | git reset [options] 44 | ``` 45 | 46 | 这条命令会使HEAD提向指定的Commit,一般会用到3个参数,这3个参数会影响到工作区与暂存区中的修改: 47 | 48 | + --soft: 只改变HEAD的State,不更改工作区与暂存区的内容 49 | + --mixed(默认): 撤销暂存区的修改,暂存区的修改会转移到工作区 50 | + --hard: 撤销工作区与暂存区的修改 51 | 52 | ### git rebase and git merge 53 | 54 | + git rebase 55 | 56 | `rebase` 会把你当前分支的 commit 放到公共分支的最后面 57 | 58 | ![rebase示意图](https://github.com/kentanvictor/STUDY/blob/Image/rebase%E7%A4%BA%E6%84%8F%E5%9B%BE.png?raw=true) 59 | 60 | + git merge 61 | 62 | `merge` 会把公共分支和你当前的commit 合并在一起,形成一个新的 commit 提交 63 | 64 | ![merge示意图](https://github.com/kentanvictor/STUDY/blob/Image/merge%E7%A4%BA%E6%84%8F%E5%9B%BE.png?raw=true) 65 | 66 | ### 与人协作 67 | 68 | #### cherry-pick 69 | 70 | 当与别人和作开发时,会向别人贡献代码或者接收别人贡献的代码,有时候可能不想完全merge别人贡献的代码,只想要其中的某一个提交,这时就可以使用cherry-pick了。 71 | 72 | ``` 73 | git cherry-pick 74 | ``` 75 | 76 | #### 新建分支 77 | 78 | ``` 79 | git branch 80 | ``` 81 | 82 | 有时需要在新建分支后直接切换到新建的分支,可以直接用checkout的-b选项 83 | 84 | ``` 85 | git checkout -b 86 | ``` 87 | 88 | #### 删除分支 89 | 90 | ``` 91 | git branch -d 92 | ``` 93 | 94 | 如果在指定的分支有一些unmerged的提交,删除分支会失败,这里可以使用-D参数强制删除分支。 95 | 96 | ``` 97 | git branch -D 98 | ``` 99 | 100 | #### 检出分支或提交 101 | 102 | 检出某一分支或某一提交是同一个命令 103 | 104 | ``` 105 | git checkout | 106 | ``` 107 | 108 | -------------------------------------------------------------------------------- /JAVA学习/Java EE/Java Design Pattern.md: -------------------------------------------------------------------------------- 1 | # Java Design Pattern 2 | 3 | `Ambition:` 4 | 5 | + 1、反射技术 6 | 7 | + 2、动态代理、责任链模式、拦截器 8 | 9 | + 3、观察者模式 10 | 11 | + 4、工厂和抽象工厂模式 12 | 13 | + 5、Builder构建模式 14 | 15 | ## Java 反射技术 16 | 17 | 正向的方式是: 18 | 19 | ```Java 20 | Student john = new Student(); 21 | john.setAge(23); 22 | ``` 23 | 24 | 反射的方式进行方法的调用是: 25 | 26 | ```Java 27 | // 获取Class对象实例 28 | Class clz = Class.forName("com.example.Student"); //类的全路径名 29 | // 根据 Class 对象实例获取 Constructor 对象 30 | Constructor appleConstructor = clz.getConstructor(); 31 | //使用 Constructor 对象的 newInstance 方法获取反射类对象 32 | Object johnObj = appleConstructor.newInstance(); 33 | // 获取方法的 Method 对象 34 | Method setAgeMethod = clz.getMethod("setAge", int.class); 35 | // 利用 invoke 方法调用方法 36 | setPriceMethod.invoke(johnObj, 23); 37 | 38 | /** 39 | 如果有多个参数,可以写成 40 | Method.invoke(target, obj1, obj2, obj3, ……) 41 | **/ 42 | 43 | ``` 44 | 45 | ## 动态代理、责任链模式、拦截器 46 | 47 | ### 动态代理 48 | 49 | 代理必须分为两步: 50 | 51 | + 代理对象和真实对象之间建立代理关系 52 | 53 | + 实现代理对象的代理逻辑方法 54 | 55 | 动态代理主要分为两种实现方式: 56 | 57 | + JDK动态代理 ————> JDK自带功能 58 | 59 | + CGLIB ————> 第三方 60 | 61 | #### JDK动态代理 62 | 63 | `注:需要接口` 64 | 65 | + 通常的写法: 66 | 67 | 定义接口: 68 | 69 | ```Java 70 | public interface Hello { 71 | void morning(String name); 72 | } 73 | ``` 74 | 75 | 编写实现类: 76 | 77 | ```Java 78 | public class HelloWorld implements Hello { 79 | public void morning(String name) { 80 | System.out.println("Good morning, " + name); 81 | } 82 | } 83 | ``` 84 | 85 | 创建实例,转型为接口并调用: 86 | 87 | ```Java 88 | Hello hello = new HelloWorld(); 89 | hello.morning("Bob"); 90 | ``` 91 | 92 | + JDK动态代理写法: 93 | 94 | `Proxy.newProxyInstance()`创建了一个`Hello`接口对象 95 | 96 | ```Java 97 | public class Main { 98 | public static void main(String[] args) { 99 | InvocationHandler handler = new InvocationHandler() { 100 | @Override 101 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 102 | System.out.println(method); 103 | if (method.getName().equals("morning")) { 104 | System.out.println("Good morning, " + args[0]); 105 | } 106 | return null; 107 | } 108 | }; 109 | Hello hello = (Hello) Proxy.newProxyInstance( 110 | Hello.class.getClassLoader(), // 传入ClassLoader 111 | new Class[] { Hello.class }, // 传入要实现的接口 112 | handler); // 传入处理调用方法的InvocationHandler 113 | hello.morning("Bob"); 114 | } 115 | } 116 | 117 | interface Hello { 118 | void morning(String name); 119 | } 120 | 121 | ``` -------------------------------------------------------------------------------- /Android/生命周期的分析.md: -------------------------------------------------------------------------------- 1 | # activity的生命周期分析 2 | * activity的生命周期分为两部分内容 3 | * 典型情况下的生命周期 4 | >在有用户参与的情况下,activity所经历过的生命周期的改变 5 | 6 | * 异常情况下的生命周期 7 | >指activity被系统回收或由于当前设备的Configuration发生改变从而导致activity被销毁重建 8 | 9 | 10 | 11 | ## 典型情况下的生命周期分析 12 | 13 | ### 正常生命周期解析 14 | 15 | 正常情况下,activity会经历如下生命周期 16 | 17 | + onCreate:表示activity正在被创建。 18 | 19 | >+ 这是生命周期的第一个方法、在这个方法中,我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源、初始化activity所需要的数据等等 20 | >+ 通过覆盖onCreate(Bundle)方法,activity可以预处理以下UI相关工作: 21 | >+ 实例化组件并将它们放置到屏幕上(调用setContentView(int)方法) 22 | >+ 引用已实例化的组件 23 | >+ 为组件设置监听器以处理用户交互 24 | >+ 访问外部模型数据 25 | * onRestart:表示activity正在启动。 26 | >一般情况下,当当前的activity从不可见重新变为可见的状态时,onRestart就会被调用。**这种情况一般都是用户导致的,当用户按Home键切换到桌面的或者用户打开了一个新的activity,这时当前的activity就会暂停,也就是onPause和onStop被执行,接着用户又回到了这个activity,就会出现这种情况** 27 | * onStart:表示activity正在被启动,即将开始。 28 | >这时activity已经可见了,但是还没有出现在前台,还无法和用户交互。这个时候其实可以理解为activity已经显示出来了,但是我们还看不到 29 | * onResume:表示activity已经可见了,并且出现在前台并开始活动。 30 | >要注意这个和onStart的对比,onStart和onResume都表示activity已经可见,但是onStart的时候activity还在后台,onResume的时候activity才显示到前台。 31 | * onPause:表示activity正在停止,正常情况下,紧接着onStop就会被调用。 32 | >在特殊情况下, 如果这个时候快速地再回到当前activity,那么onResume会被调用。可以理解为这种属于极端的情况,用户操作很难重现这种场景。此时可以做一些存储数据、停止动画等工作,但是注意不能太耗时,因为这会影响到新的activity的显示,onPause必须先执行完,新activity的onPause才会执行。 33 | * onStop:表示activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。 34 | * onDestroy:表示activity即将被销毁。 35 | >这是activity生命周期中的最后的一个回调,在这里,我们可以做一些回收工作和最终的资源释放。 36 | 37 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/activity.png?raw=true) 38 | 39 | 40 | `注:` 41 | 42 | + 当一个**activity**第一次启动时,回调程序如下:onCreate()->onStart()->onResume() 43 | + 用户打开**新的activity**或**切回桌面**时,回调如下:onPause()->onStop() 44 | + 用户重新回到**原activity**,回调如下;onRestart()->onStart()->onResume() 45 | + **back键**回退时,回调如下:onPause()->onStop()->onDestroy() 46 | 47 | `从整个生命周期来说:`onCreate()与onDestroy()配对。 48 | 49 | `从activity是否可见来说:`onStart()与onStop()配对。 50 | 51 | `从activity是否前台来说:`onResume()和onPause()配对。 52 | 53 | ***** 54 | 55 | `问题:`假设当前是activity A,如果用户这个时候打开一个activity B,那么是B的onResume()先执行还是A的onPause()先执行? 56 | 57 | `结论:`旧的activity中onPause()先调用,新的activity中的onResume()才被执行。 58 | 59 | ## 异常情况下的生命周期分析 60 | 61 | ### 资源相关的系统配置发生变化导致activity被杀死进行重建 62 | 63 | >默认情况下,如果我们不对activity进行特殊处理,那么当系统配置或资源发生变化的时候,activity就会被销毁并重建。如:旋转手机屏幕等。 64 | 65 | `注:` 66 | + activity被异常杀死重建,activity中onPause()、onStop()、onDestroy()都会被调用。 67 | + 系统会调用 **onSaveInstanceState()** 方法对当前activity的状态进行保存,调用位置位于onStop()之前,**时序与onPause()无关**。 68 | + 从时序上来说,**onRestoreInstanceState()** 是在onStart()之后。 69 | 70 | 示例图如图所示: 71 | ![](https://github.com/kentanvictor/STUDY/blob/Image/Android%E5%BC%80%E5%8F%91%E6%8E%A2%E7%B4%A2/%E5%BC%82%E5%B8%B8%E6%83%85%E5%86%B5%E4%B8%8Bactivity%E9%87%8D%E5%BB%BA%E8%BF%87%E7%A8%8B.png?raw=true) 72 | 73 | 74 | ### 资源内存不足导致低优先级activity被杀死 -------------------------------------------------------------------------------- /QT控件的使用.md: -------------------------------------------------------------------------------- 1 | # 控件的使用 2 | **在这里所要讲到的,就是快速开发中的控件的使用。** 3 | 4 | + QDateEdit 5 | + 控件效果为: 6 | 7 | ![](./image/dateEdit.png) 8 | 9 | + 例如,使用其`获取系统时间`(代码如下): 10 | 11 | ``` 12 | //获取系统日期 13 | QDateTime sysTime = QDateTime::currentDateTime(); 14 | QStringList list = sysTime.toString("yyyy-MM-dd").split('-'); 15 | ui.dateEdit->setDate(QDate(list[0].toInt(),list[1].toInt(), list[2].toInt())); 16 | ``` 17 | 18 | + 控件与信号槽的使用 19 | + 先使用QSpinBox控件和QSlider控件创建布局(如下图所示): 20 | ![](./image/SpinBox.png) 21 | + 下面是控件基于信号槽的使用(代码如下): 22 | 23 | + **位于QTGUITest.h中** 24 | 25 | ``` 26 | private slots: 27 | void slider1_valuechanged(int value) 28 | { 29 | ui.spinBox->setValue(value); 30 | } 31 | void slider2_valuechanged(int value) 32 | { 33 | ui.spinBox_3->setValue(value); 34 | } 35 | ``` 36 | 37 | + **位于QTGUITest.cpp中** 38 | 39 | ``` 40 | //关联QSlider控件 41 | connect(ui.horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(slider1_valuechanged(int))); 42 | connect(ui.horizontalSlider_3, SIGNAL(valueChanged(int)), this, SLOT(slider2_valuechanged(int))); 43 | ``` 44 | 45 | + 最后实现的效果如下: 46 | 47 | ![](./image/QSpinBoxFinish.png) 48 | 49 | + 键盘输入实现 50 | + **在QTGUITest.h中添加函数** 51 | 52 | ``` 53 | private void keyPressEvent(QKeyEvent *); 54 | ``` 55 | 56 | + 然后**在QTGUITest.cpp中实现** 57 | 58 | ``` 59 | void QTGUITest::keyPressEvent(QKeyEvent *e) 60 | { 61 | switch(e->key()) 62 | { 63 | //减法键 64 | case Qt::Key_Minus: 65 | ui.textBrowser->insertPlainText("-"); 66 | break; 67 | //乘法键 68 | case Qt::Key_Asterisk: 69 | ui.textBrowser->insertPlainText("*"); 70 | break; 71 | //除法键 72 | case Qt::Key_Slash: 73 | ui.textBrowser->insertPlainText("/"); 74 | break; 75 | //取模键 76 | case Qt::Key_Percent: 77 | ui.textBrowser->insertPlainText("%"); 78 | break; 79 | //乘方键 80 | case Qt::Key_AsciiCircum: 81 | ui.textBrowser->insertPlainText("^"); 82 | break; 83 | } 84 | } 85 | ``` 86 | 87 | ***上面的的Key的键位还有很多种,可以去参照QT的官方文档进行查阅。*** 88 | 89 | + 获取到textBrower里面的内容并将其转化为char*类型 90 | 91 | ``` 92 | QString str = ui.textBrowser->toPlainText(); 93 | QByteArray ba = str.toLatin1(); 94 | ch = ba.data(); 95 | ``` 96 | 97 | + 将char*转换为QString的方式 98 | 99 | ``` 100 | char c3[MAX]; 101 | QByteArray b2 = QByteArray(c3); 102 | QString s2 = QString(b2) 103 | ``` 104 | 105 | + int类型转换为QString类型 106 | 107 | ``` 108 | int _mStackSize; 109 | QString s3 = QString::number(_mStackSize); 110 | ``` 111 | 112 | + 实现键盘上的backspace键 113 | 114 | ``` 115 | QTextCursor cursor; 116 | cursor = ui.textBrowser->textCursor(); 117 | cursor.deletePreviousChar(); 118 | ``` 119 | -------------------------------------------------------------------------------- /JAVA学习/hashCode与equals深度剖析与源码详解.md: -------------------------------------------------------------------------------- 1 | # hashCode与equals详解 2 | 3 | ****注:构造方法与普通方法之间的区别在于:构造方法的名称与类名相同、不需要定义返回值类型和不可以写renturn语句。其作用只在于给对象起到初始化的效果**** 4 | ### 构造方法与一般方法在写法上的不同: 5 | 构造方法: 6 | ```java 7 | public(修饰符) class(定义类的关键字) Test(类名)() 8 | { 9 | //无参 10 | Test(类名)() 11 | { 12 | 13 | 14 | } 15 | //带一个参数 16 | Test(类名)(String(变量类型) name(变量名)) 17 | { 18 | 19 | 20 | } 21 | 22 | } 23 | ``` 24 | ### 一般方法: 25 | 定义类: 26 | ```java 27 | public(修饰符) class(定义类的关键字) Test(类名)() 28 | { 29 | private(修饰符) static(修饰符) String(变量类型) s(变量名) = "hello world"; 30 | // 下面是方法的定义 31 | public(修饰符) static(修饰符) void(返回值类型) main(方法名)(String[] args(参数)) 32 | { 33 | System.out.println(s);(代码语句) 34 | } 35 | } 36 | ``` 37 | >#### 构造方法与一般方法在运行上的不同: 38 | * 构造方法: 39 | 构造方法在创建的时候就给对象初始化; 40 | 一个对象建立构造方法只能运行一次; 41 | * 一般方法: 42 | 一般方法是对象调用才执行,给对象添加对象具备的功能; 43 | 一般方法可以被对象多次调用; 44 | 45 | # Interface Set < E > 46 | * 实现Set接口的类有: 47 | * AbstractSet、ConcurrentSkipListSet、CopyOnWriteArraySet、EnumSet、HashSet、JobStateReasons 48 | * LinkedHashSet、TreeSet 49 | 50 | ## 在Interfere Set< E >接口中,使用的最多的继承的类就是HashSet 51 | * HashSet的构造方法一共有四个: 52 | * HashSet() 53 | * HashSet(Collection c) 54 | * HashSet(int initialCapacity) 55 | * HashSet(int initialCapacity,float loadFactor) 56 | 57 | 58 | * Method Summary 59 | * boolean add(E e) 60 | >Add the specified element to this set if it is not already present.(如果不存在,则将指定的元素添加到该集合中) 61 | >If this set already contains the element, the call leaves the set unchanged and renturns false.(如果集合中包含这个元素,则集合不会被修改,返回值为假。) 62 | 63 | * void clear() 64 | >Removes all of the elements from this set.(移除此集合中的所有元素。) 65 | 66 | * Object clone() 67 | >Returns a shallow copy of this HashSet instance: the elements themselves are not cloned.(返回此HashSet实例浅拷贝:元素本身不是克隆。) 68 | 69 | * boolean contains(Object o) 70 | >Returns true if this set contains the specified element.(如果此集合包含指定元素,则返回true。) 71 | 72 | * boolean isEmpty() 73 | >Returns true if this set contains no element.(如果此集合不包含元素,返回true。) 74 | 75 | * Interator< E > interator() 76 | >Returns an iterator over the elements in this set.(返回此集合中元素的迭代器。) 77 | 78 | * boolean remove(Object o) 79 | >Removes the specified element from this set if it's present.(如果此集合存在,则从该集合中移除指定元素。) 80 | 81 | * int size() 82 | >Returns the number of elements in this set(its cardinality)(返回此集合中的元素数(它的基数) 83 | 84 | ### 关于Object类的equals方法的特点 85 | * 自反性:x.equals(x)应该返回true 86 | * 对称性:x.equals(y)为true,那么y.equals(x)返回值也为true 87 | * 可传递性:x.equals(y)为true并且y.equals(z)为true,那么x.equals(z)也应该为true。 88 | * 一致性:x.equals(y)的第一次调用为true,那么x.equals(y)的第二次、第三次、第n次调用也应该为true,前提条件是在比较之间没有修改x也沒有修改y。 89 | * 对于任何的非空引用x,x。equals(null)返回false。 90 | **当我们需要重写hashcode()方法的时候也需要重写equals()方法,同样的道理,当重写了equals()方法也需要重写equals()方法** 91 | 92 | ## 关于Object类中的hashcCode()方法的特点: 93 | * 在Java应用的一次执行过程当中,对于同一个对象的hashcCode方法的多次调用,他們应该返回同样的值。 94 | -------------------------------------------------------------------------------- /计算机基础/程序员的数学(笔记).md: -------------------------------------------------------------------------------- 1 | # 程序员的数学 2 | * 二进制 3 | * 10进制转2进制:将数反复地除以2并观察余数是'1'还是'0'。--->余数是'0'表示'除完了'。 4 | * 随后再将每步所得到的余数的列(1和0的列)逆向排列。(如下图所示:) 5 | 6 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/Binary.png?raw=true) 7 | 8 | * 二进制的加法表如下: 9 | 10 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/Binary_add.png?raw=true) 11 | 12 | + 0的作用 13 | + 占位 14 | + 统一标准,简化规则 15 | >在按位计数法中,运用"0次方",使用'0'能够将按位计数法的各个数位所对应的大小统一标示 16 | 如:(10进制为例) 17 | **10^n** 全部表示为: 18 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/Decimal_system.png?raw=true) 19 | 20 | + 逻辑 21 | + 能够判断对错的陈述句叫做命题 22 | + 单个命题的逻辑非--否A 23 | + 命题与命题之间的关系有: 24 | + 逻辑与--A并且B 25 | + 逻辑或--A或者B 26 | + 异或--A或者B(但不满足) 逻辑表达式写作:![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/XOR.png?raw=true) 27 | + 相等--A和B相等 28 | + 蕴涵--若A则B 29 | 30 | #### 以上的复合型逻辑表达式 31 | 32 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/logic.png?raw=true) 33 | 34 | * 德·摩根定律 35 | >就是一个逻辑表达式的转换 36 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/De_Morgan.png?raw=true) 37 | 38 | * 对偶性 39 | >![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/duality.png?raw=true) 40 | >它们相互成对,这称作逻辑表达式的对偶性 41 | 42 | * 卡诺图(Karnaugh Map) 43 | >将所有命题的真假组合以二维表的形式表示的图 44 | >* 这里玩一个游戏:二灯游戏 45 | > * 这里有一个游戏机,屏幕上显示着一绿一黄两个灯泡,不断忽闪忽灭。 46 | > * 遵守以下跪着迅速按下游戏机按钮 47 | > * 1)绿灯灭,黄灯亮 48 | > * 2)绿灯、黄灯都灭 49 | > * 3)绿灯、黄灯都亮 50 | > 51 | > ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/light.png?raw=true) 52 | > 53 | >* 解析: 54 | > * 假设命题A:绿灯亮 55 | > * 假设命题B:黄灯亮 56 | > * 按照题目的意思就有以下a、b、c的三种的逻辑或 57 | > 58 | > ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/Logical_or.png?raw=true) 59 | > 60 | >**也就是说当以下逻辑表达式为true的时候要按下按钮** 61 | > 62 | >![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/push_button.png?raw=true) 63 | > 64 | 65 | #### 这个时候就需要卡诺图了 66 | 1、第一步:打上勾 67 | 68 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/Tick.png?raw=true) 69 | 70 | 2、相邻打钩格形成的组合框 71 | 72 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/combo_box.png?raw=true) 73 | 74 | 3、画出组合框、思考逻辑表达式 75 | 76 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/Karnaugh.png?raw=true) 77 | 78 | ### 所以上面特别长的逻辑表达式就被简化成 79 | 80 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/complex.png?raw=true) 81 | ## 综上所述,卡诺图就是简化逻辑表达式的 82 | 83 | * 带条件的逻辑与(&&) 84 | * 三值逻辑中的逻辑与(带条件的逻辑与(conditional and, short-circuit logical and)) 85 | * 使用运算符&& 86 | * 三值为(TRUE/FALSE/UNDEFINED) 87 | 88 | # 两章总结 89 | * 关于"0"的故事,通过使用逻辑表达式、真值表、文氏图、卡诺图等等工具知道了如何表达那些复杂逻辑 90 | 91 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/logical_expression.png?raw=true) 92 | 93 | * 运用逻辑实现简化 94 | 95 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/using_logic.png?raw=true) 96 | 97 | * 关于未定义值得三值逻辑 98 | * 一般逻辑是“一分为二” 99 | * 三值逻辑是“一分为三” 100 | -------------------------------------------------------------------------------- /数据结构/线性表/Arraylist/StackList.java: -------------------------------------------------------------------------------- 1 | package com.dell.example.linearlist; 2 | 3 | import java.util.Scanner; 4 | 5 | /* 6 | * Created by JohnnyTan on 2017/10/10. 7 | */ 8 | public class StackList { 9 | public static void main(String[] args) { 10 | StackType st = new StackType(); 11 | Information data = new Information(); 12 | //初始化 13 | StackType stack = st.STInit(); 14 | Scanner input = new Scanner(System.in); 15 | System.out.println("入栈操作:\n"); 16 | System.out.println("输入姓名 年龄进行入栈操作:"); 17 | do { 18 | Information info = new Information(); 19 | info.name = input.next(); 20 | 21 | if(info.name.equals("0")) 22 | { 23 | break; 24 | } 25 | else 26 | { 27 | info.age = input.nextInt(); 28 | st.PushST(stack,info); 29 | } 30 | }while (true); 31 | String temp = "1"; 32 | System.out.println("出栈操作:按任意非0键进行出栈操作:"); 33 | temp = input.next(); 34 | while (!temp.equals("0")) 35 | { 36 | data = st.PopST(stack); 37 | System.out.printf("出栈的数据是(%s,%d)\n",data.name,data.age); 38 | temp = input.next(); 39 | } 40 | System.out.println("测试结束!"); 41 | st.STFree(st);//释放所占用的空间 42 | } 43 | } 44 | class Information 45 | { 46 | String name; 47 | int age; 48 | } 49 | 50 | class StackType 51 | { 52 | static final int MAX = 50; 53 | Information[] data = new Information[MAX + 1]; 54 | int top; 55 | 56 | //申请栈内存,并初始化 57 | StackType STInit() 58 | { 59 | StackType p; 60 | if ((p = new StackType()) != null) 61 | { 62 | p.top = 0; 63 | return p; 64 | } 65 | return null; 66 | } 67 | 68 | //判断栈是否为空 69 | boolean STIsEmpty(StackType s) 70 | { 71 | boolean t; 72 | t = (s.top == 0); 73 | return t; 74 | } 75 | 76 | //判断栈是否已满 77 | boolean STIsNUll(StackType s) 78 | { 79 | boolean t; 80 | t =(s.top == MAX); 81 | return t; 82 | } 83 | 84 | //清空栈 85 | void STClear(StackType s) 86 | { 87 | s.top = 0; 88 | } 89 | 90 | //释放栈所占用的空间 91 | void STFree(StackType s) 92 | { 93 | if(s != null) 94 | { 95 | s = null; 96 | } 97 | } 98 | 99 | //入栈操作 100 | int PushST(StackType s,Information data) 101 | { 102 | if((s.top+1) > MAX) 103 | { 104 | System.out.println("栈溢出!\n"); 105 | return 0; 106 | } 107 | s.data[++s.top] = data; 108 | return 1; 109 | } 110 | 111 | //出栈操作 112 | Information PopST(StackType s) 113 | { 114 | if(s.top == 0) 115 | { 116 | System.out.println("栈为空!\n"); 117 | System.exit(0); 118 | } 119 | return (s.data[s.top]); 120 | } 121 | } 122 | 123 | -------------------------------------------------------------------------------- /JAVA学习/深入理解ArrayList.md: -------------------------------------------------------------------------------- 1 | # ArrayList 2 | * Java中的动态数组,可以用来动态的开辟空间用于存储数据。 3 | * 位于java.util包中 4 | * 继承的接口有:Serializable, Cloneable, Iterable, Collection, List, RandomAccess 5 | * 继承ArrayList的子类有:AttributeList, RoleList, RoleUnresolvedList 6 | 7 | ```java 8 | public class ArrayList 9 | extends AbstractList 10 | implements List,RandomAccess,Cloneable,Serializable 11 | 12 | ``` 13 | 14 | * 增加内容: 15 | * ArrayList.add(E e)/*Appends the specified element to the end of this list.*/(将指定元素按照列表的形式排列到结束) 16 | * ArrayList.add(int index,E element)/*Inserts the specified element at the specified position in this list.*/(插入算法,将指定元素插入到指定的位置上) 17 | * ArrayList.addAll(Collection<?extends E> c) 18 | * ArrayList.addAll(int index,Collection c) 19 | * 上面两种方法是将第一个生成的对象插入到第二个对象之后或者是指定位置。(*代码如下:*) 20 | 21 | ```Java 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /* 26 | * Here we will learn how to append elements from a Collection to ArrayList. 27 | */ 28 | public class AppendAllElementOfCollection { 29 | 30 | public static void main(String args[]) { 31 | List list = new ArrayList(); 32 | 33 | /* 34 | * add() method appends the specified element to the end of given list. 35 | */ 36 | list.add(1); 37 | list.add(2); 38 | list.add(3); 39 | list.add(4); 40 | 41 | List listToAppend = new ArrayList(); 42 | 43 | /* 44 | * This is the second collection whose elements needs to be added in 45 | * first collection 46 | */ 47 | listToAppend.add(5); 48 | listToAppend.add(6); 49 | listToAppend.add(7); 50 | listToAppend.add(8); 51 | 52 | System.out.println("Elements in Arraylist"); 53 | /* 54 | * As ArrayList implements Iterable, ArrayList can be used in extended 55 | * For Loop 56 | */ 57 | for (int i : list) 58 | System.out.println(i); 59 | 60 | /** 61 | * ArrayList have a Overloaded method(addAll(Collection c)) 62 | * which appends all of the elements in the specified collection to the 63 | * end of given list, in the order elements are returned by the 64 | * specified collection's iterator. The behavior of this operation is 65 | * undefined if the specified collection is modified while the operation 66 | * is in progress. 67 | */ 68 | list.addAll(listToAppend); 69 | 70 | System.out 71 | .println("nElements in ArrayList after appending all elements from Collection"); 72 | 73 | for (int i : list) 74 | System.out.println(i); 75 | 76 | } 77 | } 78 | ``` 79 | 80 | * 清除:ArrayList.clear()/*Removes all of the elements from this list.*/(清除列表中所有的元素) 81 | * 复制:ArrayList.clone()/*Returns a shallow copy of this ArrayList instance.*/(返回一个ArrayList的拷贝实例) 82 | * 判断是否包含元素:ArrayList.contains(Object o)/*Returns true if this list contains the specified element.*/(判断列表中是否包含某种元素,若包含则返回true) 83 | 84 | ## 注:还有更多的ArrayList的方法可以参考官方文档 85 | 86 | [java.util.ArayList](http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4) 87 | 88 | ![](https://github.com/kentanvictor/STUDY/blob/Image/old_image/ArrayList.png?raw=true) 89 | 90 | -------------------这是一条分割线(下面是ArrayList另外具有的方法)-------------------------- 91 | 92 | ![](../image/method.png) 93 | -------------------------------------------------------------------------------- /基于Python的简单爬虫结构.md: -------------------------------------------------------------------------------- 1 | # 爬虫 2 | ## 简单爬虫结构 3 | ![](./image/python.png) 4 |
5 | ## URL管理器 6 | ![](./image/URL.png) 7 |
8 | ## URL实现方式 9 | ![](image/URL_Realization.png) 10 |
11 | ## 这里是一个爬虫网页下载器 12 | 13 | ### 网页下载器-urllib2 14 | * urllib2下载网页方法1:最简洁方法 15 | ![](./image/URL_download.png) 16 | * urllib2下载网页方法2:添加data、http、header 17 | ![](./image/URL_add.png) 18 | * urllib2下载网页方法3:添加特殊情景的处理器 19 | ![](./image/URL_processor.png) 20 | **代码如下** 21 | ```python 22 | from urllib import request 23 | import http.cookiejar 24 | url = 'http://www.baidu.com' 25 | print('第一种方法:') 26 | response1 = request.urlopen(url) 27 | print(response1.getcode()) 28 | print(len(response1.read())) 29 | print('第二种方法') 30 | req = request.Request(url) 31 | req.add_header('user-agent', 'Mozilla/5.0') 32 | response2 = request.urlopen(req) 33 | print(response2.getcode()) 34 | print(len(response2.read())) 35 | print('第三种方法') 36 | cj = http.cookiejar.CookieJar() 37 | opener = request.build_opener(request.HTTPCookieProcessor(cj)) 38 | request.install_opener(opener) 39 | response3 = request.urlopen(url) 40 | print(response3.getcode()) 41 | print(cj) 42 | print(response3.read()) 43 | r = opener.open(req) 44 | print(r.read().decode('utf-8')) 45 | ``` 46 | ## 下面是一个网页解析器 47 | >网页解析器:**从网页中提取有价值数据的工具** 48 | >![](./image/Web_parser.png) 49 | >* python四种网页解析器 50 | >![](./image/four_type_of_Web_parser.png) 51 | >>**什么叫做结构化解析?** 52 | >>结构化解析-DOM(Document Object Model)树 53 | >>![](./image/DOM.png) 54 | 55 | ### BeautifulSoup语法 56 | ![](./image/BeautifulSoup.png) 57 | * [BeautifulSoup4.2.0中文文档](https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#id10) 58 | 59 | ```python 60 | from bs4 import BeautifulSoup 61 | import re 62 | #下面的html_doc是一个例子 63 | html_doc = """ 64 | The Dormouse's story 65 | 66 |

The Dormouse's story

67 |

Once upon a time there were three little sisters; and their names were 68 | Elsie, 69 | Lacie and 70 | Tillie; 71 | and they lived at the bottom of a well.

72 |

...

73 | """ 74 | soup = BeautifulSoup(html_doc, 'html.parser', from_encoding='utf-8') 75 | print('获取所有链接') 76 | links = soup.find_all('a') 77 | for link in links: 78 | print(link.name, link['href'], link.get_text()) 79 | #这里只想获取Lacie的链接,所以href后面的链接就可以直接复制过来 80 | print('获取Lacie链接') 81 | linknode = soup.find_all('a', href='http://example.com/lacie') 82 | for link in linknode: 83 | print(link.name, link['href'], link.get_text()) 84 | #正则匹配就相当于模糊匹配 85 | print('正则匹配') 86 | linknode = soup.find_all('a', href=re.compile(r'ill')) 87 | for link in linknode: 88 | print(link.name, link['href'], link.get_text()) 89 | print('获取P') 90 | pnode = soup.find_all('p', class_='title') 91 | for link in pnode: 92 | print(link.name, link.get_text()) 93 | 94 | ``` 95 | -------------------------------------------------------------------------------- /Git.md: -------------------------------------------------------------------------------- 1 | # Git 2 | ## What is Git? 3 | * Git is the most advanced distributed version control system in the world. 4 | ## What is the different between the SVN(Subversion) and the Git? 5 | * SVN is a centralized version control system which version library centralized packed in the central server.So if you need to do your work,you must go to the central server to download the latest version.When you finished your work,you have to push on the central server.It's so inconvenient.Actually the centralized version control system must accessible networking. 6 | ##### just like this photo 7 | 8 | ![](./image/subversion.png) 9 | 10 | * Git is a distributed version control system,which advantaged is if it has not a central version,the LapTop is a rounded version library.because of this, you can work without using network. 11 | ##### just like this photo 12 | 13 | ![](./image/git.png) 14 | 15 | ## there are some useful command lines : 16 | * mkdir: XX (Create an empty directory)/*XX refer to directory name*/ 17 | * pwd: (Show the path to the current directory) 18 | * git: init (Change the current directory to a managed Git repository,create a hidden file) 19 | * git add XX (Add XX file to working-storage section) 20 | * git commit -m "XX" (Add a comment to a file)/*XX is the comment*/ 21 | * git status (View warehouse status) 22 | * git log (View history) 23 | * git diff XX (View XX file what are modified) 24 | * git rm XX (Delete XX file) 25 | * cat XX (View file contents) 26 | * git checkout -b A (Create a A branch and switch to A branch) 27 | * git checkout master (back to master branch) 28 | * git clone HTTPS (clone from online warehouse) 29 | * git branch name (create a branch) 30 | * git branch -d A (Delete A branch) 31 | * git push origin master (push master branch to online warehouse) 32 | 33 | # 如何使用Git Bash 34 | 35 | ## 新建 36 | + 第一步:当需要上传一个项目到Github时,这个时候你需要在自己的Github上新建一个项目New repository 37 | + 第二步:在右下角有一个Clone or download点击之后有一个Clone with HTTPS Use Git or checkout with SVN using the web URL. 38 | + 第三步:复制地址之后在需要上传的项目文件中右键,点击Git Bash Here之后先输入 git clone + 地址。 39 | + 第四步:这时会出现一个项目名称的文件夹里面有隐藏文件.git与README.md 40 | + 第五步:将具有项目名称的文件夹中的全部内容剪切到需要上传的项目的根目录下之后在Git Bash中输入git add . 41 | 42 | + 第六步:然后在本地执行提交操作git commit -m "//在这里面输入你的内容,比如:First commit." 43 | 44 | + Finally:将提交的内容同步到远程版本库,也就是GitHub上面:git push origin master 45 | 46 | ## 更新 47 | 48 | + 当需要更新已经上传的项目时,直接在已经写好的更新过的项目中 49 | 右键,点击Git Bash Here然后在命令行中输入: 50 | 51 | git pull + 地址 52 | 53 | + 上传跟新过之后,需要在命令行中输入git add .之后的步骤又是重复着之前的了然后在本地执行提交操作 54 | 55 | git commit -m "//在这里面输入你的内容,比如:First commit." 56 | 57 | + 最后将提交的内容同步到远程版本库,也就是Github上面: 58 | 59 | git push origin master 60 | 61 | > 小技巧: 62 | 63 | + 当仓库中的内容或者说提交次数过多的情况下,`.git`文件夹下所含有的内容是十分庞大的,因此可以使用如下命令只`拉取最近一次的提交`情况: 64 | 65 | **git clone --depth 1 + 地址** 66 | 67 | ## 删除所有提交记录并代码保持当前状态 68 | 69 | 以下是操作流程: 70 | 71 | + 尝试 运行:`git checkout --orphan latest_branch` --> 创建一个新的分支 72 | 73 | + 添加所有文件:`git add -A` --> 将目前所有内容添加到新的分支上 74 | 75 | + 提交更改:`git commit -am "commit message"` --> commit信息提交 76 | 77 | + 删除分支:`git branch -D master` --> 将master分支删除 78 | 79 | + 将当前分支重命名:`git branch -m master` --> 将当前分支的名字换成master 80 | 81 | + 最后,强制更新存储库:`git push -f origin master` 82 | -------------------------------------------------------------------------------- /数据结构/线性表/LinkedList/linkedDemo.java: -------------------------------------------------------------------------------- 1 | package linkedDemo_1; 2 | 3 | import static linkedDemo_1.RevSingleLinkFactory.reverse1; 4 | 5 | /** 6 | * Created by wwwww on 2017/11/4. 7 | */ 8 | public class LinkedDemo { 9 | public static void main(String[] args) { 10 | //带有头结点 11 | Node head = new Node(0); 12 | Node tmp = null; // 保存临时变量 13 | Node cur = null; // 始终指向末尾节点 14 | //构造一个长度为10的链表,保存头节点对象head 15 | //利用尾插入法 16 | for (int i = 1; i < 10; i++) { 17 | tmp = new Node(i); 18 | if (1 == i) { 19 | head.setNextNode(tmp); 20 | } else { 21 | cur.setNextNode(tmp); 22 | } 23 | cur = tmp; 24 | } 25 | //打印反转前的链表 26 | Node h = head; 27 | while (h !=null) { 28 | System.out.print(h.getRecord() + " "); 29 | h = h.getNextNode(); 30 | } 31 | //调用反转方法 32 | head = reverse1(head); 33 | System.out.println("\n*******************"); 34 | //打印反转后的结果 35 | while (head !=null) { 36 | System.out.print(head.getRecord() + " "); 37 | head = head.getNextNode(); 38 | } 39 | } 40 | } 41 | 42 | class Node 43 | //定义一个链表 44 | { 45 | private int record; 46 | private Node nextNode; 47 | 48 | public Node(int record) { 49 | this.record = record; 50 | } 51 | 52 | public int getRecord() { 53 | return record; 54 | } 55 | 56 | public void setRecord(int record) { 57 | this.record = record; 58 | } 59 | 60 | public Node getNextNode() { 61 | return nextNode; 62 | } 63 | 64 | public void setNextNode(Node node) { 65 | this.nextNode = node; 66 | } 67 | } 68 | 69 | /** 70 | * 两种方式实现单链表的反转(递归、普通) 71 | */ 72 | class RevSingleLinkFactory { 73 | /** 74 | * 递归,在反转当前节点之前先反转后续节点 75 | */ 76 | //最终传递一个指向最后一个节点的变量 77 | public static Node reverse1(Node head) { 78 | //当为空或者本节点为末尾节点的时候 79 | if (head == null || head.getNextNode() == null) 80 | return head; 81 | Node reversedHead = reverse1(head.getNextNode()); 82 | //获取先前的下一个节点,让该节点指向自身 83 | head.getNextNode().setNextNode(head); 84 | //破坏以前自己指向下一个节点 85 | head.setNextNode(null); 86 | //层层传递给最上面的 87 | return reversedHead; 88 | } 89 | 90 | /** 91 | * 遍历,将当前节点的下一个节点缓存后更改当前节点指针 92 | */ 93 | public static Node reverse2(Node head) { 94 | if (null == head) { 95 | return head; 96 | } 97 | Node pre = head; 98 | Node cur = head.getNextNode(); 99 | Node next; 100 | 101 | while (cur != null) { 102 | //断之前先找到原始的下一个节点 103 | next = cur.getNextNode(); 104 | //逆序连接 105 | cur.setNextNode(pre); 106 | //两个节点同时滑动 107 | pre = cur; 108 | cur = next; 109 | } 110 | //将原链表的头节点的下一个节点置为null,再将反转后的头节点赋给head 111 | head.setNextNode(null); 112 | head = pre; 113 | return head; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Android/App研发录/高效App框架设计与重构.md: -------------------------------------------------------------------------------- 1 | # 重构,夜未眠 2 | 3 | ## 为Activity定义新的生命周期 4 | 5 | 重点:`单一职责`->一个类或者方法,只做一件事情 6 | 7 | ### 重构一: 8 | 9 | + 原来的代码结构: 10 | 11 | ```java 12 | 13 | public class LoginActivity extends Activity implements View.onClickListener{ 14 | @Override 15 | protected void onCreate(Bundle saveInstanceState){ 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_main); 18 | 19 | Bundle bundle = getIntent().getExtras(); 20 | String strEmail = bundle.getString(AppConstants.Email); 21 | 22 | etEmail = (EditText) findViewById(R.id.email); 23 | etEmail.setText(strEmail); 24 | etPassword = (EditText) findViewById(R.id.password); 25 | 26 | //登录事件 27 | Button btnLogin = (Button) findViewById(R.id.sign_in_button); 28 | btnLogin.setOnClickListener(this); 29 | 30 | //获取2个MobileAPI,获取天气数据,获取城市数据 31 | loadWeatherData(); 32 | loadCityData(); 33 | } 34 | } 35 | 36 | ``` 37 | 38 | 从上面的Oncreate()方法中,可以看出,需要做的事情太多了,其实可以简化成三块: 39 | 40 | + initVariables 41 | 42 | + initViews 43 | 44 | + loadData 45 | 46 | 代码如下: 47 | 48 | ```java 49 | 50 | public abstract class BaseActivity extends Activity{ 51 | @Override 52 | protected void onCreate(Bundle saveInstanceState){ 53 | super.onCreate(savedInstanceState); 54 | 55 | initVariables(); 56 | initViews(savedInstanceState); 57 | loadData(); 58 | } 59 | 60 | protected abstract void initVariables(); 61 | protected abstract void initViews(Bundle savedInstanceState); 62 | protected abstract void loadData(); 63 | } 64 | 65 | ``` 66 | 67 | ### 重构二: 68 | 69 | 一般的,对点击事件的监听方式可以有以下两种: 70 | 71 | + 第一种: 72 | 73 | ```java 74 | 75 | public class LoginActivity extends Activity implements View.OnClickListener{ 76 | 77 | @Override 78 | protected void onCreate(Bundle savedInstanceState){ 79 | //省略代码 80 | 81 | Button btnLogin = (Button)findViewById(R.id.sign_in_button); 82 | btnLogin.setOnClickListener(this); 83 | } 84 | 85 | @Override 86 | public void onClick(View v){ 87 | switch(v.getId()){ 88 | case R.id.sign_in_button: 89 | Intent intent = new Intent(LoginActivity.this,PersonCenterActivity.class); 90 | startActivity(intent); 91 | } 92 | } 93 | } 94 | 95 | ``` 96 | 97 | + 第二种: 98 | 99 | ```java 100 | 101 | //登录事件 102 | btnLogin = (Button) findViewById(R.id.sign_in_button); 103 | btnLogin.setOnClickListener(new View.OnClickListener{ 104 | @Override 105 | public void onClick(View v){ 106 | getoLoginActivity(); 107 | } 108 | }); 109 | 110 | ``` 111 | 112 | 书中更推荐使用`第二种`方式进行实现,其给出的原因是: 113 | 114 | 第二种相比较于第一种: 115 | + 直接在btnLogin这个按钮对象上增加点击事件,是面向对象的写法。 116 | + 将onClick方面的实现,封装成一个gotoLoginActivity方法。 117 | 118 | ## 实体化编程 119 | 120 | 下面是一段糟糕的代码: 121 | 122 | ```java 123 | 124 | try{ 125 | JSONObject jsonResponse = new JSONObject(result); 126 | JSONObject weatherInfo = jsonResponse.getJSONObject("weatherInfo"); 127 | 128 | String city = weatherInfo.getString("city"); 129 | int cityId = weatherInfo.getInt("cityid"); 130 | }catch(JSONException e){ 131 | e.printStackTrace(); 132 | } 133 | 134 | ``` 135 | 136 | 有两个问题: 137 | 138 | + 根据key值取value,其可以看成是一个字典,容易产生bug。 139 | + 每次都要手动的从JSONObject或者JSONArray中取值,很烦琐。 -------------------------------------------------------------------------------- /数据结构/线性表/順序表的算法設計.md: -------------------------------------------------------------------------------- 1 | # 順序表的算法設計 2 | 順序表算法設計:數據採用順序表存儲,利用順序表的基本操作來完成求解任務。 3 | ## 例一: 4 | 已知長度為n的線性表A採用順序存儲結構。設計一個時間複雜度為O(n)、空間複雜度為O(1)的算法,該算法刪除線性表中所有值為X的數據元素。 5 | ### 注:以下兩種方法都是不滿足的: 6 | a)如果刪除一個值為x的元素都進行移動,其時間複雜度為O(n^2),空間複雜度為O(1)。 7 | b)如果藉助一個新的順序表,存放將A中所有不為x的元素,其時間複雜度為O(n),空間複雜度為O(n)。 8 | ### 解法一:設刪除A中所有值等于x元素后的顺序表为A1,显然A1包含在A中,為此A1重用A的空間。 9 | 思路:掃描順序表A,重建A只包含不等於x的元素。 10 | #### 對應的算法如下:(算法1類似於建立順序表) 11 | ```c 12 | void delnode1(SqList *&A,ElemType x) ---------------------------* 13 | { 14 | int k = 0,i; //k記錄值不等於x的元素個數 15 | for(i=0;ilength;i++) 16 | { 17 | if(A->data[i]!=x) //若當前元素不為x,將其插入A中 18 | { 19 | A->data[k]=a->data[i]; 20 | k++; //不等於x的元素增1 21 | } 22 | } 23 | A->length=k; //順序表A的長度等於k 24 | } 25 | ``` 26 | ### 解法二:用k記錄順序表A中等於x的元素個數,一邊掃描A一邊統計k值。 27 | 思路:將不為x的元素前移k個位置,最後修改A的長度。 28 | #### 對應的算法如下: 29 | ```c 30 | void delnode1(SqList *&A,ElemType x) ---------------------------* 31 | { 32 | int k = 0,i=0; //k記錄值等於x的元素個數 33 | while (ilength) 34 | { 35 | if(A->data[i]==x) //當前元素為x時k增加1 36 | k++; 37 | else //當前元素不為x時,將其前移k個位置 38 | A->data[i-k]=A->data[i]; 39 | i++; 40 | } 41 | A->length-=k; //順序表A的長度遞減k 42 | } 43 | ``` 44 | ## 例二: 45 | 設順序表L有10個整數。設計一個算法,以第一個元素為分界線(基準),將所有小於等於它的元素移到該元素的前面,將所有大於它的元素移到該元素的後面。 46 | ### 解法一: 47 | pivot = L->data[0]//(基准) 48 | j從後面往前面找<=pivot的元素 49 | i從前面往後面找>pivot的元素 50 | 然後兩者交換 51 | ![](http://p1.bpimg.com/567571/e8d752a1185f0a3b.png) 52 | #### 找到之後兩者交換 53 | ![](http://p1.bpimg.com/567571/cf3a2a40eb3d6e8b.png) 54 | #### 之後就開始第二輪循環,然後第三輪循環 55 | ### 算法的實現 56 | ```c 57 | void move1(SqList *&l) ---------------* 58 | { 59 | int i=0,j=L->length-1; 60 | ElemType tmp; 61 | ElemType pivot = L->data[0]; //以data[0]為基準 62 | while (idata[j]>pivot) 65 | { 66 | j--; //從後面向前面掃描,找一個小於等於pivot的元素 67 | } 68 | while (idata[i]<=pivot) 69 | { 70 | i++; //從前面向後掃描,找到一個大於pivot的元素 71 | } 72 | if(idata[i]; //L->data[i]與L->data[j]互換 75 | L->data[i]=L->data[j]; 76 | L->data[j]=tmp; 77 | } 78 | } 79 | tmp = L->data[0]; L->data[0]與L->data[j]互換 80 | L->data[0]=L->data[j]; 81 | L->data[j]=tmp; 82 | } 83 | ``` 84 | ### 解法二: 85 | pivot=L->data[0]//(基準) 86 | j從後面向前面找小於等於pivot的元素:前移 87 | i從前面向後找大於pivot的元素:後移 88 | 相當於把基準專門提取出來,然後排完序再放回去 89 | #### 將基準提出來 90 | ![](http://i1.piimg.com/567571/3024828b5fa5c6de.png) 91 | #### 將最後一位放置第一位 92 | ![](http://p1.bqimg.com/567571/346dd79638352ded.png) 93 | #### 然後再像解法一一樣進行排序 94 | ![](http://i1.piimg.com/567571/e32671e09e53db86.png) 95 | ### 這樣所得到的時間複雜度以及最終結果如圖 96 | ![](http://p1.bqimg.com/567571/28460c5dbc9c2680.png) 97 | ### 算法的實現 98 | ```c 99 | void move2(SqList *&L)---------------* 100 | { 101 | int i=0,j=L->length-1; 102 | ElemType pivot = L->data[0]; //以datap[0]為基準 103 | while (ii && L->data[j]>pivot) 106 | { 107 | j--; //從右向左掃描,找一個小於等於pivot的data[j] 108 | } 109 | L->data[i]=L->data[j]; //將其放入data[i]處 110 | while (idata[i]<=pivot) 111 | { 112 | i++; //從左向右掃描,找一個大於pivot的data[i] 113 | } 114 | L->data[j]=L->data[i]; //將其放入data[j]處 115 | } 116 | L->data[i]=pivot; //放置基準 117 | } 118 | ``` 119 | ### 為什麼解法二比解法一好: 120 | * 兩個記錄a、b交換:tmp=a;a=b;b=tmp; 需要3次移動 121 | * 多個相鄰記錄連續交換,如a、b、c: 122 | * 位置1和位置2的元素交換即:b、a、c 需要3次移動 123 | * 位置2和位置3的元素交換即:b、c、a 需要3次移動 124 | #### 一共6次移動 125 | ### 而採用: 126 | tmp=a;a=b;b=c;c=tmp; 4次移動 127 | #### 性能得到提高 128 | -------------------------------------------------------------------------------- /Ubuntu+Windows双系统安装指南.md: -------------------------------------------------------------------------------- 1 | # Ubuntu+Windows双系统安装指南 2 | 3 | >写在前面:非常感谢[Linux探索之旅](https://www.jianshu.com/c/01390ac22fa9)在最初的时候给我的安装教程的指南,自己按照这篇教程安装双系统折腾了将近一个月,期间更是将Windows也给装炸了。。。于是乎重装系统,直到现在可以稳定的使用Ubuntu和Windows双系统。 4 | 5 | --- 6 | 7 | - [Windows和Linux的区别](#Windows和Linux的区别) 8 | - [观念](#观念) 9 | - [发布](#发布) 10 | - [内核API](#内核API) 11 | - [Ubuntu系统安装](#Ubuntu系统安装) 12 | - [下载](#下载) 13 | - [烧录](#烧录) 14 | - [使用USB方式进行安装](#使用USB方式进行安装) 15 | 16 | --- 17 | 18 | 19 | 20 | ## Windows 和 Linux 的区别 21 | 22 | 对于 Windows 和 Linux 的区别,我在这里先使用一张直观的图让大家看一下。 23 | 24 | ![内核区别](https://img2018.cnblogs.com/blog/1410558/201903/1410558-20190305083814221-945937821.jpg) 25 | 26 | 从上图中可以看到,Linux 与苹果的 Mac OS 是基于 Unix 系统下的操作系统,而 Windows 是基于MS-DOS的操作系统。下面的几个部分的内容,将分析 Windows 和 Linux 系统的区别。 27 | 28 | ### 观念 29 | 30 | 商业模式与开源运作: 31 | 32 | 众所周知,Windows 是一款商业级的操作系统,它的源代码是保密的,这也就导致想要看到Windows的源代码变成了一件十分困难的事情。这使得微软授权过的《WINDOWS INTERNALS》一书变得十分的畅销,因为这里面涉及到了部分 Windows 操作系统内部的构建细节。 33 | 34 | 相对于 Linux 来说,Linux 是开源的,代码随时可见. 这对刚从 Windows 世界转过来的我是十分震撼的. 虽然我一直都知道这个事实, 但是当你发现了以前需要用尽各种方法,采用各种手段才可以得到只言片语的信息现在完全呈献在你面前的时候,你才能真正体会开源确实是一件伟大的工程。 35 | 36 | ### 发布 37 | 38 | 2进制与源代码: 39 | 40 | 这里所指的2进制与源代码是集中在两者操作系统中在安装程序中的不同之处。 41 | 42 | 在 Windows 世界,安装程序几乎全部都是以二进制形式发布的。也就是说,用户下载了一个程序,然后双击,一路 next 就可以了。这个方法很适合初学者。 43 | 44 | 在 Linux 世界也有类似的机制,比如 YUM , APT-GET 等。不过 YUM 和 APT-GET 都是比较晚才出现的,在那之前,在 Linux 世界安装程序要更麻烦些。 45 | 46 | ### 内核API 47 | 48 | 固定与非固定: 49 | 50 | Windows 内核有一套固定的 API ,而且向后兼容。这使得 Windows 驱动的开发人员在不同版本之间移植时变得很容易。 51 | 52 | 而 Linux 没有固定的内核API。2.4版本的内核模块在2.6几乎很大可能是不能兼容的。 53 | 54 | - 下面展示的是基于开源的 Linux 所分化出来的不同的分支系统。 55 | 56 | ![Linux分支](https://img2018.cnblogs.com/blog/1410558/201903/1410558-20190305083947874-1701950222.jpg) 57 | 58 | --- 59 | 60 | ## Ubuntu系统安装 61 | 62 | ### 下载 63 | 64 | Ubuntu的英文下载页面:[Ubuntu](http://www.ubuntu.com/download) 65 | 66 | Ubuntu的中文下载页面:[Ubuntu国内官网](https://cn.ubuntu.com/) 67 | 68 | 优麒麟的下载页面:[优麒麟](http://www.ubuntukylin.com/downloads/) 69 | 70 | 在这里,能够下载到的最新版本是18.04.2LTS(Long Term Support)版本。 71 | ![Ubuntu18.04下载](https://img2018.cnblogs.com/blog/1410558/201903/1410558-20190305090804692-434581225.png) 72 | 73 | ### 烧录 74 | 75 | 在电脑中插入一个空白的U盘(不空白也行,反正之后要格式化的),大小至少8GB。 76 | 77 | Universal USB Installer:[下载](https://www.pendrivelinux.com/universal-usb-installer-easy-as-1-2-3/) 78 | 79 | 下载好Universal USB Installer之后,打开它,在"Device"下拉菜单中选择你的U盘。然后点击创建。`对于右侧NTFS格式和Fat32格式,个人建议选择FAT32。` 80 | 81 | ![选择ISOs和Drive](https://img2018.cnblogs.com/blog/1410558/201903/1410558-20190305091852832-1065563335.png) 82 | 83 | ### 使用USB方式进行安装 84 | 85 | >前提:你需要先进入你的Boot Menu中,选择USB Storage Device。如下图所示: 86 | ![USB Storage Device](https://img2018.cnblogs.com/blog/1410558/201903/1410558-20190305092511043-1063454481.jpg) 87 | > 88 | >如果发现没有USB Storage Device,那么选择Setup进入BIOS,或者重启按F2进入BIOS。切换到Boot,选择Secure Boot Control回车,改成Disabled,USB Boot Support设置成Enabled,Boot Mode改成Legacy。如下图所示: 89 | > 90 | >![Secure Boot Control](https://img2018.cnblogs.com/blog/1410558/201903/1410558-20190305092636657-1945689688.jpg) 91 | 92 | 在进入到下图所示界面的时候(pure EFI Boot),这里就出现了一个坑。 93 | 94 | ![EFIBoot](https://img2018.cnblogs.com/blog/1410558/201903/1410558-20190305093615846-1061830699.jpg) 95 | 96 | 在这个时候,可以选择第一项,你可以先体验一下Ubuntu,也可不体验,直接Install Ubuntu。但是,在具有`独立显卡`的笔记本或者是台式机上,你会发现界面是能够进去的,但是很快就会卡死。这是因为独立显卡与Ubuntu的集成显卡不兼容所产生的问题。 97 | 98 | 这个时候,你需要再次回到pure EFI Boot界面,然后在`按E`进入到如图所示的界面: 99 | 100 | ![UbuntuNoModeSet](https://img2018.cnblogs.com/blog/1410558/201903/1410558-20190305094404291-535649607.jpg) 101 | 102 | 将原本`quiet splash`后面的内容修改为`nomodeset`。然后再`按F10`进入到安装界面安装即可。 103 | 104 | 在到 `安装类型` 这一步骤时,如果你在上一步压缩完分区后,没有新建简单卷(保持未分配状态),那么就只需选择 安装 Ubuntu,与 Windows boot manager 共存 这一选项,将分区相关事宜交由 Ubuntu 处理。 -------------------------------------------------------------------------------- /数据结构/线性表/线性表.md: -------------------------------------------------------------------------------- 1 | # 线性表的基本概念 2 | ## 线性表的定义 3 | 线性表是一个具有相同特性的数据元素的有限序列 4 | 5 | 相同特性:所有元素属于同一数据类型 6 | 有限:数据元素个数是有限的 7 | 序列:数据元素由逻辑序号唯一确定。一个线性表中可以有相同值的元素。 8 | 9 | 线性表中所含元素的个数叫做“线性表的长度”,用n表示,n>=0。n=0时,表示线性表是一个空表,即表中不包含任何元素。 10 | 11 | 线性表的逻辑表示为: 12 | (a1,a2,……ai,a(i+1),……,an) 13 | ai(1<=i<=n)表示第i(i表示逻辑为序)个元素。 14 | a1表示“表头元素”,an表示"表尾元素" 15 | 16 | ## 顺序表与顺序栈的区别 17 | * 顺序表中,你是要输入你的表长的,而且,输入的表长不可以超过你最初定义的MAX的值 18 | * 而顺序栈是已经给你开辟了最大值的MAX的存储空间,然后你只需要直接往里面输入数就行了,设定一个数为终止输入就行.例如: 19 | ```c 20 | printf("请输入需要往顺序栈中插入的元素(并且以输入-1结束):\n"); 21 | scanf("%d",&temp); 22 | while(temp!=-1) 23 | { 24 | push(&st1,temp); 25 | i++; 26 | scanf("%d",&temp); 27 | } 28 | printf("你一共输入了%d个数.",i); 29 | ``` 30 | * 当你的顺序栈自动的超过了你当初定义的MAX的值的时候,栈就会溢出 31 | ## 顺序表指针的引用 32 | ```c 33 | void CreateList(SqList *&L,ElemType a[],int n) 34 | ``` 35 | "&"引用參數:將執行結果回傳給實參 36 | 引用符號“&”放在形參L的前面 37 | 輸出型參數均為使用“&”,不論參數是否改變。* 38 | 39 | ## 初始化線性表InitList(L) 40 | 該運算的結果是構造一個空的線性表L。實際上只需要將length成員設置為0即可。 41 | ```c 42 | void InitList(SqList *&L){ 43 | L = (SqList*)malloc(sizeof(SqList)); 44 | //分配存放線性表的順序空間 45 | L->length=0; 46 | } 47 | ``` 48 | ## 銷毀一個線性表DestoryList(L) 49 | 該運算的結果是釋放線性表L佔用的內存空間。 50 | 51 | void DestoryList(SqList *&L) { 52 | free(L); 53 | // 54 | L指向順序表,free(L)釋放L所指向的空間 55 | }* 56 | 57 | ## 判定是否為空表ListEmpty(L) 58 | 該運算返回一個值表示L是否為空表。若L為空表,則返回true,否則返回false。 59 | 60 | bool ListEmpty(SqList *L) 61 | { 62 | 63 | }* 64 | ## 求線性表的長度ListLength(L) 65 | 66 | int ListLength(SqList *L) 67 | { 68 | return (L->length); 69 | }* 70 | ## 輸出線性表DispList(L) 71 | 該運算當線性表L不為空的時候,順序顯示L中各元素的值 72 | 73 | void DispList(SqList *L) { 74 | int i; 75 | if(ListEmpty(L)) return; 76 | for(i=0;ilength;i++) 77 | { 78 | printf("%c",L->data[i]); 79 | } 80 | printf("\n"); 81 | }* 82 | ## 求某個數據元素值GetElem(L,i,e) 83 | 該運算返回L中第i(1<=i<=ListLength(L))個元素的值,存放在e中 84 | 85 | bool GetElem(SqList *L,int i,ElemType &e) 86 | { 87 | if(i<1||i>L->length) return false; 88 | e=L->data[i-1]; 89 | return true; 90 | }* 91 | # 本算法的時間複雜度為O(1)。 92 | ## 體現順序表的隨機存取特性 93 | ## 按元素值查找LocateElem(L,e) 94 | 該運算順序查找第1個值域與e相等的元素的邏輯位序。若這樣的元素不存在,則返回值為0。 95 | 96 | int LocateElem(SqList *L,ElemType e) 97 | { 98 | int i=0; 99 | while (ilength&&L->data[i]!=e) { 100 | i++; 101 | } 102 | if(i>=L->length) return 0; 103 | else return i+1; 104 | }* 105 | # 删除数据元素ListDelete(L,i,e) 106 | 該運算刪除順序表L的第i(1<=i<=ListLength(L))個元素。{ 107 | # 刪除算法如下: 108 | ```c 109 | bool ListDelete(SqList *&L,int i,ElemType &e)* 110 | { 111 | int j; 112 | if(i<1||i>L->length)//參數錯誤時返回false 113 | { 114 | return false; 115 | } 116 | i--;//將順序表邏輯序號轉化為物理序號 117 | e=L->data[i]; 118 | for(j=i;jlength-1;j++)//將data[i…n-1]元素前移 119 | { 120 | L->data[j]=L->data[j+1]; 121 | } 122 | L->length--;//順序表長度減1 123 | return true;//成功刪除返回true 124 | } 125 | ``` 126 | 對於刪除算法來說,元素移動的次數也與表長n和刪除元素的位置i有關: 127 | 當i=n時,移動次數為0; 128 | 當i=1時,移動次數為n-1。(刪除算法最壞的時間複雜度為O(n)) 129 | ## 刪除算法的平均情況分析 130 | 在線性表L中共有n個可以刪除元素的地方 131 | 在刪除元素ai時,若為等概率情況,則pi=1/n 132 | 此時需要將a(i+1)~an的元素均前移一個位置,共移動n-(i+1)+1=n-i個元素 133 | 所以在長度為n的線性表中刪除一個元素所需移動元素的平均次數為(n-1)/2 134 | 因此刪除算法的平均時間複雜度為O(n)。 135 | # 插入算法 136 | 137 | ```c 138 | bool ListInsert(SqList *&L,int i,ElemType e) 139 | { 140 | int j; 141 | if(i<1||i>L->length+1) 142 | { 143 | return false; //參數錯誤時返回false 144 | } 145 | i--; //將順序表邏輯序號轉化為物理序號 146 | for(j=L->length;j>i;j--) //將data[i…n-1]元素後移一個位置 147 | L->data[i]=L->data[j-1]; 148 | L->data[i]=e; //插入元素e 149 | L->length++; //順序表長度增1 150 | return true; //成功插入返回true 151 | } 152 | ```* 153 | 對於插入算法來說,元素移動的次數不僅與表長L->length=n有關,而且,與插入位置i有關: 154 | (1)當i=n+1時,移動次數為0; 155 | (2)當i=1時,移動次數為n,達到最大值。//算法最壞時間複雜度為O(n) 156 | 157 | # 插入算法的平均情況分析 158 | 在線性表L中共有n+1個可以插入元素的地方。 159 | 在插入元素ai時,若為等概率情況,則pi=1/(n+1)。 160 | 此時需要將ai~an的元素均後移一個位置,共移動n-i+1個元素。所以在長度為n的線性表中插入一個元素所需移動元素的平均次數為:n/2。因此插入算法的平均時間複雜度為O(n)。 161 | -------------------------------------------------------------------------------- /JAVA学习/JAVA之封裝.md: -------------------------------------------------------------------------------- 1 | # JAVA之封装 2 | ### 1.面向对象程序设计的三大基本特征:继承(Inheritence)、封装(Encapsulation)、多态(Polymorphism) 3 | 4 | ### 2.封装:类包含了数据与方法,将数据与方法放在一个类中就构成了封装。 5 | 6 | ### 3.继承:继承是从已有的类中继承信息然后创建新类的过程。提供继承信息的被称为父类(亦或是超类(super class)、基类);得到继承的类是子类(派生类)。***`继承是封装程序中可变因素的重要手段。`*** 7 | 8 | ### 4.如何定义类? 9 | ``` 10 | 修饰符 class 类的名字 11 | 12 | { 13 | 14 | //类的內容(包含了属性与方法) 15 | 16 | } 17 | ``` 18 | ### 4.方法。如何定义方法? 19 | ``` 20 | 修饰符 返回类型 方法名称([参数 1, 参数 2, 参数 3…]) 21 | 22 | { 23 | 24 | //方法体 25 | 26 | } 27 | ``` 28 | ### 5.main 方法是整个 Java 程序的入口点,如果类的定义中没有 main 方法,则程序无法执行。 29 | 30 | ### 6.方法定义不能嵌套,也就说不能在一个方法中定义另外一个方法。方法只能定义在类中。 31 | 32 | ### 7.关于方法的执行:首先需要定義方法,接下來就可以使用方法(調用方法),當方法調用完畢後,方法可以返回值。方法到底是否返回值是由方法的定義決定的。 33 | 34 | ### 8.如何生成對象?通過類來生成對象(通常使用 new 關鍵字來生成對象)。 35 | ```java 36 | public class Person 37 | 38 | { 39 | 40 | } 41 | 42 | 类名 变量名 = new 类名(); 43 | 44 | Person person = new Person(); 45 | Person person2 = new Person(); 46 | Person person3 = new Person(); 47 | ``` 48 | ### 9.方法调用需要通过对象来完成,方法调用的形式是:对象变量.方法名([参数值 1, 参数值 2, 参数值 3….]); 49 | 50 | ### 10.关于方法的注意事项: 51 | 52 | 1) 在方法定义中,方法的返回类型与 return 后米娜的变量或常量类型保持一致。 53 | 54 | 2) 在方法调用时,給方法传递的参数需要与方法定义时的参数保持一致(参数个数一致,参数类型一致)。 55 | 56 | 3) 方法定义时的返回类型与接收方法返回值的变量类型保持一致。 57 | 58 | ### 11. 59 | ```Java 60 | public int add(int a, int b) 61 | 62 | { 63 | 64 | 65 | return a + b; 66 | 67 | } 68 | ``` 69 | 方法定義時的參數叫做形式參數。 70 | ```Java 71 | int a = test.add(8, 3); 72 | ``` 73 | 方法調用時所賦予的具體值叫做實際參數。 74 | 75 | ### 12.關鍵字 void 表示方法不返回值。 76 | 77 | ### 13.如果方法不返回值,那麼聲明方法的時候使用 void 關鍵字,在方法定義中可以有兩種情況實現不返回值: 78 | 79 | a)不使用 return 語句。 80 | 81 | b)使用 return,但 return 後面沒有任何值或者變數,return 後面只有一個分號,表示 82 | 83 | 退出方法,返回到方法的調用端。使用方式: 84 | 85 | return; 86 | 87 | ### 14.類中的屬性又叫做成員變數(member variable),屬性用英文表示為 property 或者attribute。 88 | 89 | ### 15.對象(Object)又叫做實例(Instance)。生成一個對象的過程又叫做實例化。 90 | 91 | ### 16.命名約定 92 | 93 | a)類:首字母大寫,如果一個類名由多個單詞構成,那麼每個單詞的首字母都大寫,中間不使用任何的連接符。比如 Person 類,MemberTest 類。 94 | 95 | b)方法:首字母小寫。如果一個方法由多個單詞構成,那麼第一個單詞的所有字母全都小寫,從第二個單詞開始,每個單詞的首字母大寫。比如 add,addThreeInt。 96 | 97 | c)屬性:命名約定與方法相同。比如 age,ageOfPerson。 98 | 99 | ### 17.屬性需要定義在類中,又叫做成員變數;而定義在方法中的變數叫做局部變數。 100 | 101 | ### 18.如何定義屬性? 102 | ```Java 103 | public class Person 104 | 105 | { 106 | 107 | 修飾符 類型 屬性名稱; 108 | 109 | } 110 | ``` 111 | 如何使用屬性?與方法一樣,使用.運算符。首先需要生成類的實例,然後使用實例+”.”的方式來使用屬性。 112 | 113 | 比如: 114 | ```Java 115 | Person person = new Person(); person.age 116 | ``` 117 | ### 19.局部變數使用前必須要聲明並賦初值;成員變數使用前必須要聲明,但可以不賦初值。 118 | 119 | ### 20.成員變數與局部變數的聯繫與區別: 120 | 121 | a)無論是成員變數還是局部變數,使用前都需要聲明(定義)。 122 | 123 | b)對於局部變數來說,使用前必須要初始化;對於成員變數來說,使用前可以不初始化。如果沒有初始化成員變數就開始使用,那麼每個類型的成員變數都有一個默認的初始值 124 | 125 | i.byte、short、int、long 類型的初始值為 0 126 | 127 | ii.float、double 類型的初始值為 0.0 128 | 129 | iii.char 類型的初始值‘\u0000’ 130 | 131 | iv.boolean 類型的初始值為 false 132 | 133 | ### 21.引用類型(reference type):引用類型是用在對象上的。一個對象可以被多個引用所指向,但同一時刻,每個引用只能指向唯一的一個對象。如果一個對象被多個引用所指向,那麼無論哪個引用對對象的屬性進行了修改,都會反映到其他的引用當中。 134 | 135 | ### 22.如果一個類包含了屬性與方法,那麼該類的每一個對象都具有自己的屬性,但無論一個類有多少個對象,這些對象共用同一個方法。 136 | 137 | ### 23.關於方法參數傳遞的總結:對於 Java 中的方法參數傳遞,無論傳遞的是原生數據類型還是引用類型,統一是傳值(pass by value)。 138 | 139 | ### 24.什麼類型的引用就能指向什麼類型的對象,比如 People 類型的引用就能指向 People 類型的對象,但不能指向 Student 類型的對象。比如: 140 | ```Java 141 | People people = new People(); // 正確 People people = new Student(); //錯誤 142 | ``` 143 | ### 25.構造方法(Constructor):構造方法用於完成對象屬性的初始化工作,構造方法的特點: 144 | 145 | a)構造方法的名字必須與類名完全一致(包含大小寫) 146 | 147 | b)構造方法沒有返回值,連 void 也不能出現。 148 | 149 | c)如果在定義一個類的時候,沒有為類聲明構造方法,那麼 Java 編譯器會自動為類添加一個沒有參數且方法體為空的構造方法(默認的構造方法) 150 | 151 | d)如果在定义一個类的时候,为类声明了构造方法,那么 Java 编译器就不会再为类添加构造方法了。 152 | 153 | e)不能显式调用类的构造方法,构造方法通常是通过 new 关键字隐式调用。 154 | 155 | ### 26.new 关键字在生成对象时完成了三件事情: 156 | 157 | a)为对象开辟记忆体空间。 158 | 159 | b)调用类的构造方法。 160 | 161 | c)将生成的对象的地址返回。 162 | 163 | ### 27.默认的构造方法:构造方法沒有参数且方法体为空。 164 | 165 | ### 28.使用 new 来生成对象的时候,后面的小括弧()表示构造方法的参数列表,如果构造方法不接收参数,那么小括弧中的内容为空;如果构造方法接收参数,那么小括弧中的实际参数就需要与构造方法定义中的形式参数保持一致(参数数量一致、参数类型一致、按照顺序逐一赋值)。 166 | -------------------------------------------------------------------------------- /C&C++/C++_正则表达式.md: -------------------------------------------------------------------------------- 1 | # 正则表达式 2 | 3 | 正则表达式是一种字符串匹配的一种模式,可以用于检测一个字符串是否包含某串、将匹配的字符串进行替换或者从一个字符串中提取符合某个条件的的子串等等 4 | 5 | `注:`在C++中使用正则表达式进行字符串操作的时候,需要添加头文件 **```#include```** 6 | 7 | ## 正则表达式中匹配的字符 8 | 9 | ### 特殊字符 10 | 11 | | 特别字符 | 描述 | 12 | | ---- | ---- | 13 | | $ | 匹配输入字符串的结尾位置 | 14 | | ( ) | 标记一个子表达式的开始和结束位置 | 15 | | * | 匹配前面的子表达式零次或多次 | 16 | | + | 匹配前面的子表达式一次或多次 | 17 | 18 | 19 | ### 限定符 20 | 21 | | 字符 | 描述 | 22 | | ---- | ---- | 23 | | * | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,} | 24 | | + | 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,} | 25 | | ? | 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1} | 26 | | {n} | n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o | 27 | | {n,} | n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*' | 28 | | {n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格 | 29 | 30 | ## regex_match 31 | + match为全文匹配,要求整个字符串符合匹配规则。 32 | + 返回值为bool值,匹配成功返回1。 33 | 34 | ```C++ 35 | #include 36 | #include 37 | using namespace std; 38 | int main(){ 39 | cout << regex_match("123", regex("\\d")) << endl; //结果为0 40 | cout << regex_match("123", regex("\\d+")) << endl; //结果为1 41 | return 0; 42 | } 43 | ``` 44 | 45 | + `\d`:匹配一个数字字符 46 | + `+` :匹配一次或多次 47 | 48 | regex_match函数还有一种重载方式:regex_match(str, result, pattern)。示例如下所示: 49 | ```C++ 50 | #include 51 | #include 52 | using namespace std; 53 | int main(){ 54 | string str = "Hello_2018"; 55 | smatch result; 56 | regex pattern("(.{5})_(\\d{4})"); //匹配5个任意单字符 + 下划线 + 4个数字 57 | 58 | if (regex_match(str, result, pattern)) 59 | { 60 | cout << result[0] << endl; //完整匹配结果,Hello_2018 61 | cout << result[1] << endl; //第一组匹配的数据,Hello 62 | cout << result[2] << endl; //第二组匹配的数据,2018 63 | cout<<"结果显示形式2"< 85 | #include 86 | using namespace std; 87 | int main(){ 88 | string str = "Hello 2018, Bye 2017"; 89 | smatch result; 90 | regex pattern("\\d{4}"); //匹配四个数字 91 | 92 | //迭代器声明 93 | string::const_iterator iterStart = str.begin(); 94 | string::const_iterator iterEnd = str.end(); 95 | string temp; 96 | while (regex_search(iterStart, iterEnd, result, pattern)) 97 | { 98 | temp = result[0]; 99 | cout << temp << " "; 100 | iterStart = result[0].second; //更新搜索起始位置,搜索剩下的字符串 101 | } 102 | return 0; 103 | } 104 | 105 | 106 | 输出结果:2018 2017 107 | ``` 108 | ## regex_replace 109 | 110 | + replace是替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串 111 | ```C++ 112 | #include 113 | #include 114 | using namespace std; 115 | int main(){ 116 | string str = "Hello_2018!"; 117 | regex pattern("Hello"); 118 | cout << regex_replace(str, pattern, "") << endl; //输出:_2018,将Hello替换为"" 119 | cout << regex_replace(str, pattern, "Hi") << endl; //输出:Hi_2018,将Hello替换为Hi 120 | return 0; 121 | } 122 | 123 | ``` 124 | 125 | + 除了直接替换以外,还有可以用来调整字符串内容(缩短、顺序等) 126 | 127 | ```C++ 128 | #include 129 | #include 130 | using namespace std; 131 | int main(){ 132 | string str = "Hello_2018!"; 133 | regex pattern2("(.{3})(.{2})_(\\d{4})"); //匹配3个任意字符+2个任意字符+下划线+4个数字 134 | cout << regex_replace(str, pattern2, "$1$3") << endl; //输出:Hel2018,将字符串替换为第一个和第三个表达式匹配的内容 135 | cout << regex_replace(str, pattern2, "$1$3$2") << endl; //输出:Hel2018lo,交换位置顺序 136 | return 0; 137 | } 138 | ``` 139 | `注:` $n用于表示第n组匹配数据 140 | -------------------------------------------------------------------------------- /C&C++/C语言培训.md: -------------------------------------------------------------------------------- 1 | # 10.14 c语言培训 2 | 3 | ### 8:00 - 12:00 4 | 5 | + **面试题目考察** 6 | + 代码编写规范 7 | - 标识符命名规范:标识符只能由字母(A~Z, a~z)、数字(0~9)和下划线_组成,并且第一个字符必须是字母或下划线 8 | ```c 9 | #include 10 | int main() 11 | { 12 | printf("Hello World\n"); 13 | return 0; 14 | } 15 | ``` 16 | + 顺序结构: 17 | + 基本数据类型 18 | - ![](./image/c_language.png) 19 | - `char, short, int, long int, float, double` 20 | - 基本数据类型所占直接数与三个方面因素有关: 21 | - CPU位宽(即你的CPU是多少位的) 22 | - 操作系统位宽(笼统说就是操作系统位数,操作系统位宽取决于CPU位宽) 23 | - 编译器类型和版本 24 | 25 | 26 | 数据类型 | 所占字节数 | 取值范围 27 | ------------ | ------------- | ------------- 28 | short | 2 | -32768~32767,即 -215~(215-1) 29 | unsigned short | 2 | 0~65535,即 0~(216-1) 30 | int | 4 | -2147483648~2147483647,即 -231~(231-1) 31 | unsigned int | 4 | 0~4294967295,即0~(232-1) 32 | long | 4 | -2147483648~2147483647,即 -231~(231-1) 33 | unsigned long | 4 | 0~4294967295,即0~(232-1) 34 | - [c语言中有符号和无符号数据类型的区别](http://blog.csdn.net/gogokongyin/article/details/39758289) 35 | - 关系运算符 36 | 37 | 关系运算符 | 含义 38 | ------- | -------- 39 | < | 小于 40 | <= | 小于或等于 41 | > | 大于 42 | >= | 大于或等于 43 | == | 等于 44 | != | 不等于 45 | 46 | - 逻辑运算符 47 | 48 | 49 | 运算符 | 说明 50 | ------- | -------- 51 | && | 与运算,双目,对应数学中的“且” 52 | ``||`` |或运算,双目,对应数学中的“或” 53 | ! | 非运算,单目,对应数学中的“非” 54 | 55 | - 转义字符 56 | - `\n, \t,\0` 57 | - i++与++i的区别 58 | - ++ 在前面叫做前自增(例如 ++a)。前自增先进行自增操作,再进行其他操作。 59 | - ++ 在后面叫做后自增(例如 a++)。后自增先进行其他操作,再进行自增操作。 60 | - 自减(--)也一样,有前自减和后自减之分。 61 | - 自增自减完成后,会用新值替换旧值,并将新值保存在当前变量中。自增自减只能针对变量,不能针对数字 62 | - 输入输出 63 | - `getchar()` 和 `putchar()` : 字符的输入输出 64 | - `gets()` 和 `puts()` : 字符串的输入输出 65 | - `scanf()` 和 `printf()` : 可以输入输出各种类型的数据 66 | 67 | 数据类型 | 输出格式 68 | ---- | ----- 69 | int | %d 70 | long int | %ld 71 | char | %c 72 | float | %f 73 | double | %lf 74 | 八进制整数 | %o 75 | 指针 | %p 76 | 无符号十进制整数 | %u 77 | - 常量 78 | - `const int max = 100;` 79 | - const与define所申明的是有区别的。const只是将变量申明成只读的。 80 | - ``#define MAX 100`` (宏定义) 81 | - 数值宏常量:例如: ` #define a 10 ` (注意,中间是有空格的) 82 | - `#define`替换:在调用宏时,首先对其参数检查,如果参数又包含`#define`定义的符号,则会被替换。 83 | - `#undef`用于移除一个宏定义 84 | - 变量 85 | - `int a = 1;` 86 | ****** 87 | + 选择结构: 88 | - if-else语句 89 | ``` 90 | if(判断条件) 91 | { 92 | //真 to-do 93 | } 94 | else 95 | { 96 | //假 to-do 97 | } 98 | ``` 99 | - switch语句 100 | ``` 101 | switch(表达式) 102 | { 103 | case 数字/单个字符: 104 | // to-do 105 | break; 106 | case 数字/单个字符: 107 | // to-do 108 | break; 109 | default: 110 | // to-do 111 | break; 112 | } 113 | ``` 114 | - 三目运算符 : 115 | `判断条件 ? 真 : 假;` 116 | ****** 117 | ` 请编写一个程序,它的功能是:计算三位整数中的各位数字之和。输入一个三位整数,函数返回各位数字之和。` 118 | ****** 119 | + 循环结构: 120 | - while循环 121 | ``` 122 | while(表达式) 123 | { 124 | // to-do 125 | } 126 | ``` 127 | - do-while循环 128 | ``` 129 | do 130 | { 131 | // to-do 132 | }while(表达式); //do-while后面要加分号 133 | ``` 134 | - for循环 135 | ``` 136 | for(循环变量的初始化; 循环判断条件; 循环递增条件) 137 | { 138 | // to-do 139 | } 140 | ``` 141 | - **什么时候用whlie或do-while:** 142 | 1. 循环次数不确定 143 | 2. 循环的改变不是递增或递减 144 | - continue和break的区别 145 | - `continue` **结束本次** 循环,进行下一次循环 146 | `break` **终止** 循环不再进行 147 | ****** 148 | ** ` 请编写一个程序,它的功能是:统计素数的个数。输入一个自然数n(n在100到10000之间),函数返回100到n之间(包括n)素数的个数。` ** 149 | ****** 150 | ### 14:00~17:00 151 | 152 | + 数组: 153 | - 一维和二维数组 154 | 155 | + 函数: 156 | - 形参与实参 157 | 158 | - 递归的使用 159 | 160 | + 综合运用练习 161 | 162 | + 指针的简单使用 163 | 164 | + 结构体 165 | 166 | + 文件的简单使用 167 | 168 | + 综合练习(如果讲的完,带你们写写我去年的C语言小题库) 169 | 170 | __*附加:*__ 171 | 172 | >github的简单使用 173 | 174 | >markdown语法 175 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # STUDY_NOTE 2 | ## Android 3 | * [生命周期分析](https://github.com/kentanvictor/STUDY/blob/master/Android/%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%9A%84%E5%88%86%E6%9E%90.md) 4 | * [Activity启动模式](https://github.com/kentanvictor/STUDY/blob/master/Android/Android%E5%BC%80%E5%8F%91%E8%89%BA%E6%9C%AF%E6%8E%A2%E7%B4%A2/Activity%E5%90%AF%E5%8A%A8%E6%A8%A1%E5%BC%8F.md) 5 | ## JAVA学习 6 | * [ArrayList与LinkedList](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/ArrayList%E4%B8%8ELinkedList.md) 7 | * [IDE的详细介绍](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/IDE%E7%9A%84%E8%AF%A6%E7%BB%86%E4%BB%8B%E7%BB%8D.md) 8 | * [Java数组查找方式以及二分查找剖析](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/Java%E6%95%B0%E7%BB%84%E6%9F%A5%E6%89%BE%E6%96%B9%E5%BC%8F%E4%BB%A5%E5%8F%8A%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE%E5%89%96%E6%9E%90.md) 9 | * [冒泡排序的JAVA实现](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F%E7%9A%84java%E5%AE%9E%E7%8E%B0.md) 10 | * [String类源代码深析](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/String%E7%B1%BB%E6%BA%90%E4%BB%A3%E7%A0%81%E6%B7%B1%E6%9E%90.md) 11 | * [String类陷阱深度解析](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/String%E7%B1%BB%E9%99%B7%E9%98%B1%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90.md) 12 | * [Object类详解](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/Object%E7%B1%BB%E8%AF%A6%E8%A7%A3.md) 13 | * [包与导入语句的剖析](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/%E5%8C%85%E4%B8%8E%E5%AF%BC%E5%85%A5%E8%AF%AD%E5%8F%A5%E7%9A%84%E5%89%96%E6%9E%90.md) 14 | * [访问控制符详解](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6%E7%AC%A6%E8%AF%A6%E8%A7%A3.md) 15 | * [面向对象](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1.md) 16 | * [JAVA学习之接口_static_final等关键字](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/JAVA%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%8E%A5%E5%8F%A3_static_final%E7%AD%89%E5%85%B3%E9%94%AE%E5%AD%97.md) 17 | * [JAVA学习之单例模式](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/JAVA%E5%AD%A6%E4%B9%A0%E4%B9%8B%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F.md) 18 | * [JAVA之封装](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/JAVA%E4%B9%8B%E5%B0%81%E8%A3%9D.md) 19 | * [运算符](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/%E8%BF%90%E7%AE%97%E7%AC%A6.md) 20 | * [原生数据类型](https://github.com/kentanvictor/STUDY/blob/master/JAVA%E5%AD%A6%E4%B9%A0/%E5%8E%9F%E7%94%9F%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.md) 21 | 22 | 23 | ## 数据结构 24 | * [数据结构绪论](https://github.com/kentanvictor/STUDY/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%BB%AA%E8%AE%BA/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%BB%AA%E8%AE%BA.md) 25 | * [数据中的结构](https://github.com/kentanvictor/STUDY/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%BB%AA%E8%AE%BA/%E6%95%B0%E6%8D%AE%E4%B8%AD%E7%9A%84%E7%BB%93%E6%9E%84.md) 26 | * [数据](https://github.com/kentanvictor/STUDY/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%BB%AA%E8%AE%BA/%E6%95%B0%E6%8D%AE.md) 27 | * [线性表](https://github.com/kentanvictor/STUDY/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%BA%BF%E6%80%A7%E8%A1%A8/%E7%BA%BF%E6%80%A7%E8%A1%A8.md) 28 | * [顺序表的算法设计](https://github.com/kentanvictor/STUDY/blob/master/%E6%95%B8%E6%93%9A%E7%B5%90%E6%A7%8B/%E7%B7%9A%E6%80%A7%E8%A1%A8/%E9%A0%86%E5%BA%8F%E8%A1%A8%E7%9A%84%E7%AE%97%E6%B3%95%E8%A8%AD%E8%A8%88.md) 29 | * [流程控制语句](https://github.com/kentanvictor/STUDY/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6%E8%AF%AD%E5%8F%A5.md) 30 | * [枚举-讨厌的青蛙](https://github.com/kentanvictor/STUDY/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%9E%9A%E4%B8%BE-%E8%AE%A8%E5%8E%8C%E7%9A%84%E9%9D%92%E8%9B%99.md) 31 | 32 | ## MATLAB 33 | * [MATLAB概述](https://github.com/kentanvictor/STUDY/blob/master/MATLAB%E7%9A%84%E4%BD%BF%E7%94%A8/MATLAB%E6%A6%82%E8%BF%B0.md) 34 | 35 | ## 杂项 36 | * [Git](https://github.com/kentanvictor/STUDY/blob/master/Git.md) 37 | -------------------------------------------------------------------------------- /前端/HTML.md: -------------------------------------------------------------------------------- 1 | # HTML+CSS 2 | 3 | * 外壳的框架 4 | 5 | ```html 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ``` 17 | 18 | * < p >段落文本< /p > 19 | 20 | **一个< p >代表一个段落,这个是插入段落文本用的** 21 | 22 | **** 23 | * < hx >标题文本< /hx >(x为1~6) 24 | 25 | 26 | **hx中的x表示标签字号的大小,h1位最大,h6为最小** 27 | **** 28 | * < em >斜体标签< /em > 29 | * < strong >粗体标签< /strong > 30 | 31 | **在这两个标签中都是需要强调的文本,只不过这两种标签所强调出来的样式不一样,但是可以两者结合在一起使用** 32 | 33 | **** 34 | * < span >标签< /span > 35 | 36 | **< span >标签是没有语义的,它的作用就是为了设计单独的样式用的,相当于自定义CSS** 37 | >* aqua 浅绿色 38 | * black 黑色 39 | * blue 蓝色 40 | * fuchsia 紫红色 41 | * gray 灰色 42 | * green 绿色 43 | * lime 绿黄色 44 | * maroon 栗色 45 | * navy 深蓝色 46 | * olive 橄榄色 47 | * purple 紫色 48 | * red 红色 49 | * silver 银白色 50 | * teal 蓝绿色 51 | * white 白色 52 | * yellow 黄色 53 | 54 | >***如果使用其它颜色的话,就应该使用十六进制的颜色值*** 55 | 56 | **< em >< /em >和< strong >< /strong >标签是为了强调一句话中的关键作用,它们的语义是强调** 57 | 58 | **< strong >< /strong >和< b >< /b > 一样用法,语义是强调** 59 | 60 | **** 61 | 62 | * < q >标签,短文本引用 63 | ```html 64 | 引用文本 65 | ``` 66 | 67 | **就像引用别人说的话一样,为了标注,则需要加双引号,但是需要< q >< /q >这样的引用** 68 | 69 | **并且这种引用的文本是不需要加**双引号**的,浏览器会对q标签自动添加双引号** 70 | 71 | >添加< q >之前,浏览器只知道一段文字和一些双引号在里面。 72 | >>添加< q >之后,浏览器知道这里是一段引用。 73 | >>>如果浏览器有自己的优化(如对老人增大引用的字体及对其加粗),或者你在CSS中安排了格式,这部分就有意义了。 74 | 75 | **** 76 | * < blockquote >< /blockquote > 77 | >转指对长文本的引用,这个标签的解析是**缩进样式** 78 | 79 | **这个与上面的< q >< /q >不一样的地方是:第一、这个是用来表示引用长文本的;第二、这个是不会自动添加双引号,但是会缩进样式。(而< q >< /q >是不会缩进样式的)** 80 | 81 | **** 82 | * < br >标签分行显示文本 83 | >用一个< br >< /br >就像是回车一样,进行了换行。
84 | >这就意味着你在HTML代码中输入回车、空格都是没有作用的。在HTML文本中想要输入回车换行就必须输入< br >
85 | >而< pre >< /pre >可以保留文本中的空格和回车 86 | 87 | **** 88 | * 输入 & n b s p;就会在html中显示空格 89 | **** 90 | * 输入< hr/ >就是用来添加水平线的 91 | **** 92 | * < address >标签,为网页加入地址信息 93 | >一般网页中会有一些网站的联系地址信息需要在网页中展示出来,这些联系地址信息如公司的地址就可以< address >标签。也可以定义一个地址(比如电子邮件地址)、签名或者文档的作者身份。 94 | **** 95 | * < code >< /code >进行添加代码 96 | >目的是防止浏览器误认为是需要执行的代码,加了标签,浏览器就不会执行了
这种只能添加一行代码,如果需要添加多行,就不能使用< code >标签,而需要使用< pre > 97 | **** 98 | * 使用< ul >添加新闻信息列表 99 | >模板: 100 | ```html 101 |
    102 |
  • 信息
  • 103 |
  • 信息
  • 104 |
  • 信息
  • 105 | …… 106 |
107 | ``` 108 | **** 109 | * 使用< ol >添加列表标签序号 110 | >这种与上面的区别就在于,下面的这一种就是由序号的,而上面的只有一个点
111 | ```html 112 |
    113 |
  1. 信息
  2. 114 |
  3. 信息
  4. 115 | ...... 116 |
117 | ``` 118 | **** 119 | * < div >< /div >标签在排版中的作用 120 | >一个html页面可以看成一个家,而一个div你们可以看成家的每个小房间,房间有了当然没什么效果,但是一个家必须分成一个个小房间才能多姿多彩,但每个房间里怎么装饰就得你们自己放东西,当然装饰就得交给css了。 121 | **** 122 | * table标签写表格 123 | >用如下代码实现表格: 124 | ```html 125 | 126 | 127 | 128 | 129 | 认识table表标签 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 |
班级学生数平均成绩
一班3089
二班3585
三班3280
156 | 157 | 158 | ``` 159 | 上面的代码实现的样子就像下面的样子一样: 160 | 161 | ![table](../image/table.png) 162 | **** 163 | 164 | *

上面的代码可以添加一个CSS样式进行表格的变换

165 | 166 | ```html 167 | 为表格添加边框 168 | 171 | ``` 172 | 173 | **** 174 | 175 | * summary与caption用来添加标题与摘要 176 | 177 | >< table summary="摘要的内容">
178 | >上面的summary添加的摘要与在html中添加注释的效果是一样的,目的是为了给程序员看,防止表格太多改错了。
179 | >< caption >标题文本< /caption >
180 | >上面的就是给表格添加标题(表头)的 181 | **** 182 | * < a >标签使用的超链接 183 | >使用 184 | ```html 185 | 连接显示的文本 186 | ``` 187 | >href:Hypertext Reference的缩写。意思是超文本引用。
188 | >title属性的作用,鼠标滑过链接文字时会显示这个属性的文本内容。
189 | >注:只要文本加入a标签之后,文字的颜色就会自动变成蓝色(点击之后的文本颜色会变成紫色) 190 | -------------------------------------------------------------------------------- /Android/AudioSystem相关.md: -------------------------------------------------------------------------------- 1 | 音频系统主要分为连个部分:`数据流`和`策略`。 2 | 3 | + `数据流:` **AudioTrack**,**AudioFlinger**就是数据流,描述了音频数据从数据源流向目的地的流程。 4 | 5 | + `策略:` **AudioPolicyService**,**AudioService**都是策略的范畴,管理及控制数据流的路径与呈现方式。 6 | 7 | | | Audio管理环节 | Audio输出 | Audio输入 | 8 | | ---- | ---- | ---- | ---- | 9 | | Java层 | android.media.AudioSystem | android.media.AudioTrack | android.media.AudioRecorder | 10 | | 本地框架层 | AudioSystem | AudioTrack | AudioRecorder | 11 | | AudioFlinger | IAudioFlinger | IAudioTrack | IAudioRecorder | 12 | | 硬件抽象层 | AudioHardwareInterface | AudioSteamOut | AudioStreamIn | 13 | 14 | 总通信方式大致如下: 15 | ![android通信方式](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/android%E9%80%9A%E4%BF%A1%E6%96%B9%E5%BC%8F.png?raw=true) 16 | 17 | Android音频系统的`核心`是Audio系统 18 | 19 | ![Audio系统框架结构](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/Audio%E7%B3%BB%E7%BB%9F%E6%A1%86%E6%9E%B6%E7%BB%93%E6%9E%84.png?raw=true) 20 | 21 | 在Java层中,AudioSystem的最上层是AudioService、AudioSystem进行着Audio相关的管理,下面是AudioService.java所在的路径。 22 | 23 | ![AudioService路径](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/AudioService%E8%B7%AF%E5%BE%84.png?raw=true) 24 | 25 | 以其中一个为例子,isAudioServerRunning方法用来判断音频系统是否工作,可以看到,中间的checkMonitorAudioServerStatePermission()方法是用来判断是否给予权限,而实际上的判断语句是return后面`AudioSystem.checkAudioFlinger`进行比较的。 26 | 27 | ![AudioService中方法](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/AudioService%E4%B8%AD%E6%96%B9%E6%B3%95.png?raw=true) 28 | 29 | 使用OpenGrok,我们可以追踪到AudioSystem.java文件所在的路径。 30 | 31 | ![AudioSystem路径](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/AudioSystem%E8%B7%AF%E5%BE%84.png?raw=true) 32 | 33 | 在该类中,我们可以发现,其通过JNI的方式,声明了checkAudioFlinger()的方法。我们就可以通过该方法去JNI层去寻找C++中实现的类。 34 | 35 | ![AudioSystem中checkAudioFlinger](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/AudioSystem%E4%B8%ADcheckAudioFlinger.png?raw=true) 36 | 37 | 可以看到,在`core/jni/`的包下,有一个android_media_AudioSystem.cpp的对应的文件进行实现JNI层提供的checkAudioFlinger()的接口。 38 | 39 | `问:`Java中如何通过方法名就能够找到native层中的函数呢? 40 | 41 | `答:`native层的函数名遵循如下规则:**Java_包名_类名_方法名** 42 | 43 | ![android_media_AudioSystem路径](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/android_media_AudioSystem%E8%B7%AF%E5%BE%84.png?raw=true) 44 | 45 | 在android_media_AudioSystem.cpp中具体的实现方法如下: 46 | 47 | ![android_media_AudioSystem实现方式](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/android_media_AudioSystem%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F.png?raw=true) 48 | 49 | 可以看到其中的具体实现是`check_AudioSystem_Command()`函数中实现的, 然后传入了AudioSystem中的CheckAudioFlinger()函数的返回值。下图显示的是AudioSystem类中的checkAudioFlinger()函数的实现。 50 | + NO_ERROR = 0 51 | 52 | ![checkAudioFlinger()方法](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/checkAudioFlinger()%E6%96%B9%E6%B3%95.png?raw=true) 53 | 54 | 从`check_AudioSystem_Command()`函数中可以看到最终也是返回一个状态值。 55 | 56 | ![check_AudioSystem_Command()](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/check_AudioSystem_Command().png?raw=true) 57 | 58 | defaultServiceManager()是一个位于binder下IServiceManager.cpp中的一个函数 59 | 60 | ![defaultServiceManager智能指针](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/defaultServiceManager%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88.png?raw=true) 61 | 62 | `注:` sp指的是shared_ptr,C++11后推出的智能指针的概念。shared_ptr是实现共享式拥有概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放。 63 | 64 | ### 总结 65 | 66 | 以上只是一种从上层Java层一路追溯到native层中C++的实现方式。而这也侧面的证明了Java层与native层的数据通信的方式是通过Binder实现的。 67 | 68 | 在native层中的AudioSystem.cpp中就属于一个中间件的作用,进行了承上启下,在AudioSystem.cpp中,有AudioFlinger相关的智能指针,如下图所示: 69 | 70 | ![AudioSystem中与AudioFlinger相关指针](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/AudioSystem%E4%B8%AD%E4%B8%8EAudioFlinger%E7%9B%B8%E5%85%B3%E6%8C%87%E9%92%88.png?raw=true) 71 | 72 | + gAudioFlinger作为AudioFlinger的代理端句柄可以输入输出设备进行相关控制。 73 | 74 | ![get_audio_policy_service函数](https://github.com/kentanvictor/STUDY/blob/Image/JNI%E5%88%B0native%E7%9A%84AudioSystem%E8%B4%AF%E9%80%9A/get_audio_policy_service%E5%87%BD%E6%95%B0.png?raw=true) 75 | 76 | + gAudioPolicyService作为AudioPolicyService服务代理端的句柄提可以对策略相关业务流程进行调度。 -------------------------------------------------------------------------------- /数据结构/线性表/Arraylist/Sequence.java: -------------------------------------------------------------------------------- 1 | package com.dell.example.linearlist; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Scanner; 5 | 6 | /* 7 | * Created by JohnnyTan on 2017/10/2. 8 | */ 9 | public class Sequence { 10 | public static void main(String[] args) { 11 | int i; 12 | SLType SL = new SLType();//定义顺序表变量 13 | Data pdata;//定义结点保存引用变量 14 | String key;//保存关键字 15 | System.out.println("顺序表操作演示!\n"); 16 | SL.Init(SL);//初始化顺序表 17 | System.out.println("初始化顺序表完成!\n"); 18 | Scanner input = new Scanner(System.in); 19 | do //循环添加结点数据 20 | { 21 | System.out.println("输入添加的结点(学号 姓名 年龄):"); 22 | Data data = new Data(); 23 | data.key = input.next(); 24 | data.name = input.next(); 25 | data.age = input.nextInt(); 26 | 27 | if (data.age != 0) { 28 | if (SL.SLAdd(SL, data) == 0) { 29 | break; 30 | } 31 | } else { 32 | break; 33 | } 34 | } 35 | while (true); 36 | System.out.println("\n順序表中的结点顺序为:\n"); 37 | SL.SLALL(SL);//显示所有结点数据 38 | 39 | System.out.println("\n要取出的结点的序号:"); 40 | i = input.nextInt(); 41 | pdata = SL.SLFindByNum(SL, i); 42 | if (pdata != null) { 43 | System.out.println("第" + i + "个结点为:" + pdata.key + "," + pdata.name + "," + pdata.age + "\n"); 44 | } 45 | 46 | System.out.println("\n" + "要查找的关键字:"); 47 | key = input.next(); 48 | i = SL.SLFindByCont(SL,key); 49 | pdata = SL.SLFindByNum(SL,i); 50 | if(pdata != null) 51 | { 52 | System.out.println("第" + i+"个结点为:" + pdata.key+"," + pdata.name+"," +pdata.age+ ","); 53 | } 54 | } 55 | } 56 | 57 | class Data { 58 | String key; 59 | String name; 60 | int age; 61 | } 62 | 63 | class SLType { 64 | static final int MAX = 100; 65 | Data[] ListData = new Data[MAX + 1]; 66 | int ListLen; 67 | 68 | void Init(SLType SL) { 69 | SL.ListLen = 0; 70 | } 71 | 72 | int SLLength(SLType SL) { 73 | return (SL.ListLen); 74 | } 75 | 76 | int SLInsert(SLType SL, int n, Data data) { 77 | int i; 78 | if (SL.ListLen >= MAX)//顺序表结点数量已经超过最大数量 79 | { 80 | System.out.println("顺序表已经满了,不能插入结点了!\n"); 81 | return 0; 82 | } 83 | if (n < 1 || n > SL.ListLen - 1)//插入结点序号不正确 84 | { 85 | System.out.println("插入元素序号错误,不能插入元素!\n"); 86 | return 0; 87 | } 88 | for (i = SL.ListLen; i >= n; i--)//将顺序表 89 | { 90 | SL.ListData[i + 1] = SL.ListData[i]; 91 | } 92 | SL.ListData[n] = data; 93 | SL.ListLen++; 94 | return 1; 95 | } 96 | 97 | int SLAdd(SLType SL, Data data)//添加元素到顺序表的尾部 98 | { 99 | if (SL.ListLen >= MAX)//顺序表已满 100 | { 101 | System.out.println("顺序表已满,无法再添加结点!\n"); 102 | return 0; 103 | } 104 | SL.ListData[++SL.ListLen] = data; 105 | return 1; 106 | } 107 | 108 | int SLDele(SLType SL, int n)//删除顺序表中的元素 109 | { 110 | int i; 111 | if (n < 1 || n > SL.ListLen + 1)//删除结点错误 112 | { 113 | System.out.println("删除结点序号错误,不能删除结点!\n"); 114 | return 0; 115 | } 116 | for (i = n; i < SL.ListLen; i++)//将顺序表中的数据向前移动 117 | { 118 | SL.ListData[i] = SL.ListData[i + 1]; 119 | } 120 | SL.ListLen--; 121 | return 1; 122 | } 123 | 124 | Data SLFindByNum(SLType SL, int n)//按序号返回数据元素 125 | { 126 | if (n < 1 || n > SL.ListLen + 1)//元素序号不正确 127 | { 128 | System.out.println("结点序号错误,不能返回结点!\n"); 129 | return null; 130 | } 131 | return SL.ListData[n]; 132 | } 133 | 134 | int SLFindByCont(SLType SL, String key)//按照关键字查询结点 135 | { 136 | int i; 137 | for (i = 1; i <= SL.ListLen; i++) { 138 | if (SL.ListData[i].key.compareTo(key) == 0) { 139 | return i; 140 | } 141 | } 142 | return 0; 143 | } 144 | 145 | int SLALL(SLType SL)//显示顺序表中的所有的结点 146 | { 147 | int i; 148 | for (i = 1; i <= SL.ListLen; i++) { 149 | System.out.println(SL.ListData[i].key + "," + SL.ListData[i].name + "," + SL.ListData[i].age); 150 | } 151 | return 0; 152 | } 153 | } 154 | 155 | -------------------------------------------------------------------------------- /前端/CSS.md: -------------------------------------------------------------------------------- 1 | # CSS 2 | 3 | ## 选择器 4 | 5 | + 选择器的样式: 6 | 7 | > **选择器{ 属性:值; 属性:值 }** 8 | 9 | + 选择器:**选择标签的过程** 10 | 11 | + 选择器的种类: 12 | 13 | >+ 标签选择器 14 | >+ 类选择器 15 | >+ ID选择器 16 | >+ 通配符选择器 17 | >+ 交集选择器(标签指定式) 18 | >+ 子代选择器 19 | >+ 并集选择器 20 | >> + 补充选择器(C3): 21 | >> + 伪类选择器 22 | >> + 属性选择器 23 | >> + 伪元素选择器 24 | 25 | ### 标签选择器 26 | 27 | + 标签选择器的样式: 28 | > **Html 标签名 { 属性:值;}** 29 | 30 | + 常用的属性: 31 | 32 | > + color --> 前景色(文字颜色) 33 | > + background-color --> 背景色 34 | > + font-size --> 字体大小 35 | > + width --> 设置宽度 36 | > + height --> 设置高度 37 | > + 代码形式如下: 38 | 39 | >```html 40 | >/*标签选择器*/ 41 | >P{ 42 | > color:red;/*改变文字颜色*/ 43 | > font-size:50px;/*改变文字大小*/ 44 | >} 45 | >``` 46 | > 47 | 48 | + 属性单位问题: 49 | > + px --> 像素 50 | > + em --> 文字大小:**e.g: 1em=一个文字大小** 51 | 52 | + 颜色的表示方式: 53 | > + 直接设置成颜色的名称: **e.g: red,green,pink。。。** 54 | > + 使用十六进制表示:**e.g: 0-f** 55 | > + 使用三原色表示: **rgb()** 56 | > + 半透明效果: **rgba() a的取值是0-1范围内** 57 | > + + 半透明效果还可以用*opacity* 58 | > + + 为了兼容IE8等更早的浏览器,则还需要加一句**filter:Alpha(opacity=50);**作为兼容 59 | 60 | ### 通配符选择器 61 | + 通配符选择器的语法: 62 | > **{属性:值;.....}** 63 | 64 | > + `常用在样式初始化的时候` 65 | > + 因为不同浏览器的默认样式不一样,所以需要使用通配符选择器进行初始化。 66 | 67 | ### 标签指定式选择器 68 | + 标签指定式选择器的语法: 69 | > **标签名.类名{属性:值;.....}** 70 | > 或者 71 | > **标签名#id名{属性:值;.....}** 72 | + 关系: 73 | > + `既。。。又。。。` 74 | > 75 | > 示例代码如下: 76 | >```html 77 | >CSS: 78 | >div.one{ 79 | > color:green; 80 | >} 81 | >dic#two{ 82 | > color:red; 83 | >} 84 | >HTML: 85 | >
div中的文字
86 | >
id选择中的文字
87 | >``` 88 | 89 | ### 后代选择器 90 | + 后代选择器的语法: 91 | > **选择器 选择器{属性:值;......}** 92 | + `注意:` 93 | > + 后代选择器标签之间必须是嵌套关系 94 | > + 选择器与选择器之间必须使用空格隔开 95 | > + 后代选择器只能选择后代元素,当前的元素无法被选中 96 | > + 只要是父代中的子元素,就都会被选中 97 | > 98 | >示例代码如下: 99 | >```html 100 | >CSS: 101 | > p span { 102 | > color: red; 103 | >} 104 | > 105 | >HTML: 106 | > 107 | >
108 | > 文字1 109 | >

110 | > 文字2 111 | >

112 | >
113 | >``` 114 | 115 | 116 | ## font属性介绍 117 | + `font-size:` **文字大小** 118 | + `font-weight:` **文字加粗效果** (值可以为:700(具体值)或 bold)(文字默认正常显示可以设置为400(具体值)或normal) 119 | + `font-style:` **设置文字是否斜体显示** (值可以为:italic) (文字默认正常显示:normal) 120 | + `font-family:` **设置文字字体** 121 | + + `注意:` **font-family一次性可以设置多个字体,字体值与值之间用“,”隔开,设置多个字体是为了适配各种浏览器。** 122 | + + 文字字体表现方式: 123 | + + + 直接设置字体对应的名称(如:宋体或黑体) 124 | + + + 设置字体对应的英文名称(如:SimSun(宋体)、NSimSun(新宋体)、微软雅黑(microsoft yahei)、黑体(SimHei)) 125 | + + + 设置字体对应的unicode编码 126 | + `line-height:` **设置文字行高** 127 | ### font 属性联写 128 | ```html 129 | font: font-weight font-style font-size/line-height font-family; 130 | ``` 131 | + 示例代码如下: 132 | ```html 133 | font: 700 italic 30px/20px 微软雅黑; 134 | ``` 135 | + **`注意:`** 136 | + + 使用font属性联写的过程中,必须要设置`font-size`和`font-family` 137 | + + 在属性联写中,font-size必须放在font-family 138 | + + 如果font属性联写中的属性都需要设置,那么就按照示例代码的方式去写。 139 | 140 | ## CSS中大小、定位、轮廓相关属性 141 | 142 | + 大小相关属性 143 | > + height:用于设置目标对象高度。 144 | > + max-height:用于设置目标对象的最大高度。 **如果此属性值小于min-height的属性值,将会自动转换为min-height属性值。** 145 | > + min-height:用于设置目标对象的最小高度。 **和max-height的道理一样,会有自动转换的过程。** 146 | > + width:用于设置目标对象的宽度。 147 | > + max-width:用于设置目标对象的最大宽度。**如果此属性值小于min-width的属性值,将会自动转换为min-width属性值。** 148 | > + 用于设置目标对象的最小宽度。 **和max-width的道理一样,会有自动转换的过程。** 149 | > 150 | >代码如下: 151 | >```html 152 | >
CSS学习中
153 | >``` 154 | 155 | + box-sizing属性 156 | > + width和height只是指定该元素的内容区的宽度、高度。然而对与元素区域内的内补丁区、边框区、外补丁区所占的空间不产生任何效果。 157 | > + border:设置内补丁区。*属性与width和height具有相同的属性值* 158 | > + padding:设置边框区。*属性与width和height具有相同的属性值* 159 | > + background-clip:设置元素的背景(背景图片或颜色)是否延伸到边框下面。 160 | > + 备注:background-clip这个属性如果元素没有设置背景颜色或者图片,那么这个属性只有在边框(border)设置为透明或者半透明时才能看到视觉效果,不然这个属性造成的样式变化会被边框覆盖住。 161 | > + background-clip属性的值有: 162 | > + + border-box:背景延伸到边框外沿(但是在边框之下)。 163 | > + + padding-box:边框下面没有背景,即背景延伸到内边距外沿。 164 | > + + content-box:背景裁剪到内容区(content-box)外沿。 165 | > 166 | >background-clip示例代码如下: 167 | >```html 168 | > 169 | > 170 | > 171 | > 172 | > CSS+DIV页面布局 173 | > 185 | > 186 | > 187 | >

The yellow background extends behind the border.

188 | >

The yellow background extends to the inside edge of the border.

189 | >

The yellow background extends only to the edge of the content box.

190 | > 191 | > 192 | >``` 193 | > 194 | >box-sizing代码如下: 195 | >```html 196 | >
CSS学习引用
197 | >``` -------------------------------------------------------------------------------- /数据结构/枚举-讨厌的青蛙.md: -------------------------------------------------------------------------------- 1 | # 討厭的青蛙 2 | ## 問題描述: 3 | * 在韓國有一種青蛙 4 | * 每到晚上這種青蛙會跳躍稻田,從而踩踏稻子 5 | * 農民早上看到被踩踏的稻子,希望找到造成最大傷害的那隻青蛙所經過的路徑 6 | ### 發現: 7 | * 每隻青蛙總是沿著一條直線跳躍稻田 8 | * 且每次跳躍的距離都是相同的 9 | #### 當然還有如下幾種情況 10 | 11 | ![](http://p1.bpimg.com/567571/b29d2f1356260fbf.png) 12 | 13 | * 稻田裡的稻子組成一個柵格,每顆稻子位於一個格點上 14 | * 而青蛙總是從稻田的一側跳進稻田,然後沿著某線條直線穿越稻田,從另一側跳出去 15 | * 如圖所示 16 | 17 | ![](http://i1.piimg.com/567571/8fd5ee30a2f328f9.png) 18 | 19 | * 可能會有很多只青蛙從稻田穿越 20 | * 青蛙每一跳都恰好踩在一顆水稻上,將這顆水稻拍倒 21 | * 有些水稻可能被多隻青蛙踩踏 22 | * 如圖所示 23 | 24 | ![](http://p1.bpimg.com/567571/e104feabb4df590c.png) 25 | 26 | * 農民所見到的情形卻是下圖的情形,並不能夠看到上圖的直線,也見不到別人家田裡被踩踏到的水稻 27 | * 如圖所示 28 | 29 | ![](http://p1.bpimg.com/567571/e47a89dc23a08419.png) 30 | 31 | * 而在一條青蛙行走路徑的直線上,也可能會有一些被踩踏的水稻不屬於該行走路徑 32 | 1)1不是一條行走路徑:只有2顆被踩踏的水稻 33 | 2)2是一條行走路徑,但是不包括(2,6)上的水稻 34 | 3)3不是一條行走路徑:雖然有3顆水稻被踩踏但是3顆水稻之間的距離間隔不相等 35 | * 如圖所示 36 | 37 | ![](http://i1.piimg.com/567571/0e00cb14c7c6c846.png) 38 | 39 | ## 題目要求: 40 | * 請寫一個程序,確定: 41 | * 在各條青蛙行走路徑中,踩踏水稻最多的那一條上,有多少顆水稻被踩踏 42 | * 例如,圖4中答案是7,因為第6行上全部水稻恰好構成一條青蛙行走路徑 43 | * 如圖所示 44 | 45 | ![](http://i1.piimg.com/567571/60ee08a972e025ee.png) 46 | 47 | ### 程序輸入 48 | * 從標準輸入設備讀入數據 49 | * 第一行上兩個整數R,C,分別表示稻田中水稻的行數和列數,1<=R,C<=5000 50 | * 第二行是一個整數N,表示被踩踏的水稻數量,3<=N<=5000 51 | * 在剩下的N行中,每行有兩個整數,分別是一顆被踩踏水稻的行號(1~R)和列號(1~C),兩個整數用一個空格隔開 52 | * 且每棵被踩踏水稻只被列出一次 53 | ### 程序輸出 54 | * 從標準輸出設備上輸出一個整數 55 | * 如果在稻田中存在青蛙行走路徑,則輸出包含最多水稻的青蛙行走路徑中的水稻數量,否則輸出0 56 | ## 解題思路——枚舉 57 | ### 枚舉是什麼 58 | * 枚舉每個被踩的稻子作為行走路徑起點(5000個) 59 | * 對每個起點,枚舉行走方向(5000種) 60 | * 對每個方向枚舉步長(5000種) 61 | * 枚舉步長后還要判斷是否每步都猜到水稻 62 | * 時間:5000*5000*5000 .....不行!!! 63 | ### 枚舉什麼? 64 | * 枚舉路徑上的開始的兩點 65 | * 每條青蛙行走路徑中至少有3顆水稻 66 | * 假設一隻青蛙進入稻田后踩踏的前兩顆水稻分別是(X1,Y1),(X2,Y2).那麼: 67 | * 青蛙每一跳在X方向上的步長dX = X2-X1, 68 | 在Y方向上的步長dY = Y2-Y1, 69 | * (X1-dX,Y1-dY)需要落在稻田之外 70 | * 當青蛙踩在水稻(X,Y)上時,下一跳踩踏的水稻是(X+dX,Y+dY) 71 | * 將路徑上的最後一顆水稻記作(Xk,Yk),(Xk+dX,Yk+dY)需要落在稻田之外 72 | ### 解題思路:猜測一條路徑 73 | * 猜測的辦法需要保證: 74 | * 每條可能的路徑都能夠被猜測到 75 | * 從輸入的水稻中任取兩顆 76 | ->*作為一隻青蛙進入稻田后踩踏的前兩顆水稻* 77 | ->*看能否形成一條穿越稻田的行走路徑* 78 | * 猜測的過程需要盡快排出錯誤答案 79 | * 猜測(X1,Y1),(X2,Y2)--所要尋找的行走路徑上的前兩顆水稻 80 | * 當下列條件之一滿足時,這個猜測就不成立: 81 | * 青蛙不能夠經過一跳就從稻田外跳到(X1,Y1)上 82 | * 按照(X1,Y1),(X2,Y2)確定的步長,從(X1,Y1)出發青蛙最多經過(MAXSTEPS-1)步,就會跳到稻田外 83 | * MAXSTEPS是當前已經找到的最好答案 84 | ## 選擇合適的數據結構 85 | * 選擇合適的數據結構 86 | * 採用的數據結構需要與問題描述中個的概念對應 87 | * 關於被踩踏的水稻的坐標,該如何定義? 88 | * 方案一: 89 | ```java 90 | struct{ 91 | int x,y; 92 | }plants[5000];//定義好結構體 93 | ``` 94 | * 方案二: 95 | ```java 96 | int plantsRow[5000],plantsCol[5000]; 97 | ``` 98 | * 顯然方案一更加符合問題本身的描述 99 | ## 設計的算法要簡潔 100 | * 盡量使用C++提供的函數完成計算的任務 101 | * 猜測一條行走路徑時,需要從當前位置(X,Y)出發上時,看看(X+dX,Y+dY)位置的水稻是否被踩踏 102 | * 方案一:自己寫一段代碼,看看(X+dX,Y+dY)是否在數組plants中 103 | * 方案二:先用sort()對plants中的元素排序,再用binary_search()從中查找元素(X+dX,Y+dY) 104 | * 基於 方案二 設計的算法更加簡潔,容易實現,更不容易出錯誤 105 | ## 注: 106 | * 一個有n個元素的數組,每次取兩個元素,遍歷所有取法 107 | * 代碼寫法: 108 | ```java 109 | for(int i=0;i 121 | #include 122 | #include 123 | using namespace std; 124 | int r,c,n;//定義全局變量 125 | struct PLANT{ 126 | int x,y; 127 | }//定義相應的結構體用來描述踩踏的水稻的相應的橫縱坐標 128 | PLANT plants[5001]; 129 | PLANT plant;//再定義了一個plant用來存放臨時的一些點 130 | int searchPath(PLANT secPlant,int dX,int dY);//關鍵函數,找尋相應的路徑,相應的secPlant,還有相應的dX和dY用來表示相應的步長 131 | int main() { 132 | int i,j,dX,dY,pX,pY,steps,max = 2; 133 | scanf("%d %d",&r, &c); 134 | //行數和列數,x方向是上下,y方向是左右 135 | scanf("%d", &n); 136 | for(i = 0 ;i < n; i++) 137 | { 138 | scanf("%d %d",&plants[i].x, &plants[i].y); 139 | } 140 | //將水稻按x坐標從小到大排序,x坐標相同按y從小到大排序 141 | sort(plants,plants + n); 142 | for (i = 0; i < n-2; i++) //plants[i]是第一個點 143 | { 144 | for (j = 0; j < n-1; j++) //plants[j]是第二個點 145 | { 146 | dX = plants[j].x - plants[i].x; 147 | dY = plants[j].y - plants[i].y; 148 | pX = plants[i].x - dX; 149 | pY = plants[i].y - dY; 150 | if (pX <= r && pX >= 1 && pY <= c && pY >= 1) { 151 | continue; 152 | } 153 | //第一點的前一點在稻田里 154 | //說明本次選的第二點導致的x方向步長不合理(太小) 155 | //去下一個點作為第二點 156 | if (plants[i].x + (max - 1)*dX > r) { // -----------------* 157 | break; 158 | } 159 | //x方向過早越界了,說明本次選的第二點不成立 160 | //如果換下一個點作為第二點,x方向步長只會更大,更不成立,所以應該 161 | //認為本次選的第一點必然是不成立的,那麼取下一個點作為第一點再試 162 | pY = plants[i].y + (max - 1)*dY; // --------------* 163 | if(pY>c||pY<1) 164 | continue;//y方向過早越界了,應換一個點作為第二點再試 165 | steps = searchPath(plants[j], dX, dY); 166 | //看看從這兩點出發,一共能夠幾步 167 | if(steps > max) max = steps; 168 | } 169 | if(max == 2)max == 0; 170 | printf("%d\n", max); 171 | } 172 | bool operator <(const PLANT & p1,const PLANT & p2)//"<"在c++中表示重載的意思 173 | { 174 | if(p1.x == p2.x) 175 | return p1.x=1 && plant.y <= c && plant.y >= 1) { 185 | if (binary_search(plants,plants + n,plant)) { 186 | //每一步都必須踩倒水稻才算合理,否則這就不是一條行走路徑 187 | steps = 0; 188 | break; 189 | } 190 | plant.x += dX; 191 | plant.y += dY; 192 | steps++; 193 | } 194 | } 195 | return(steps); 196 | } 197 | ``` 198 | # 小結 199 | 200 | * 枚舉順序十分重要,好的枚舉順序能夠及早排除不可能的情況,減少枚舉次數 201 | * 本題將踩倒的水稻按照位置進行排序 202 | * 枚舉的時候先枚舉序號低的,就能狗有效減少枚舉次數: 203 | ```c++ 204 | if (plants[i].x + (max - 1)*dX >r) { 205 | break; 206 | } 207 | //x方向過早越界了,說明本次選的第二點不成立 208 | //如果換下一個點作為第二點,x方向步長只會更大,更不成立 209 | //所以應該認為本次選的第一點必然是不成立的 210 | //那麼取下一個點作為第一點在試 211 | ``` 212 | -------------------------------------------------------------------------------- /数据结构/线性表/LinkedList/Linked.java: -------------------------------------------------------------------------------- 1 | package com.dell.example.linked; 2 | 3 | import java.util.Scanner; 4 | 5 | /* 6 | * Created by JohnnyTan on 2017/10/4. 7 | */ 8 | public class Linked { 9 | public static void main(String[] args) { 10 | CLType node, head = null; 11 | CLType CL = new CLType(); 12 | String key, findkey; 13 | Scanner input = new Scanner(System.in); 14 | System.out.println("链表测试.先输入链表中的数据,格式为:关键字 姓名 年龄\n"); 15 | do { 16 | Data nodeData = new Data(); 17 | nodeData.key = input.next(); 18 | if (nodeData.key.equals("0")) { 19 | break;//若输入0,则退出 20 | } else { 21 | nodeData.name = input.next(); 22 | nodeData.age = input.nextInt(); 23 | head = CL.CLAddEnd(head, nodeData);//在链表尾部添加结点 24 | } 25 | } while (true); 26 | CL.CLALLNode(head); 27 | System.out.println("\n演示插入结点,输入插入位置的关键字:"); 28 | findkey = input.next();//输入插入位置的关键字 29 | System.out.println("输入插入结点的数据(关键字 姓名 年龄):"); 30 | Data nodeData = new Data(); 31 | nodeData.key = input.next(); 32 | nodeData.name = input.next(); 33 | nodeData.age = input.nextInt();//输入插入结点的数据 34 | head = CL.CLInsertNode(head, findkey, nodeData);//调用插入方法 35 | CL.CLALLNode(head);//显示所有结点 36 | System.out.println("\n演示删除结点,输入要删除的关键字:"); 37 | key = input.next(); //输入需要删除的结点关键字 38 | CL.CLDeleNode(head,key);//调用删除方法 39 | CL.CLALLNode(head);//显示所有结点 40 | System.out.println("\n演示在链表中查找,输入查找关键字:"); 41 | key = input.next(); 42 | node = CL.CLFindNode(head,key); 43 | if(node != null) 44 | { 45 | nodeData = node.nodeData;//获取结点数据 46 | System.out.printf("关键字%s对应的结点为(%s.%s,%d)\n",key,nodeData.key,nodeData.name,nodeData.age); 47 | } 48 | else 49 | { 50 | System.out.printf("在链表中未找到关键字为%s的结点!\n",key); 51 | } 52 | } 53 | } 54 | 55 | class Data//结点的关键字 56 | { 57 | String key; 58 | String name; 59 | int age; 60 | } 61 | 62 | class CLType//定义链表结构 63 | { 64 | Data nodeData = new Data(); 65 | CLType nextNode; 66 | 67 | //追加结点 68 | CLType CLAddEnd(CLType head, Data nodeData) { 69 | CLType node, htemp; 70 | if ((node = new CLType()) == null) { 71 | System.out.println("申请内存失败!\n"); 72 | return null; 73 | } else { 74 | node.nodeData = nodeData;//保存数据 75 | node.nextNode = null;//设置结点引用为空,即为表尾 76 | if (head == null) { 77 | head = node; 78 | return head; 79 | } 80 | htemp = head; 81 | while (htemp.nextNode != null) { 82 | htemp = htemp.nextNode; 83 | } 84 | htemp.nextNode = node; 85 | return head; 86 | } 87 | } 88 | 89 | //头部增加结点 90 | CLType CLAddFirst(CLType head, Data nodeData) { 91 | CLType node; 92 | if ((node = new CLType()) == null) { 93 | System.out.println("申请内存失败!\n");//分配内存失败 94 | return null; 95 | } else { 96 | node.nodeData = nodeData; 97 | node.nextNode = head; 98 | head = node; 99 | return head; 100 | } 101 | } 102 | 103 | //查找结点 104 | CLType CLFindNode(CLType head, String key) { 105 | CLType htemp; 106 | htemp = head; 107 | while (htemp != null) { 108 | if (htemp.nodeData.key.compareTo(key) == 0) { 109 | return htemp; 110 | } 111 | htemp = htemp.nextNode; 112 | } 113 | return null; 114 | } 115 | 116 | //插入结点 117 | CLType CLInsertNode(CLType head, String findkey, Data nodeData) { 118 | CLType node, nodeTemp; 119 | if ((node = new CLType()) == null) { 120 | System.out.println("申请内存失败!\n"); 121 | return null; 122 | } 123 | node.nodeData = nodeData; 124 | nodeTemp = CLFindNode(head, findkey); 125 | if (nodeTemp != null) { 126 | node.nextNode = nodeTemp.nextNode;//新插入结点指向关键结点的下一结点 127 | nodeTemp.nextNode = node;//设置关键结点指向新的结点 128 | } else { 129 | System.out.println("未找到正确的插入位置!\n"); 130 | // free(node); //释放内存 131 | } 132 | return head; 133 | } 134 | 135 | //删除某结点 136 | int CLDeleNode(CLType head, String key) { 137 | CLType node, htemp; //node保存删除结点的前一个结点 138 | htemp = head; 139 | node = head; 140 | while (htemp != null) { 141 | if (htemp.nodeData.key.compareTo(key) == 0)//找到关键字,执行删除操作 142 | { 143 | node.nextNode = htemp.nextNode; //使前一个结点指向当前结点的下一个结点 144 | return 1; 145 | } else { 146 | node = htemp; //指向当前结点 147 | htemp = htemp.nextNode; //指向下一个结点 148 | } 149 | } 150 | return 0; 151 | } 152 | 153 | //计算链表的长度 154 | int CLength(CLType head) { 155 | CLType htemp; 156 | int Len = 0; 157 | htemp = head; 158 | while (htemp != null) { 159 | Len++; 160 | htemp = htemp.nextNode; 161 | } 162 | return Len; 163 | } 164 | 165 | //遍历链表 166 | void CLALLNode(CLType head) { 167 | CLType htemp; 168 | Data nodeData; 169 | htemp = head; 170 | System.out.println("当前链表共有" + CLength(head) + "个结点.链表所有数据如下:\n"); 171 | while (htemp != null) { 172 | nodeData = htemp.nodeData; 173 | System.out.printf("结点(%s,%s,%d)\n", nodeData.key, nodeData.name, nodeData.age); 174 | htemp = htemp.nextNode; 175 | } 176 | } 177 | } -------------------------------------------------------------------------------- /JAVA学习/Java多线程.md: -------------------------------------------------------------------------------- 1 | # java多线程 2 | 3 | 标签: java多线程 4 | 5 | --- 6 | 7 | **Contents** 8 | - [什么是线程](#进程与线程) 9 | - [传统线程技术](#传统线程技术) 10 | - [Java中的线程](#Java中的线程) 11 | - [传统创建线程方式](#传统创建线程方式) 12 | - [互斥](#互斥) 13 | - [同步](#同步) 14 | 15 | --- 16 | 17 | # 进程与线程 18 | 19 | ![](https://raw.githubusercontent.com/kentanvictor/STUDY/Image/SystemProcess.jpg) 20 | 21 | + `进程(process)是指运行中的应用程序,每一个进程都有自己独立的内存空间。`一个应用程序可以同时启动多个进程。例如对于IE浏览器程序,每打开一个IE浏览器窗口,就启动了一个新的进程。同样,每次执行JDK的java.exe程序,就启动了一个独立的Java虚拟机进程,该进程的任务是解析并执行Java程序代码。 22 | 23 | ![](https://raw.githubusercontent.com/kentanvictor/STUDY/Image/ProcessAndThread.jpg) 24 | 25 | + `线程(thread)是操作系统能够进行运算的最小单位。` **线程被包含在进程之中,是行程中的实际运行单位。一条线程是指进程中的一个单一顺序的控制流,一个进程中可以并行多个现成,每条线程并行执行不同的任务。** 当进程内的多个线程同时运行时,这种运行方式称为并发运行。许多服务器程序,如数据库服务器和Web服务器,都支持并发运行,这些服务器能同时响应来自不同客户的请求。 26 | 27 | # 传统线程技术 28 | 29 | ## Java中的线程 30 | 31 | >Java语言的一大特性点就是内置对多线程的支持。多线程是指一个应用程序中同时存在几个执行体,按几条不同的执行线索共同工作的情况。(如下图所示:) 32 | ![](https://raw.githubusercontent.com/kentanvictor/STUDY/Image/JVMThread.png) 33 | > 34 | >让我们提出这样一个问题: 35 | > 36 | > `能否在一个Java程序中出现两个以上的无限循环呢?` 37 | > 38 | > 如果不使用多线程技术,是无法解决上述问题的,比如下面的代码: 39 | > 40 | ```java 41 | public class Hello{ 42 | public static void main(String args[]){ 43 | while(true){ 44 | System.out.println("Hello"); 45 | } 46 | while(true){ 47 | System.out.println("您好"); 48 | } 49 | } 50 | } 51 | ``` 52 | > 53 | >上述代码是有问题的,因为第2个while语句是永远没有机会会被执行到的。如果能在主线程中创建两个线程,每个线程分别执行一个while循环,那么两个循环就都有机会执行。`JVM负责管理这些线程,这些线程会被轮流执行,使得每个线程都有机会使用CPU资源。` 54 | > 55 | 56 | 57 | ## 传统创建线程方式 58 | 59 | ![](https://raw.githubusercontent.com/kentanvictor/STUDY/Image/Thread.png) 60 | 61 | 1.继承Thread类,覆盖run方法 62 | 63 | ```java 64 | Thread t = new Thread(); 65 | t.start(); 66 | ``` 67 | 68 | 2.实现Runnable接口 69 | 70 | Runnable不是线程,是线程要运行的代码的宿主。 71 | 72 | 1.看看Thread类源码,捋清Runnable,target,run,start关系 73 | 74 | - `Runnable`是一个接口 75 | - `target`是`Thread`类中类型为`Runnable`,名为`target`的属性 76 | - `run`是`Thread`类实现了`Runnable`的接口,重写的方法。 77 | - `start`是启动线程的方法 78 | - **在`Thread`类中,调用关系为:`start`->`start0`->`run`->`target.run`** 79 | 80 | `Thread`类的`run`方法源码 81 | 82 | ```java 83 | public void run() { 84 | if (target != null) { 85 | target.run(); 86 | } 87 | } 88 | ``` 89 | 90 | `Thread`类的`target`属性 91 | 92 | ```java 93 | /* What will be run. */ 94 | private Runnable target; 95 | ``` 96 | 97 | `target`属性由`private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc)`方法初始化。`init`方法在`Thread`类的构造方法里被调用 98 | 99 | 100 | 101 | 102 | 2.匿名内部类对象的构造方法如何调用父类的非默认构造方法 103 | 104 | 105 | 106 | ## 互斥 107 | 108 | 关键字:`synchronized`,检查锁对象 109 | 110 | - `synchronized(this)` 111 | - `synchronized void function(){}` 112 | - `synchronized(A.class)` 113 | 114 | 例子:实现登录 115 | 116 | + A登录类: 117 | 118 | ```java 119 | public class ALogin extends Thread{ 120 | @Override 121 | public void run() { 122 | LoginServlet.doPost("a","aa"); 123 | } 124 | } 125 | ``` 126 | + B登录类: 127 | 128 | ```java 129 | public class BLogin extends Thread{ 130 | @Override 131 | public void run() { 132 | LoginServlet.doPost("b","bb"); 133 | } 134 | } 135 | ``` 136 | + 登录方法: 137 | ```java 138 | public class LoginServlet { 139 | private static String usernameRef; 140 | private static String passwordRef; 141 | public static void doPost(String username,String password){ 142 | try { 143 | usernameRef = username; 144 | if (username.equals("a")){ 145 | Thread.sleep(5000); 146 | } 147 | passwordRef = password; 148 | System.out.println("userName=" + usernameRef + "\t" + "password=" + password); 149 | }catch (InterruptedException e){ 150 | e.printStackTrace(); 151 | } 152 | } 153 | } 154 | ``` 155 | + 实现类: 156 | 157 | ```java 158 | public class Run { 159 | public static void main(String[] args) { 160 | ALogin a = new ALogin(); 161 | a.start(); 162 | BLogin b = new BLogin(); 163 | b.start(); 164 | } 165 | } 166 | ``` 167 | `如果不使用互斥锁,则会出现下面的情况:` 168 | 169 | ![](https://raw.githubusercontent.com/kentanvictor/STUDY/Image/ThreadResultWithNotSy.png) 170 | 171 | >为了避免由于线程的随机运行带来的线程的不安全性,我们需要在`doPost方法前加上互斥锁(synchronized)`。 172 | 173 | ## 同步 174 | 175 | 经验: 176 | 177 | >* 要用到共同数据(包括同步锁)或共同算法的若干个方法应该归在同一个类身上,这种设计体现了高聚类和程序的健壮。性。 178 | >* 同步互斥不是在线程上实现,而是在线程访问的资源上实现,线程调用资源。 179 | 180 | 例子: 子线程循环5次,主线程循环10次,如此交替50次 181 | 182 | 设计: 183 | 184 | 使用一个Business类来包含子线程和主线程要运行的代码,从而,该类的对象成为加锁的对象。同步互斥在该类实现,由线程调用该类的方法,即调用了资源。 185 | 186 | 代码: 187 | 188 | ```java 189 | 190 | public class TraditionalThreadCommunication { 191 | public static void main(String[] args) { 192 | Business business = new Business(); 193 | new Thread( 194 | new Runnable() { 195 | @Override 196 | public void run() { 197 | for(int i=1;i<=50;i++){ 198 | business.sub(i); 199 | } 200 | } 201 | } 202 | ).start(); 203 | 204 | for(int i=1;i<=50;i++){ 205 | business.main(i); 206 | } 207 | 208 | } 209 | } 210 | 211 | class Business{ 212 | private boolean bShouldSub = true; 213 | 214 | public synchronized void sub(int i){ 215 | while(!bShouldSub){ 216 | try { 217 | this.wait(); 218 | } catch (InterruptedException e) { 219 | e.printStackTrace(); 220 | } 221 | } 222 | for(int j=1;j<=5;j++){ 223 | System.out.println("sub thread count "+j+","+i+"/50"); 224 | } 225 | bShouldSub = false; 226 | this.notify(); 227 | } 228 | public synchronized void main(int i){ 229 | while(bShouldSub){ 230 | try { 231 | this.wait(); 232 | } catch (InterruptedException e) { 233 | e.printStackTrace(); 234 | } 235 | } 236 | for(int j=1;j<=10;j++){ 237 | System.out.println("main thread count "+j+","+i+"/50"); 238 | } 239 | bShouldSub = true; 240 | this.notify(); 241 | } 242 | } 243 | ``` 244 | 245 | 判断条件时,while与if的区别:while防止伪唤醒。 246 | -------------------------------------------------------------------------------- /JAVA学习/Java线程.md: -------------------------------------------------------------------------------- 1 | # java 线程 2 | 3 | >* 多个线程并发的意思就是,多个线程同时请求同一个资源 4 | >* 同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求 5 | 不到,怎么办,A线程只能等待下去 6 | >* 异步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程 7 | 仍然请求的到,A线程无需等待 8 | 9 | + java中实现多线程 10 | + 继承Thread,重写里面的run方法 11 | + 实现runnable接口(推荐这种实现方式) 12 | 13 | # java线程 同步与异步 线程池 14 | 15 | >显然,同步最最安全,最保险的。而异步不安全,容易导致死锁,这样一个线程死掉就会导致整个 16 | 进程崩溃,但没有同步机制的存在,性能会有所提升 17 | 18 | java中实现多线程 19 | 20 | + 继承Thread,重写里面的run方法 21 | + 实现runnable接口 22 | 23 | + Doug Lea比较推荐后者,第一,java没有单继承的限制,第二,还可以隔离代码* 24 | 25 | ## 线程池 26 | 27 | >要知道在计算机中任何资源的创建,包括线程,都需要消耗系统资源的。在WEB服务中,对于web服务器的响应速度必须要尽可能的快,这就容不得每次在用户提交请求按钮后,再创建线程提供服务。为了减少用户的等待时间,线程必须预先创建,放在线程池中,线程池可以用HashTable这种数据结构来实现,看了Apach HTTP服务器的线程池的源代码,用是就是HashTable,KEY用线程对象,value 用ControlRunnable,ControlRunnable是线程池中唯一能干活的线程,是它指派线程池中的线程对外提供服务。出于安全考虑,Apach HTTP服务器的线程池它是同步的。听说weblogic有异步的实现方式,没有研究过,不敢确定。 28 | 29 | 一、`关键字`: 30 | 31 | + thread(线程) 32 | + thread-safe(线程安全) 33 | + intercurrent(并发的) 34 | + synchronized(同步的) 35 | + asynchronized(异步的) 36 | + volatile(易变的) 37 | + atomic(原子的) 38 | + share(共享) 39 | 40 | 二、总结背景: 41 | 42 | >一次读写共享文件编写,嚯,好家伙,竟然揪出这些零碎而又是一路的知识点。于是乎,Google和翻阅了《Java参考大全》、《Effective Java Second Edition》,特此总结一下供日后工作学习参考。 43 | 44 | 三、概念: 45 | 46 | 1、 什么时候必须同步?什么叫同步?如何同步? 47 | >要跨线程维护正确的可见性,只要在几个线程之间共享非 final 变量,就必须使用synchronized(或 volatile)以确保一个线程可以看见另一个线程做的更改。 48 | 为了在线程之间进行可靠的通信,也为了互斥访问,同步是必须的。这归因于java语言规范的内存模型,它规定了:一个线程所做的变化何时以及如何变成对其它线程可见。因为多线程将异步行为引进程序,所以在需要同步时,必须有一种方法强制进行。例如:如果2个线程想要通信并且要共享一个复杂的数据结构,如链表,此时需要确保它们互不冲突,也就是必须阻止B线程在A线程读数据的过程中向链表里面写数据(A获得了锁,B必须等A释放了该锁)。为了达到这个目的,java在一个旧的的进程同步模型——监控器(Monitor)的基础上实现了一个巧妙的方案:监控器是一个控制机制,可以认为是一个很小的、只能容纳一个线程的盒子,一旦一个线程进入监控器,其它的线程必须等待,直到那个线程退出监控为止。通过这种方式,一个监控器可以保证共享资源在同一时刻只可被一个线程使用。这种方式称之为同步。(一旦一个线程进入一个实例的任何同步方法,别的线程将不能进入该同一实例的其它同步方法,但是该实例的非同步方法仍然能够被调用)。 49 | 50 | *错误的理解:同步嘛,就是几个线程可以同时进行访问。* 51 | 52 | + 同步和多线程关系:没多线程环境就不需要同步;有多线程环境也不一定需要同步。 53 | + 锁提供了两种主要特性:互斥(mutual exclusion)和可见性(visibility)。 54 | 55 | >互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。 56 | 57 | **小结:为了防止多个线程并发对同一数据的修改,所以需要同步,否则会造成数据不一致(就是所谓的:线程安全。如java集合框架中Hashtable和Vector是线程安全的。我们的大部分程序都不是线程安全的,因为没有进行同步,而且我们没有必要,因为大部分情况根本没有多线程环境)。** 58 | 59 | 2、 什么叫原子的(原子操作)? 60 | 61 | >Java原子操作是指:不会被打断地的操作。(就是做到互斥和可见性?!) 62 | 那难道原子操作就可以真的达到线程安全同步效果了吗?实际上有一些原子操作不一定是线程安全的。那么,原子操作在什么情况下不是线程安全的呢?也许是这个原因导致的:java线程允许线程在自己的内存区保存变量的副本。允许线程使用本地的私有拷贝进行工作而非每次都使用主存的值是为了提高性能(本人愚见:虽然原子操作是线程安全的,可各线程在得到变量(读操作)后,就是各自玩弄自己的副本了,更新操作(写操作)因未写入主存中,导致其它线程不可见)。 63 | 那该如何解决呢?因此需要通过java同步机制。 64 | 在java中,32位或者更少位数的赋值是原子的。在一个32位的硬件平台上,除了double和long 65 | 型的其它原始类型通常都是使用32位进行表示,而double和long通常使用64位表示。另外,对象引用使用本机指针实现,通常也是32位的。对这些32位的类型的操作是原子的。 66 | 这些原始类型通常使用32位或者64位表示,这又引入了另一个小小的神话:原始类型的大小是 67 | 由语言保证的。这是不对的。java语言保证的是原始类型的表数范围而非JVM中的存储大小。因此,int型总是有相同的表数范围。在一个JVM上可能使用32位实现,而在另一个JVM上可能是64位的。在此再次强调:在所有平台上被保证的是表数范围,32位以及更小的值的操作是原子的。 68 | 69 | 3、 不要搞混了:同步、异步 70 | 举个例子:普通B/S模式(同步)AJAX技术(异步) 71 | 同步:提交请求->等待服务器处理->处理完返回这个期间客户端浏览器不能干任何事 72 | 异步:请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕 73 | 可见,彼“同步”非此“同步”——我们说的java中的那个共享数据同步(synchronized) 74 | 一个同步的对象是指行为(动作),一个是同步的对象是指物质(共享数据)。 75 | 76 | 4、 Java同步机制有4种实现方式:(部分引用网上资源) 77 | 78 | ① ThreadLocal ② synchronized( ) ③ wait() 与 notify() ④ volatile 79 | 80 | 目的:都是为了解决多线程中的对同一变量的访问冲突 81 | 82 | ### ThreadLocal 83 | 84 | ThreadLocal 保证不同线程拥有不同实例,相同线程一定拥有相同的实例,即为每一个使用该变量的线程提供一个该变量值的副本,每一个线程都可以独立改变自己的副本,而不是与其它线程的副本冲突。 85 | 86 | + 优势:提供了线程安全的共享对象与其它同步机制的区别:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信;而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源,这样当然不需要多个线程进行同步了。 87 | 88 | ### volatile 89 | 90 | volatile 修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。 91 | 92 | + 优势:这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。 93 | 94 | + 缘由:Java 语言规范中指出,为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。而 volatile 关键字就是提示 VM :对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。 95 | 96 | + 使用技巧:在两个或者更多的线程访问的成员变量上使用 volatile 。当要访问的变量已在 97 | synchronized 代码块中,或者为常量时,不必使用。线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B。只在某些动作时才进行A和B的同步,因此存在A和B不一致的情况。volatile就是用来避免这种情况的。 volatile告诉jvm,它所修饰的变量不保留拷贝,直接访问主内存中的(读操作多时使用较好;线程间需要通信,本条做不到)Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的. 98 | 一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。 99 | 您只能在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理 100 | 想的线程安全,必须同时满足下面两个条件: 101 | 对变量的写操作不依赖于当前值;该变量没有包含在具有其他变量的不变式中。 102 | 103 | ### sleep() vs wait() 104 | 105 | + sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 106 | + wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。(如果变量被声明为volatile,在每次访问时都会和主存一致;如果变量在同步方法或者同步块中被访问,当在方法或者块的入口处获得锁以及方法或者块退出时释放锁时变量被同步。) 107 | 108 | 四、例子: 109 | Demo1: 110 | 111 | ```java 112 | package test.thread; 113 | 114 | 115 | class SynTest{ 116 | 117 | //非同步 118 | static void method(Thread thread){ 119 | System.out.println("begin "+thread.getName()); 120 | try{ 121 | Thread.sleep(2000); 122 | }catch(Exception ex){ 123 | ex.printStackTrace(); 124 | } 125 | System.out.println("end "+thread.getName()); 126 | } 127 | 128 | //同步方式一:同步方法 129 | synchronized static void method1(Thread thread){//这个方法是同步的方法,每次只有一个线程可以进来 130 | System.out.println("begin "+thread.getName()); 131 | try{ 132 | Thread.sleep(2000); 133 | }catch(Exception ex){ 134 | ex.printStackTrace(); 135 | } 136 | System.out.println("end "+thread.getName()); 137 | } 138 | 139 | //同步方式二:同步代码块 140 | static void method2(Thread thread){ 141 | synchronized(SynTest.class) { 142 | System.out.println("begin "+thread.getName()); 143 | try{ 144 | Thread.sleep(2000); 145 | }catch(Exception ex){ 146 | ex.printStackTrace(); 147 | } 148 | System.out.println("end "+thread.getName()); 149 | } 150 | } 151 | 152 | 153 | //同步方式三:使用同步对象锁 154 | private static Object _lock1=new Object(); 155 | private static byte _lock2[]={};//据说,此锁更可提高性能。源于:锁的对象越小越好 156 | static void method3(Thread thread){ 157 | synchronized(_lock1) { 158 | System.out.println("begin "+thread.getName()); 159 | try{ 160 | Thread.sleep(2000); 161 | }catch(Exception ex){ 162 | ex.printStackTrace(); 163 | } 164 | System.out.println("end "+thread.getName()); 165 | } 166 | } 167 | 168 | public static void main(String[] args){ 169 | //启动3个线程,这里用了匿名类 170 | for(int i=0;i<3;i++){ 171 | new Thread(){ 172 | public void run(){ 173 | method(this); 174 | //method1(this); 175 | //method2(this); 176 | //method3(this); 177 | } 178 | }.start(); 179 | } 180 | } 181 | } 182 | ``` 183 | 184 | Demo2: 185 | 186 | ```java 187 | package test.thread; 188 | 189 | import com.util.LogUtil; 190 | 191 | 192 | public class SynTest2 { 193 | 194 | public static void main(String[] args){ 195 | Callme target=new Callme(); 196 | Caller ob1=new Caller(target,"Hello"); 197 | Caller ob2=new Caller(target,"Synchronized"); 198 | Caller ob3=new Caller(target,"World"); 199 | } 200 | } 201 | 202 | class Callme{ 203 | 204 | 205 | synchronized void test(){ 206 | LogUtil.log("测试是否是:一旦一个线程进入一个实例的任何同步方法,别的线程将不能 207 | 进入该同一实例的其它同步方法,但是该实例的非同步方法仍然能够被调用"); 208 | } 209 | 210 | void nonsynCall(String msg){ 211 | LogUtil.log("["+msg); 212 | LogUtil.log("]"); 213 | } 214 | 215 | synchronized void synCall(String msg){ 216 | LogUtil.logPrint("["+msg); 217 | LogUtil.log("]"); 218 | } 219 | } 220 | 221 | class Caller implements Runnable{ 222 | String msg; 223 | Callme target; 224 | Thread t; 225 | 226 | Caller(Callme target,String msg){ 227 | this.target=target; 228 | this.msg=msg; 229 | t=new Thread(this); 230 | t.start(); 231 | } 232 | 233 | public void run() { 234 | // TODO Auto-generated method stub 235 | //target.nonsynCall(msg); 236 | target.synCall(msg); 237 | target.test(); 238 | } 239 | 240 | 241 | } 242 | ``` 243 | -------------------------------------------------------------------------------- /数据结构/树/treeDemo/TreeDemo.java: -------------------------------------------------------------------------------- 1 | package com.dell.example.treeDemo; 2 | 3 | import java.util.Scanner; 4 | 5 | /* 6 | * Created by JohnnyTan on 2017/11/2. 7 | */ 8 | public class TreeDemo { 9 | public static void main(String[] args) { 10 | Scanner input = new Scanner(System.in); 11 | CBTType root = null; //root为指向二叉树根结点的引用 12 | int menusel; 13 | TreeOperation tree = new TreeOperation(); 14 | //设置根元素 15 | root = tree.InitTree(); 16 | //添加结点 17 | do { 18 | System.out.printf("请选择菜单添加二叉树的结点\n"); 19 | System.out.printf("0.退出\t"); //显示菜单 20 | System.out.printf("1.添加二叉树的结点\n"); 21 | menusel = input.nextInt(); 22 | switch (menusel) 23 | { 24 | case 1: 25 | tree.AddTreeNode(root); 26 | break; 27 | case 0: 28 | break; 29 | default: 30 | ; 31 | } 32 | } 33 | while (menusel != 0); 34 | 35 | //遍历 36 | do { 37 | System.out.printf("请选择菜单遍历二叉树,输入0表示推出:\n"); 38 | System.out.printf("1.先序遍历DLR\t"); 39 | System.out.printf("2.中序遍历LDR\t"); 40 | System.out.printf("3.后序遍历LRD\t"); 41 | System.out.printf("4.按层遍历\n"); 42 | menusel = input.nextInt(); 43 | switch (menusel) 44 | { 45 | case 0: 46 | break; 47 | case 1: //先序遍历 48 | System.out.printf("\n先序遍历DLR的结果:"); 49 | tree.DLRTree(root); 50 | System.out.printf("\n"); 51 | break; 52 | case 2: //中序遍历 53 | System.out.printf("\n中序遍历的结果:"); 54 | tree.LDRTree(root); 55 | System.out.printf("\n"); 56 | break; 57 | case 3: //后序遍历 58 | System.out.printf("\n后序遍历LRD的结果:"); 59 | tree.LRDTree(root); 60 | System.out.printf("\n"); 61 | break; 62 | case 4: 63 | System.out.printf("\n按层遍历的结果:"); 64 | tree.LevelTree(root); 65 | System.out.printf("\n"); 66 | break; 67 | default: 68 | break; 69 | } 70 | }while (menusel != 0); 71 | //深度 72 | System.out.printf("\n二叉树深度为:%d\n",tree.TreeDepth(root)); 73 | tree.ClearTree(root); 74 | root = null; 75 | } 76 | } 77 | 78 | class CBTType //二叉树结点类型 79 | { 80 | String data; //元素数据 81 | CBTType left; //左子树结点引用 82 | CBTType right; //右子树结点引用 83 | } 84 | 85 | class TreeOperation { 86 | static final int MAX = 20; 87 | static Scanner input = new Scanner(System.in); 88 | 89 | CBTType InitTree() { 90 | CBTType node; 91 | if ((node = new CBTType()) != null) { 92 | System.out.printf("请先输入一个根结点数据:\n"); 93 | node.data = input.next(); 94 | node.left = null; 95 | node.right = null; 96 | if (node != null) //如果二叉树的根结点不为空 97 | { 98 | return node; 99 | } else { 100 | return null; 101 | } 102 | } 103 | return null; 104 | } 105 | 106 | void AddTreeNode(CBTType treenode) { 107 | CBTType pnode, parent; 108 | String data; 109 | int menusel; 110 | 111 | if ((pnode = new CBTType()) != null) //分配内存 112 | { 113 | System.out.printf("输入二叉树结点数据:\n"); 114 | pnode.data = input.next(); 115 | pnode.left = null; //设置左右子树为空 116 | pnode.right = null; 117 | 118 | System.out.printf("输入该结点的父结点数据:"); 119 | data = input.next(); 120 | 121 | parent = TreeFindNode(treenode, data); //查找指定数据的结点 122 | if (parent == null) { 123 | System.out.printf("未找到该父结点!\n"); 124 | pnode = null; 125 | return; 126 | } 127 | System.out.printf("1.添加该结点到左子树\n2.添加该结点到右子树\n"); 128 | do { 129 | menusel = input.nextInt(); //输入选择项 130 | if (menusel == 1 || menusel == 2) { 131 | if (parent == null) { 132 | System.out.printf("不存在父结点,请先设置父结点!\n"); 133 | } else { 134 | switch (menusel) { 135 | case 1: // 添加到左结点 136 | if (parent.left != null) // 左子树不为空 137 | { 138 | System.out.printf("左子树结点不为空!\n"); 139 | } else { 140 | parent.left = pnode; 141 | } 142 | break; 143 | case 2: //添加到右结点 144 | if (parent.right != null) //右子树不为空 145 | { 146 | System.out.printf("左子树结点不为空!\n"); 147 | } else { 148 | parent.right = pnode; 149 | } 150 | break; 151 | default: 152 | System.out.printf("无效参数!\n"); 153 | } 154 | } 155 | } 156 | } 157 | while (menusel != 1 && menusel != 2); 158 | } 159 | } 160 | 161 | CBTType TreeFindNode(CBTType treenode, String data) { //查找结点 162 | CBTType ptr; 163 | if (treenode == null) { 164 | return null; 165 | } else { 166 | if (treenode.data.equals(data)) { 167 | return treenode; 168 | } else { 169 | if ((ptr = TreeFindNode(treenode.left, data)) != null) { 170 | return ptr; 171 | } else if ((ptr = TreeFindNode(treenode.right, data)) != null) { 172 | return ptr; 173 | } else { 174 | return null; 175 | } 176 | } 177 | } 178 | } 179 | 180 | CBTType TreeLeftNode(CBTType treeNode) // 获取左子树 181 | { 182 | if (treeNode != null) { 183 | return treeNode.left; //返回值 184 | } else { 185 | return null; 186 | } 187 | } 188 | 189 | CBTType TreeRightNode(CBTType treeNode) // 获取右子树 190 | { 191 | if (treeNode != null) { 192 | return treeNode.right; //返回值 193 | } else { 194 | return null; 195 | } 196 | } 197 | 198 | int TreeIsEmpty(CBTType treeNode) //判断空树 199 | { 200 | if (treeNode != null) { 201 | return 0; 202 | } else { 203 | return 1; 204 | } 205 | } 206 | 207 | int TreeDepth(CBTType treeNode) 208 | { 209 | int depleft,depright; 210 | if(treeNode == null) 211 | { 212 | return 0; // 对于空树,深度为0 213 | } 214 | else 215 | { 216 | depleft = TreeDepth(treeNode.left); //左子树深度(递归调用) 217 | depright = TreeDepth(treeNode.right); //右子树深度(递归调用) 218 | if(depleft > depright) 219 | { 220 | return depleft + 1; 221 | } 222 | else 223 | { 224 | return depright + 1; 225 | } 226 | } 227 | } 228 | 229 | void ClearTree(CBTType treeNode) //清空二叉树 230 | { 231 | if (treeNode != null) { 232 | ClearTree(treeNode.left); // 清空左子树 233 | ClearTree(treeNode.right); //清空右子树 234 | treeNode = null; // 释放当前结点所占据的内存 235 | } 236 | } 237 | 238 | void TreeNodeData(CBTType p) //显示结点数据 239 | { 240 | System.out.printf("%s", p.data); //输出结点数据 241 | } 242 | 243 | void LevelTree(CBTType treeNode) //按层遍历 244 | { 245 | CBTType p; 246 | CBTType[] q = new CBTType[MAX]; //定义一个顺序栈 247 | int head = 0, tail = 0; 248 | if (treeNode != null) { 249 | tail = (tail + 1) % MAX; //计算循环队列队尾序号 250 | q[tail] = treeNode; //将二叉树根引用进队 251 | } 252 | while (head != tail) { 253 | head = (head + 1) % MAX; 254 | p = q[head]; 255 | TreeNodeData(p); //处理队首元素 256 | if (p.right != null) { 257 | tail = (tail + 1) % MAX; //计算循环队列的队尾序号 258 | q[tail] = p.right; //将右子树引用进队 259 | } 260 | } 261 | } 262 | 263 | void DLRTree(CBTType treeNode) //先序遍历 264 | { 265 | if (treeNode != null) { 266 | TreeNodeData(treeNode); //显示结点数据 267 | DLRTree(treeNode.left); 268 | DLRTree(treeNode.right); 269 | } 270 | } 271 | 272 | void LDRTree(CBTType treeNode) { 273 | if (treeNode != null) { 274 | LDRTree(treeNode); //中序遍历左子树 275 | TreeNodeData(treeNode); //显示结点数据 276 | LDRTree(treeNode.right); // 中序遍历右子树 277 | } 278 | } 279 | 280 | void LRDTree(CBTType treeNode) { 281 | if (treeNode != null) { 282 | LRDTree(treeNode.left); //后序遍历左子树 283 | LRDTree(treeNode.right); //后序遍历右子树 284 | TreeNodeData(treeNode); //显示结点数据 285 | } 286 | } 287 | 288 | } 289 | -------------------------------------------------------------------------------- /JAVA学习/JavaIO.md: -------------------------------------------------------------------------------- 1 | # javaIO 2 | 3 | 标签: javaIO 4 | 5 | --- 6 | 7 | **Contents** 8 | - [什么是IO流](#流的概念和作用) 9 | - [IO流的分类](#IO流的分类) 10 | - [字符流和字节流](#字符流和字节流) 11 | - [文件字节、字符IO](#文件字节、字符IO) 12 | - [文件字节IO流](#文件字节IO流) 13 | - [文件字符IO流](#文件字符IO流) 14 | 15 | --- 16 | 17 | # Java流图结构 18 | 19 | ![](https://raw.githubusercontent.com/kentanvictor/STUDY/Image/JavaIO.jpg) 20 | 21 | # 流的概念和作用 22 | 23 | >流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。 24 | 25 | ## IO流的分类 26 | 27 | + 根据处理数据类型的不同可以分为:字符流和字节流 28 | + 根据数据流向不同分为:输入流和输出流 29 | 30 | ## 字符流和字节流 31 | 32 | > 字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别: 33 | > 34 | > + 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。 35 | > 36 | > + 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。 37 | > 38 | > + 字节流:一次读入或读出是8位二进制。 39 | > 40 | > + 字符流:一次读入或读出是16位二进制。 41 | > 42 | > **设备上的数据无论是图片或者视频,文字,它们都以二进制存储的。二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据。** 43 | > 44 | > **`结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。`** 45 | > 46 | > 47 | > 48 | 49 | 50 | # 文件字节、字符IO 51 | > Java程序可能经常需要获取磁盘上文件的有关信息或在磁盘上创建新的文件等,这就需要用到`File类`。 52 | > 53 | > ### 创建一个File对象的构造方法有3个: 54 | > + File(String filename); 55 | > + File(String directoryPath,String filename); 56 | > + File(File dir,String filename); 57 | > 58 | > *filename--文件名字;directoryPath--文件路径;dir--一个目录;`使用File(String filename)创建文件时,该文件被认为与当前应用程序在同一个目录中。`* 59 | > 60 | ### **文件的属性:** 61 |
 62 | public String getName();            //获取文件的名字
 63 | public boolean canRead();           //判断文件是否是可读的
 64 | public boolean canWrite();          //判断文件是否可被写入
 65 | public boolean exists();            //判断文件是否存在
 66 | public long length();               //获取文件的长度(单位是字节)
 67 | public String getAbsolutePath();    //获取文件的绝对路径
 68 | public String getParent();          //获取文件的父目录
 69 | public boolean isFile();            //判断文件是否是一个普通文件,而不是目录
 70 | public boolean isDirectory();       //判断文件是否是一个目录
 71 | public boolean isHidden();          //判断文件是否是隐藏文件
 72 | public long lastModified();         //获取文件最后修改的时间(时间是从1970年午夜至文件最后修改时刻的毫秒数)
 73 | 
74 | **例子:使用上述方法获取某些文件的信息:** 75 | 76 | ```java 77 | public class FileTest { 78 | public static void main(String[] args) { 79 | File f = new File("F:\\IDEA_code\\IOTest","newIO.txt"); 80 | System.out.println(f.getName() + "是可读的吗:" + f.canRead()); 81 | System.out.println(f.getName() + "的长度:" + f.length()); 82 | System.out.println(f.getName() + "的绝对路径:" + f.getAbsolutePath()); 83 | 84 | File newFile = new File("new.txt"); 85 | System.out.println("在当前目录下创建新文件:" + newFile.getName()); 86 | if (!newFile.exists()){ 87 | try { 88 | newFile.createNewFile(); //如果没有new.txt则创建一个 89 | System.out.println("创建成功!"); 90 | } catch (IOException e) { 91 | e.printStackTrace(); 92 | } 93 | } 94 | } 95 | } 96 | ``` 97 | 98 | ### **目录:** 99 | > 100 | + 创建目录 101 | >File对象调用方法public boolean mkdir()创建一个目录,如果创建成功返回true,否则返回false(如果该目录已经存在将返回false)。 102 | + 列出目录中的文件 103 | >如果File对象是一个目录,那么该对象调用下述方法列出目录下的文件和目录。 104 |
105 | public String[] list();             //用字符串形式返回目录下的全部文件
106 | public File[] listFiles();          //用File对象形式返回目录下的全部文件
107 | 
108 | >有时候需要列出目录下指定类型的文件,比如.java、.txt等扩展名的文件。可以使用File类的下述两个方法,列出指定类型的文件: 109 |
110 | public String[] list(FilenameFilter obj);           //该方法用字符串形式返回目录下的指定类型的所有文件
111 | public File[] listFiles(FilenameFilter obj);        //该方法用File对象形式返回目录下的指定类型的所有文件
112 | 
113 | >上述两个方法的参数FIlenameFilter是一个接口,该接口有个方法: 114 |
115 | public boolean accept(File dir,String name);
116 | 
117 | >File对象dirFile调用list方法时,需向该方法传递一个实现FilenameFilter接口的对象,list方法执行时,参数obj不断回调接口方法accept(File dir,String name),该方法中的参数dir为调用list的当前目录dirFile,参数name被实例化为dirFile,参数name被实例化为dirFile目录中的一个文件名,当接口方法返回true时,list方法就将名字为name的文件存放到返回的数组中。 118 | > 119 | **例子:列出当前目录下(应用程序所在的目录)下全部.java文件的名字:** 120 | ```java 121 | public class DirFileTest { 122 | public static void main(String[] args) { 123 | File dirFile = new File("F:\\IDEA_code\\Singleton_pattern\\src\\com\\dell\\example\\IODemo\\FileTest"); 124 | FileAccept fileAccept = new FileAccept(); 125 | fileAccept.setExtendName("java"); 126 | String fileName[] = dirFile.list(fileAccept); 127 | for (String name : fileName){ 128 | System.out.println(name); 129 | } 130 | } 131 | } 132 | ``` 133 | 134 | ```java 135 | public class FileAccept implements FilenameFilter { 136 | private String extendName; 137 | public void setExtendName(String s){ 138 | extendName = "." + s; 139 | } 140 | @Override 141 | public boolean accept(File dir, String name) { //重写接口中的方法 142 | return name.endsWith(extendName); 143 | } 144 | } 145 | ``` 146 | 147 | ## **文件字节IO流** 148 | 149 | ### 文件字节输入流 150 | `使用输入流通常包括4个基本步骤:` 151 | + 设定输入流的源 152 | + 创建指向源的输入流 153 | + 让输入流读取源中的数据 154 | + 关闭输入流 155 | 156 | 如果对文件读取需求比较简单,那么可以使用`FileInputStream类(文件字节输入流)`,该类是InputStream类的子类(以字节为单位读取文件),该类的实例方法都是从InputStream继承来的。 157 | 158 | + 构造方法: 159 | 160 | 可以使用FileInputStream类的下列构造方法创建指向文件的输入流。 161 | ```java 162 | FileInputStream(String name); 163 | FileInputStream(File file); 164 | ``` 165 | 第一个构造方法使用给定的文件名name创建FileInputStream流,第二个构造方法使用File对象创建FileInputStream流。参数name和file指定的文件称为输入流的源。 166 | 167 | **注意:** FileInputStream输入流打开一个到达文件的通道。当创建输入流的时候,可能会出现异常。 168 | ```java 169 | try{ 170 | FileInputStream in = new FileInputStream("hello.txt");//创建指向文件hello.txt的输入流 171 | } 172 | catch(IOException e){ 173 | System.out.println("File read error:" + e); 174 | } 175 | ``` 176 | 或 177 | ```java 178 | File f = new File("hello.txt"); //指定输入流的源 179 | try{ 180 | FileInputStream in = new FileInputStream(f); //创建指向源的输入流 181 | } 182 | catch(IOEception e){ 183 | System.out.println("File read error:" + e); 184 | } 185 | ``` 186 | + 使用输入流读取字节 187 | 188 | 文件字节流可以调用从父类继承的`read方法`顺序地读取文件,只要不关闭流,每次调用read方法就顺序地读取文件中的其余内容,直到文件的末尾或文件字节输入流被关闭。 189 | 190 | 字节输入流的read方法以字节为单位读取源中的数据。 191 |
192 |     int read()                              //输入流调用该方法从源中读取单个字节的数据,该方法返回字节值(0~255之间的一个整数),如果未读出字节就返回-1
193 |     int read(byte b[])                      //输入流调用该方法从源中试图读取b.length个字节到字节数组中,返回实际读取的字节数目,如果到达文件末尾则返回-1
194 |     int read(byte b[],int off,int len)      //输入流调用该方法从源中试图读取b.length个字节到字节数组中,返回实际读取的字节数目,如果到达文件末尾则返回-1,参数off指定从字节数组的某个位置开始存放读取的数据
195 |     
196 | + 关闭流 197 | 输入流都提供了关闭方法`close()`,尽管程序结束时会自动关闭所打开的流,但是当程序使用完流后,显式地关闭任何打开的流仍是一个好习惯。 198 | 199 | **例子:使用文件字节流读文件内容:** 200 | ```java 201 | public class InputTest { 202 | public static void main(String[] args) { 203 | int n = -1; 204 | byte[] a = new byte[100]; 205 | try { 206 | File f = new File("F:\\IDEA_code\\Singleton_pattern\\src\\com\\dell\\example\\IODemo\\InputStreamTest\\InputTest.java"); 207 | InputStream in = new FileInputStream(f); 208 | while ((n = in.read(a,0,100)) != -1){ 209 | String s = new String(a,0,n); 210 | System.out.println(s); 211 | } 212 | in.close(); 213 | } catch (IOException e) { 214 | e.printStackTrace(); 215 | } 216 | } 217 | } 218 | ``` 219 | ### 文件字节输出流 220 | `使用输出流通常包括4个基本步骤:` 221 | + 给出输出流的目的地 222 | + 创建指向目的地的输出流 223 | + 让输出流把数据写入到目的地 224 | + 关闭输出流 225 | 226 | 如果对文件写入需求比较简单,那么可以使用`FileOutputStream类(文件字节输出流)`,该类是OutputStream类的子类(以字节为单位写入文件),该类的实例方法都是从OutputStream继承来的。 227 | 228 | + 构造方法: 229 | 230 | 可以使用FileOutputStream类的下列具有刷新功能的构造方法创建指向文件的输出流。 231 | ```java 232 | FileOutputStream(String name); 233 | FileOutputStream(File file); 234 | ``` 235 | 第一个构造方法使用给定的文件名name创建FileOutputStream流,第二个构造方法使用File对象创建FileOutputStream流。参数name和file指定的文件称为输出流的目的地。 236 | 237 | **注意:** FileOutputStream输出流指向的文件不存在,java就会创建该文件,如果指向的文件是已存在的文件,输入流会刷新该文件(使文件长度为0)。创建输出流可能会出现异常。 238 | ```java 239 | try{ 240 | FileOutputStream out = new FileOutputStream("androidlab.txt");//创建指向文件androidlab.txt的输出流 241 | } 242 | catch(IOException e){ 243 | System.out.println("File read error:" + e); 244 | } 245 | ``` 246 | 或 247 | ```java 248 | File f = new File("androidlab.txt"); //指定输出流的目的地 249 | try{ 250 | FileOutputStream in = new FileOutputStream(f); //创建指向目的地的输出流 251 | } 252 | catch(IOEception e){ 253 | System.out.println("File read error:" + e); 254 | } 255 | ``` 256 | + 使用输出流写字节 257 | 258 | 文件字节流可以调用从父类继承的`write方法`顺序地写文件,只要不关闭流,每次调用write方法就顺序地写文件,直到流被关闭。 259 | 260 | 字节输出流的write方法以字节为单位向目的地写入数据。 261 |
262 |     void write(int n)                       //输出流调用该方法向目的地写入单个字节
263 |     void write(byte b[])                     //输出流调用该方法向目的地写入一个字节数组
264 |     void write(byte b[],int off,int len)     //给定字节数组中起始于偏移量off处取len个字节写入目的地
265 |     void close()                             //关闭输出流
266 |     
267 | + 关闭流 268 | 需要注意的是,在操作系统把程序所写到输出流上的那些字节保存到磁盘上之前,有时被存放在缓冲区中,通过调用`close()`方法,可以保证操作系统把缓冲区的内容写到它的目的地。 269 | 270 | **例子:使用文件字节流写入文件:** 使用具有刷新功能的构造方法指向文件android.txt的输出流,并向里面写入“Android”,然后再选择使用不刷新文件的构造方法指向android.txt,并向文件中追加“Lab”。 271 | ```java 272 | public class OutputTest { 273 | public static void main(String[] args) { 274 | byte[] a = "Android".getBytes(); 275 | byte[] b = "Lab".getBytes(); 276 | File newFile = new File("android.txt"); //输出目的地 277 | try { 278 | OutputStream out = new FileOutputStream(newFile); //指向目的地的输出流 279 | System.out.println(newFile.getName() + "的大小:" + newFile.length() + "字节"); 280 | out.write(a); //向目的地写入数据 281 | out.close(); 282 | out = new FileOutputStream(newFile,true); //准备向文件尾追加内容 283 | System.out.println(newFile.getName() + "的大小:" + newFile.length() + "字节"); 284 | out.write(b,0,b.length); 285 | System.out.println(newFile.getName() + "的大小:" + newFile.length() + "字节"); 286 | out.close(); 287 | } catch (IOException e) { 288 | e.printStackTrace(); 289 | } 290 | } 291 | } 292 | ``` 293 | 294 | ## **文件字符IO流** 295 | 文件字节输入、输出流的read和write方法使用字节数组读写数据,即以字节为单位处理数据。因此字节流不能很好地操作Unicode字符。**一个汉字在文件中占两个字节,如果使用字节流读取不当会出现“乱码”现象。** 296 |
297 |     字节            ------          字符
298 | FileInputStream     ------      FileReader
299 | FileOutputStream    ------      FileWriter
300 | 
301 | FileReader和FileWriter分别是Reader和Writer的子类,其构造方法分别是: 302 |
303 | FileReader(String filename);    FileReader(File filename);
304 | FileWriter(String filename);    FileWriter(File filename);
305 | FileWriter(String filename,boolean append);
306 | FileWriter(File filename,boolean append);
307 | 
308 | **字符输入流和输出流的`read`和`write`方法使用字符数组读写数据,即以字符为基本单位处理数据。** 309 | 310 | + **例子:用文件字符输入、输出流将文件“NotHelloWorld.txt”中的内容尾加到“AndroidLab.txt”中** 311 | ```java 312 | public class RWTest { 313 | public static void main(String[] args) { 314 | File sourceFile = new File("F:\\IDEA_code\\IOTest\\NotHelloWorld.txt");//读取的文件 315 | File targetFile = new File("F:\\IDEA_code\\IOTest\\AndroidLab.txt");//写入的文件 316 | char c[] = new char[100]; 317 | try{ 318 | Writer out = new FileWriter(targetFile,true); //指向目的地的输出流 319 | Reader in = new FileReader(sourceFile); //指向源的输入流 320 | int n = -1; 321 | while ((n = in.read(c)) != -1){ 322 | out.write(c,0,n); 323 | } 324 | out.flush(); 325 | out.close(); 326 | }catch (IOException e){ 327 | System.out.println("Error " + e); 328 | } 329 | } 330 | } 331 | ``` 332 | --------------------------------------------------------------------------------