1.public,protected,friendly,private权限
作用域 当前类 同一package 子孙类 其他package
public √ √ √ √
protected √ √ √ ×
friendly √ √ × ×
private √ × × ×
注:不写时默认为friendly
public √ √ √ √
protected √ √ √ ×
friendly √ √ × ×
private √ × × ×
注:不写时默认为friendly
2.夜神模拟器安装包后会另存一个副本apk,如果不清理,这个副本apk会越来越多,而且存储在c盘。因此需要留意并且清理.一般在C:\Users\Administrator\Nox_share\App这个目录中
3.JDK中有一个UUID ---import java.util.UUID;可以用于产生唯一标识符,比如作为token等等东西,一个示例代码
public class TokenUtil {
public static Map<String, Integer> tokens = new HashMap<String, Integer>();
public static String generateToken(Integer aid){
// generate token
UUID uuid = UUID.randomUUID();
String token = uuid.toString().replaceAll("-", "").toLowerCase();
// update token
tokens.put(token, aid);
return token;
}
public static Integer getAid(String token){
return tokens.get(token);
}
}
4.cpp的vector ,hash_map等容器的一些使用说明。
cpp的这些容器与java等不太一样,主要由于其开放性的指针导致其更加灵活。
基本上遍历与查找都是检索其指针来进行处理,其迭代器就是检索用的指针,从容器起始位置到末尾,xxx.begin()到xxx.end(),检索所有元素。当检索到之后,只需要根据指针运算便可获取该元素的具体内容。
举例:1 vector
std::vector<int> testVec;
if(testVec.empty())
{
printf("empty!!!");
}
for(int i =0;i<10;i++)
{
testVec.push_back(i+1);
}
for(std::vector<int>::iterator pointer=testVec.begin();pointer!=testVec.end();pointer++)
{
printf("%d ",*pointer);
}
int tempIdx = 0;
for(int i=0;i<10;i++)
{
if(1 == testVec.at(i))
{
tempIdx = i;
break;
}
}
testVec.erase(testVec.begin()+tempIdx);
printf("\n");
for(std::vector<int>::iterator pointer=testVec.begin();pointer!=testVec.end();pointer++)
{
printf("%d ",*pointer);
}
2.hash_map: first就是其key指针,second是其元素指针
hash_map<int,int> hm;
hm[0] = 1001;
hm[1] = 1002;
hm[2] = 1003;
hm[3] = 1004;
hm[4] = 1005;
for(hash_map<int,int>::iterator i = hm.begin();i!=hm.end();i++)
{
printf("index is %d,value is %d",(*i).first,(*i).second);
}
5.面向对象语言的继承通用技巧
基类的方法是public的,派生类继承后,设置为private,那么派生类本身指针不能访问,不过通过多态方式创建的比如
BaseClass c1 = new ChildClass后,c1可以通过访问BaseClass的f1然后通过虚函数等的机制跳转到派生类函数地址中去。这样就可以来访问被设置为private的派生类函数了。
不过具体意义,暂时不知道为何要绕这么一圈来做一个明明很简单的行为。
6.MySql远程登陆时的问题(收集 复制粘贴:https://blog.csdn.net/itlqi/article/details/50592510)
a.Mysql host '192.168.1.1' is not allowed to connect to this mysql server
如何解决:
1。 改表法。
可能是你的帐号不允许从远程登陆,只能在localhost。登录安装的那台电脑,登入mysql后,更改 "mysql" 数据库里的 "user" 表里的 "host" 项,从"localhost"改称"%"
mysql>use mysql;
mysql>update user set host = '%' where user = 'root';
mysql>select host, user from user;
2. 授权法。
例如,你想myuser使用mypassword从任何主机连接到mysql服务器的话。
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;
如果你想允许用户myuser从ip为192.168.1.6的主机连接到mysql服务器,并使用mypassword作为密码
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'192.168.1.3' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;
如果你想允许用户myuser从ip为192.168.1.6的主机连接到mysql服务器的dk数据库,并使用mypassword作为密码
GRANT ALL PRIVILEGES ON dk.* TO 'myuser'@'192.168.1.3' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;
7.Mysql 5.7的安装配置细节
a.基本安装与配置如图
b.遇到如net start mysql无法正常启动的问题,报错的问题,处理如下
如果是出现: 发现发现系统错误2,系统找不到指定的文件。
说明是安装路径出错了,即如图
解压在D盘,结果在c盘安装,肯定出错,因此改为如下
说白了就是cmd要进入到文件夹下操作才有意义,否则出错:
一个在已经存在data文件夹的使用示例:
8.cpp中的字符串分割方法:
一:使用strtok(来源 https://www.cnblogs.com/Bob-tong/p/6610806.html)
字符串函数之Strtok()函数
Strtok()函数详解:
该函数包含在"string.h"头文件中
函数原型:
函数功能:
切割字符串,将str切分成一个个子串
函数参数:
str:在第一次被调用的时间str是传入需要被切割字符串的首地址;在后面调用的时间传入NULL。
delimiters:表示切割字符串(字符串中每个字符都会 当作分割符)。
函数返回值:
当s中的字符查找到末尾时,返回NULL;
如果查不到delimiter所标示的字符,则返回当前strtok的字符串的指针。
#include<stdio.h>
#include<string.h>
int main(void)
{
char buf[]="hello@boy@this@is@heima";
char*temp = strtok(buf,"@");
while(temp)
{
printf("%s ",temp);
temp = strtok(NULL,"@");
}
return 0;
}
9.c语言中的输出控制符号
%c 单个字符
%d 十进制整数(int)
%ld 十进制整数(long)
%f 十进制浮点数(float)
%lf 十进制浮点数(double)
%o 八进制数
%s 字符串(char)
%u 无符号十进制数(DWORD)
%x 十六进制数(0x00000)
10. cpp + mysql写入二进制
来源:https://blog.csdn.net/nibiru_holmes/article/details/51387047
写:
int CFinger_PrintDlg::Connect_Mysql(byte b_name[], byte* b_data,int len_of_data) {
const char user[] = "root";
const char pswd[] = "toor";
const char host[] = "127.0.0.1";
const char db[] = "Fingerprint";
int res;
int listrow = 0;
char sql_buf[100] = {};
unsigned int port = 3306;
bool return_result = false;
MYSQL myCont;
MYSQL_RES *result;
MYSQL_ROW sql_row;
HWND hWnd = GetSafeHwnd();
TCHAR sql_buf_t[100] = {};
//CListCtrl* list = (CListCtrl*)GetDlgItem(IDC_LIST3);
mysql_init(&myCont);
if (mysql_real_connect(&myCont, host, user, pswd, db, port, NULL, 0))
{
PostMessage(WM_MyMessage, (WPARAM)&L"连接数据库成功!!", (LPARAM)NULL);
}
mysql_query(&myCont, "SET NAMES GBK"); //设置编码格式
char buf[2000] = { NULL };
unsigned int escape_size = 2 * len_of_data + 2;
char* escape_object = (char *)malloc(escape_size);
escape_size = mysql_real_escape_string(&myCont, (char*)escape_object, (char *)b_data, len_of_data);
int sql_len = sprintf_s(buf, "insert into finger3(info) values('%s')", escape_object);
res = mysql_real_query(&myCont,buf, sql_len);
if (!res)
{
return_result = TRUE;
if (!res)
{
PostMessage(WM_MyMessage, (WPARAM)L"写入成功", NULL);
}
}
else
{
PostMessage(WM_MyMessage, (WPARAM)L"写入失败", NULL);
}
mysql_close(&myCont);
return return_result;
}
读:
void* CFinger_PrintDlg::Read_Mysql()
{
if (!g_connect){
SendMessage(WM_MyMessage, (WPARAM)L"数据库未连接...", NULL);
return 0;
}
MYSQL_RES *res = NULL;
MYSQL_ROW row;
unsigned long *row_len;
char *object = NULL;
//const char *sql = "select info from final where id=";
char sql[100] = { NULL };
unsigned long objsize;
int ret;
for (int i = 1; i <= 10; i++){
sprintf_s(sql, "select info from final where id='%d'", i);
ret = mysql_real_query(&myCont, sql, strlen(sql));
if (ret){
PostMessage(WM_MyMessage, (WPARAM)L"读取失败1", NULL);
}
res = mysql_store_result(&myCont);
if (res == NULL){
PostMessage(WM_MyMessage, (WPARAM)L"读取失败2", NULL);
}
/* important */
row = mysql_fetch_row(res);
row_len = mysql_fetch_lengths(res); /* get the object's length */
if (row_len == NULL){
PostMessage(WM_MyMessage, (WPARAM)L"读取失败3", NULL);
}
objsize = row_len[0];
object = (char*)malloc(objsize);
if (object == NULL){
PostMessage(WM_MyMessage, (WPARAM)L"读取失败4", NULL);
}
memcpy(object, row[0], objsize);
if (BIOKEY_DB_ADD(ZKFingerHandle, i, objsize, (byte*)object)){
PostMessage(WM_MyMessage, (WPARAM)L"读取成功", NULL);
}
}
g_connect = false;
;
//mysql_close(&myCont);
mysql_free_result(res);
return NULL;
}
更新:
int CFinger_PrintDlg::Updata_Mysql(byte b_name[], byte* b_data, int len_of_data){
if (!g_connect){
SendMessage(WM_MyMessage, (WPARAM)L"数据库未连接...", NULL);
return 0;
}
int res;
bool return_result = false;
mysql_query(&myCont, "SET NAMES GBK"); //设置编码格式
char buf[2000] = { NULL };
unsigned int escape_size = 2 * len_of_data + 2;
char* escape_object = (char *)malloc(escape_size);
escape_size = mysql_real_escape_string(&myCont, (char*)escape_object, (char *)b_data, len_of_data);
CString id_cs;
CString name_cs;
int id;
char name[20] = { NULL };
GetDlgItem(IDC_EDIT1)->GetWindowTextW(id_cs);
GetDlgItem(IDC_EDIT2)->GetWindowTextW(name_cs);
id = _wtoi(id_cs);
WideCharToMultiByte(CP_ACP, 0, name_cs, -1, name, name_cs.GetLength(), NULL, NULL);
//int sql_len = sprintf_s(buf, "insert into final(id,name,info) values('%d','%s','%s')", id, name, escape_object);
//UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
int sql_len = sprintf_s(buf, "UPDATE final SET name='%s',info='%s' where id ='%d'", name, escape_object, id);
res = mysql_real_query(&myCont, buf, sql_len);
if (!res)
{
return_result = TRUE;
if (!res)
{
PostMessage(WM_MyMessage, (WPARAM)L"更新成功", NULL);
}
}
else
{
PostMessage(WM_MyMessage, (WPARAM)L"更新失败", NULL);
}
//mysql_close(&myCont);
g_connect = false;
return return_result;
}
11.lua_newuserdata的使用来源 https://www.cnblogs.com/ring1992/p/6003405.html
在使用前,首先回顾一点,lua与c之间是通过内存直接交互的,在内存中开辟一个叫lua栈的空间,那么各种数据都会通过这个栈来交互。过程就是
要么c把数据推入栈,lua把数据从栈取出;要么lua把数据推入栈,c把数据取出。记住这个行为,对lua的与c的交互概念就清晰了。
定义一个c的结构体
static struct StudentTag
{
char *strName; // 学生姓名
char *strNum; // 学号
int iSex; // 学生性别
int iAge; // 学生年龄
};
创建一个luauserdata含有StudentTag,注意:这个luauserdata就是这个StudentTag的内存容量,容量有了但是二进制数据内容还没有,那么需要将其转换成对应的二进制数据因此在lua_newuserdata前强制将空间中二进制转换成StudentTag地址类型。
static int Student(lua_State *L)
{
size_t iBytes = sizeof(struct StudentTag);
struct StudentTag *pStudent;
pStudent = (struct StudentTag *)lua_newuserdata(L, iBytes);
return 1; // 新的userdata已经在栈上了
}
12.Lua 字符串base64处理:https://blog.csdn.net/zwc2xm/article/details/52366686
local function encodeBase64(source_str)
local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
local s64 = ''
local str = source_str
while #str > 0 do
local bytes_num = 0
local buf = 0
for byte_cnt=1,3 do
buf = (buf * 256)
if #str > 0 then
buf = buf + string.byte(str, 1, 1)
str = string.sub(str, 2)
bytes_num = bytes_num + 1
end
end
for group_cnt=1,(bytes_num+1) do
local b64char = math.fmod(math.floor(buf/262144), 64) + 1
s64 = s64 .. string.sub(b64chars, b64char, b64char)
buf = buf * 64
end
for fill_cnt=1,(3-bytes_num) do
s64 = s64 .. '='
end
end
return s64
end
local function decodeBase64(str64)
local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
local temp={}
for i=1,64 do
temp[string.sub(b64chars,i,i)] = i
end
temp['=']=0
local str=""
for i=1,#str64,4 do
if i>#str64 then
break
end
local data = 0
local str_count=0
for j=0,3 do
local str1=string.sub(str64,i+j,i+j)
if not temp[str1] then
return
end
if temp[str1] < 1 then
data = data * 64
else
data = data * 64 + temp[str1]-1
str_count = str_count + 1
end
end
for j=16,0,-8 do
if str_count > 0 then
str=str..string.char(math.floor(data/math.pow(2,j)))
data=math.mod(data,math.pow(2,j))
str_count = str_count - 1
end
end
end
local last = tonumber(string.byte(str, string.len(str), string.len(str)))
if last == 0 then
str = string.sub(str, 1, string.len(str) - 1)
end
return str
end
13.TCP与UDP总结 来源:https://www.cnblogs.com/xiaomayizoe/p/5258754.html
TCP与UDP区别总结:
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
更详细的:https://blog.csdn.net/liuyanfeier/article/details/52787037
14.JavaScript重载设计思路
js并没有系统层面的重载,不过玩家可以通过条件判断参数来选择对应的函数处理。那么利用这种想法可以实现:
- function cut(obj) {
- if (typeof obj === "string") {
- console.log("我们在剪纸");
- }
- else if (typeof obj === "boolean") {
- console.log("我们在剪肉");
- }
- }
这种方式,当然可以进行更多的完善。
更多详情:https://blog.csdn.net/teajs/article/details/53788238
15.win10家庭版完全禁止更新
我用的一个笔记本是Thinkpad X1 Carbon,预装了Win 10家庭版,目前用的时候不知道怎么回事,每次Windows Update都会使风扇一直转。联想+微软Win10真是不靠谱到极致。所以想看看怎么把自动更新关掉。
有些教程里介绍用服务设置,例如:https://blog.csdn.net/MileyPriencess/article/details/78176259
(在左下角视窗图标上点右键——计算机管理——服务和应用程序——服务)
但是把自动更新服务禁掉后,过两天它又自动开启了。而Win 10家庭版是不带组策略编辑器的,其实可以安装。具体方法为:新建一个文本文件——把下面这些代码拷贝进去:
pushd "%~dp0"
dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txt
dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum >>List.txt
for /f %%i in ('findstr /i . List.txt 2^>nul') do dism /online /norestart /add-package:"C:\Windows\servicing\Packages\%%i"
然后把文本文件命名为“组策略.bat”,右键管理员身份运行,运行完后按键盘上“Windows图标+r”,输入gpedit.msc,就可以打开本地组策略编辑器了,然后选择“计算机配置”——“管理模板”——“Windows组件”——“Windows更新”——右侧列表中选择“配置自动更新”双击——选择“已禁用”,就可以彻底关闭自动更新了。
来源:https://blog.csdn.net/qysh123/article/details/81610756?utm_source=copy
16.socket本身的心跳机制
在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。所以说,最好还是自己来实现符合现实需求的心跳。
17.eclipse打包时,太多的启动名称
xxx盘:\EclipseWorkSpace\.metadata\.plugins\org.eclipse.debug.core\.launches在这个文件夹里就是luanch文件,全部删除,就不会有了。删除后,要重启eclipse。因为文件名称它启动时会载入内存。
18.mysql密码过期的处理
一.先改系统时间,改一次 通过cmd mysql -u root -p 登陆一次,成功后,修改密码SET PASSWORD = PASSWORD(‘root’);改完后,再设置永久生效ALTER USER '用户名'@'localhost' PASSWORD EXPIRE;
19.ccc跨域问题
跨域问题吐血总结:
0. 首先只有浏览器下才有跨域问题,native下是没有的。
1. 如果是跨域请求图片的话,Canvas和WebGL都会有控制台报错,但是Canvas下能加载出图片,因此如果可以只用Cavas模式且没有其它跨域请求的话,用Canvas模式即可(忽略控制台报错。。。)。否则转2。
2. 如果请求的资源在你自己的服务器上,那么在返回的http请求的header中加上Access-Control-Allow-Origin:*字段即可。如果是文本资源(如JSON),还可以用JSONP,但是比较麻烦,不如header方便。否则转3。
3. 如果请求的资源不在你自己的服务器上,那么需要自己搭建一个服务器中转一下请求(下载请求的资源,输出的时候加上Access-Control-Allow-Origin:*字段)。例如简单使用PHP中转跨域图片的示例代码如下(正式使用时需要判断$_GET['url']是否是合法的http地址,否则可能加载出服务器本地文件,有安全隐患):
// CrossOrigin.php
<?php
header('Access-Control-Allow-Origin:*');
header('Content-type: image/png');
if (isset($_GET['url'])) {
echo file_get_contents($_GET['url']);
}
这样游戏中请求http://yourdomain/CrossOrigin.php?url=http://otherdomain/someimage.png,就可以加载出图片了。
2、3两步的关键都在于服务器返回的header中需要有Access-Control-Allow-Origin: *,浏览器才不会拦截这个请求和报跨域错误。如果希望自己的中转服务只可用于某个域名的跨域请求而不是任何请求,把Access-Control-Allow-Origin:*改为Access-Control-Allow-Origin: http(s)://yourdomain(or IP):port即可(*代表允许所有),注意:协议(http与https)、域名或IP、端口号(:port默认为80)都相同才属于同一域。
20.安卓调用系统卸载
Uri packageUri = Uri.parse("package:"+MainActivity.this.getPackageName());
Intent intent = new Intent(Intent.ACTION_DELETE,packageUri);
startActivity(intent);
21.安卓9 http不能请求问题
方案一:使用https与wss
方案二:将targetSdkVersion设置<27
方案三:
在targetSdkVersion >=27 的app运行在android 9时如果是http请求会报错,解决办法是添加xml设置 res/xml/network_security_config
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
在AndroidManifest.xml中配置
<application
...
android:networkSecurityConfig="@xml/network_security_config"
.../>
就能解决无法请求http请求了
21.jdk8 之后的版本相关问题。
sun.misc.BASE64Encoder() 与 sun.misc.BASE64Decoder()等包含于sun包中的模块基本上都被删除了。这2个功能从jdk8开始也已经提供了相应的新的模块。
Encoder encoder = Base64.getEncoder();
String result = encoder.encodeToString(out.toByteArray());
Decoder decoder = Base64.getDecoder();
byte[] compressed = decoder.decode(compressed_String);
--------------------------jaxb相关模块也被删除了----------------------------
需要手动下载4个包:
javax.activation-1.2.0.jar
jaxb-api-2.3.0.jar
jaxb-core-2.3.0.jar
jaxb-impl-2.3.0.jar
22.java 中的 Void 注意是大写的V
主要是为了作为泛型中的class类型参数使用,比如A<Void> A中的一个泛型方法就可以变成的 Void func().因为void不可以当作class,所以官方弄了个Void当class用。
23.uglifyjs不支持es6怎么办?
使用分支版本https://github.com/mishoo/UglifyJS2/tree/harmony
npm install uglify-es -g
即可。
24.js的prototype的意义是什么?
js的函数都有这个属性,因为js的类就是基于函数来实现的,比如:
function aa(){} aa a = new aa(); 那么就是创建了一个实例,而a中的各种参数与函数都是从aa的prototype中复制一份的。当然如果都是参数,那么复制一份是没有问题的,但是函数呢?函数本来就只需要一份样本,不需要不停的重复复制。因此在对于一些单例性质的概念就可以使用prototype来添加,而非单例性质的东西直接this.xxx添加即可。
所以在js的类中添加函数时,一般都是 aa.prototype.newFunc = ....;
另外如果只是一个静态单例,那么aa.staticArg = ...;即,直接用类名(函数名)访问。