class Demo01 { public static void main(String[] args) { //与 并且,只有两边都为true,结果为true,只要一边为false,结果为false /*System.out.println(true & true); //true System.out.println(true & false);//false System.out.println(false & false);//false //短路与 System.out.println(true && true);//true System.out.println(true && false);//false System.out.println(false && false);//false //区别:&&短路与左边表达式能够判定出整体结果,右边表达式就不执行。 //&不管左边是否能 int a=1; System.out.println*/ // /*System.out.println(true | true); //true System.out.println(true | false);//true System.out.println(false | false);//false System.out.println(true || true); System.out.println(true || false); System.out.println(false || false);*/ //^异或:只要两边表达式的值相同,结果为false //只要两边表达式值不同,结果为true System.out.println(true ^ true); //false System.out.println(true ^ false);//true System.out.println(false ^ false);//false //!
requests模块 python中原生的一款基于网络请求的模块,其作用是:模拟浏览器发起请求。 如何使用:
1.指定url url=...... 2.发起请求:使用get方法发起get请求,该方法会返回一个响应对象,参数url表示请求对应的url response=requests.get(url =url) 3.获取响应数据:通过调用响应对象的text属性,返回响应对象中存储的字符串形式的响应数据 page_text=response.text 4.持久化存储 with open ('文件名','w',encoding='utf-8') as fp: fp.write(page_text) print('数据爬取完毕!') 示例:
点击查看代码 import requests #url url='https://www.baidu.com/' response=requests.get(url=url) response.encoding='uft-8' page_text=response.text with open(./爬虫/baidu.html,'w',encoding='utf-8') as fp: fp.write(page_text) 实战巩固: 1.爬取搜狗指定词条的对应搜索结果 点击查看代码 import requests if __name__== __main__: keyword=input('enter a key word:') #UA伪装:将爬虫程序伪装为浏览器客户端身份进行访问请求。(用于解决服务器端检测用户身份标识的问题) # UA:user-agent:请求客户端的身份标识 headers={ 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36' } params={ 'query':keyword } url='https://www.
项目开始是因为工作需要一个聊天室功能,但是因为某些原因最终选用的是基于xmpp协议的Strophe.js写的。于是就想用node自己写一套,本来只是想简单的写个聊天页面,但是写完了又不满意,所以不断的重构(似乎可以理解产品经理为什么老是改需求了๑乛◡乛๑)。
很多东西,比如mongodb,我也是第一次用,以前只接触过mysql。所以都是一边学一边写,利用工作之余的时间,断断续续的写了几个月,包含了一整套的前后端交互。uI是按照自己的感觉来的,没有设计天分(话说主题切换到现在还只有一套主题,实在是不好设计啊~),轻喷---。项目还有很多需要优化完善的地方,欢迎大家提到issues(文末有q群,欢迎一起学习交流)。
闲话少说,本文主要讲项目的设计流程,以及部分功能实现思路。对项目感兴趣的同学请移步源码 Vchat — 从头到脚,撸一个在线聊天的web应用(vue + node + mongodb)。
这是分隔线---------------------------------------深夜码字,最近真冷
项目架构 技术栈 前端主要采用了vue全家桶,没什么多说的,脚手架构建项目,vuex状态管理,vue-router控制路由,axios进行前后端交互。后端是基于node搭的服务,用的是express。我为什么不用koa呢,纯粹是图方便,因为koa不熟(捂脸)。聊天最重要的当然是通信,项目用socket.io来进行前后端通信。
数据库是mongoDB,主要有用户、好友、群聊、消息、表情、号码池等。
功能概览 功能设计 登录注册 Vchat中用户注册时,会随机指定一个code号码,而这个code号是从预先生成的一个号码池(号码池存在mongodb)中取的。初始指定10000001-10001999的号码段为用户code, 100001-100999的号码段为群聊code。用户可以凭借code号或者账号登录 // 号码池设计 * code 号码 * status 1 已使用 0 未使用 * type 1 用户 2 群聊 * random 随机数索引,用于随机查找某一条 // user表主要字段 * name 账号 * pass 密码 * avatar 头像 * signature 个性签名 * nickname 昵称 * email 邮件 * phone 手机 * sex 性别 * bubble 气泡 * projectTheme 项目主题 * wallpaper 聊天壁纸 * signUpTime 注册时间 * lastLoginTime 最后一次登录时间 * chatColor 聊天文字颜色 * province 省 * city 市 * town 县 * conversationsList 会话列表 * cover 封面列表 注册时,需要判断账号是否已存在,以及随机取得的code需要在号码池中标记为已被使用,用户密码用md5加密等。
一、查看文件类型的方式:
①ls-l/ls-ld 或者ll [ls-l ---查看文件 ls-ld ---查看路径 ll ----跟ls -l 一样] ②file 命令 查看文件的类型 例:file 1.txt
格式:file 文件名
③stat 命令 查看文件的详细属性(其中包括文件时间属性)
二、Linux下七种文件类型:
l(link):链接文件;
d:目录文件;
分为三种文件:
1、纯文本文件(ASCII):内容可直接读取,数字字母等,比如配置文件几乎都是这种文件;
2、二进制文件(binnary):Linux中可执行文件,比如命令文件,cat ls cp;
3、数据格式的文件(date):具有特定格式的文件。
-:普通文件;
c:字符设备;
s(sock):
prw:管道文件;
三、Linux下拓展名的作用:
1、.tar、.tar.gz、.tgz、.zip、.tar.bz表示压缩文件,创建命令一般为tar,gzip,unzip等
2、sh 表示shell脚本文件,通过shell语言开发的程序;
3、.pl 表示perl语言文件,通过perl语言开发的程序;
4、.py 表示python语言的文件,通过python语言开发的程序;
5、.html、.htm、.php、.jsp、.do表示网页语言的文件;
6、.conf 表示系统服务的配置文件;
7、.rpm 表示rpm安装包文件
四、Linux常用的系统目录
基本目录结构:bin:全称binary,含义是二进制。该目录中存储的都是一些二进制文件,文件都是可以被运行的。dev:该目录中主要存放的是外接设备,例如盘、其他的光盘等。在其中的外接设备是不能直接被使用的,需要挂载(类似windows下的分配盘符)。etc:该目录主要存储一些配置文件。home:表示“家”,表示除了root用户以外其他用户的家目录,类似于windows下的User/用户目录。proc:process,表示进程,该目录中存储的是Linux运行时候的进程。root:该目录是root用户自己的家目录。sbin:全称super binary,该目录也是存储一些可以被执行的二进制文件,但是必须得有super权限的用户才能执行。tmp:表示“临时”的,当系统运行时候产生的临时文件会在这个目录存着。usr:存放的是用户自己安装的软件。类似于windows下的program files。var:存放的程序/系统的日志文件的目录。mnt:当外接设备需要挂载的时候,就需要挂载到mnt目录下。
访问http://your-ip/uploadfiles/nginx.png和http://your-ip/uploadfiles/nginx.png/.php查看效果。
这里尝试上传一个图片马
将图片保存为png格式,并用记事本打开,将其插入进一句话木马。上传该图片马。
OS模块 #查看当前路径及路径下的文件 1.os.getcwd() :查看当前所在路径 2.os.listdir(path) :列举path目录下的所有文件。返回的是列表类型 #绝对路径 1.os.path.abspath(path) :返回当前文件位置的绝对路径。 2.os.path.realpath(path) :返回当前文件位置的绝对路径。 #路径拼接 os.path.join(path1, path2, ...) :将入参的path进行组合,若其中有绝对路径,则之前的path将被删除 #创建目录(文件夹) os.mkdir(r'aaa') 使用相对路径 在当前执行文件所在的路径下创建一个aaa文件夹 os.mkdir(r'bbb/ccc') mkdir只能创建单级目录 #删除目录(文件夹) os.rmdir(r'aaa') 可以删除单级目录 os.rmdir(r'bbb') 只能删空的单级目录 #删除文件、重命名文件 os.remove(r'a.txt') os.rename(r'a.txt', r'aaa.txt') #判断文件是否存在 print(os.path.exists(r'ATM')) True 判断所给的路径是否存在 print(os.path.isdir(r'ATM')) True 判断路径是否是一个文件夹 print(os.path.isfile(r'ATM')) False 判断路径是否是一个文件 #获取文件大小(字节 bytes) print(os.path.getsize(r'ATM')) 128bytes print(os.path.getsize(r'a.txt')) 14bytes sys模块 sys模块是与python解释器交互的一个接口 1.列举当前执行文件所在的sys.path print(sys.path) 2.获取解释器版本信息 print(sys.version) 3.获取平台信息 print(sys.platform) 4.自定义命令行操作 print(sys.argv) 5.退出程序 print(sys.exit(n)) json 模块 就是一个序列化模块 主要用于跨语言传输数据(相当于一个翻译器) 序列化的目的: 1、以某种存储形式使自定义对象持久化; 2、将对象从一个地方传递到另一个地方。 3、使程序更具维护性。 json格式数据的具体特征: 1、据上图可知:数据基于网络传输肯定是二进制格式 2、python中只有字符串可以转成bytes类型(编码encode()) 3、由上述推论可知 json格式数据 本质应该属于字符串类型 4、双引号是json格式数据独有的标志符号 import json d = {'username':'jason','pwd':123} res = json.
hashlib加密模块 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。什么是摘要算法呢?摘要算法又称哈希算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串。
#具体使用 import hashlib md = hashlib.md5() # 生成一个具有加密功能的对象 md.update('hello'.encode('utf-8')) # 往对象里传明文数据 update只能接受bytes类型的数据 md.update(b'hi') # 往对象里传明文数据 update只能接受bytes类型的数据 print(md.hexdigest()) # 获取明文数据对应的密文 #分多次传入内容,但是生成的密文还是一样的 不同的算法 使用方法是相同的
密文的长度越长 内部对应的算法越复杂
但是
时间消耗越长 占用空间更大 通常情况下使用md5算法 就可以足够了
该类方法虽然与编码与解码相类似,但当明文被加密后是不能被解密的,并且加密的密文也是固定的。所以对于一些简单的明文加密后确实可以进行破解,但是破解方法也是比较暴力的穷举法,一个答案一个答案去验证。 加盐处理 import hashlib md = hashlib.md5() # 公司自己在每一个需要加密的数据之前 先手动添加一些内容 md.update(b'oldboy.com') # 加盐处理 md.update(b'hello') # 真正的内容 print(md.hexdigest()) 动态加盐 import hashlib def get_md5(data): md = hashlib.md5() md.update('加盐'.encode('utf-8')) md.update(data.encode('utf-8')) return md.
单元测试
Junit
public class UserService { public String login(String loginName, String password) { if (admin.equals(loginName) && 123456.equals(password)) { return success; } return 用户名或密码错误; } } public class UserServiceTest { /** * 测试方法要求: * 1.必须public修饰 * 2.没有返回值没有参数 * 3.必须使注解@Test修饰 */ @Test public void testLogin() { UserService userService = new UserService(); String rs = userService.login(admin, 123456); // 断言预期结果的正确性 /** * 参数一:测试失败的提示信息 * 参数二:期望值 * 参数三:实际值 */ Assert.assertEquals(登录业务功能方法有误, success, rs); } } Junit常用注解
一、前言 1.1 编译语言(编译器)vs 解释语言(解释器) 编译型语言:
c, c++等 速度快:所有代码一起编译,再执行。执行起来效率更快 跨平台性差:但编译器依赖平台,不同的操作系统要重新编译一次 解释型语言:
Python等 速度慢:代码逐句解释,并执行。执行效率比编译型慢 跨平台型好:但解释器不依赖平台,不同的操作系统无需重新解释 1.2 Python的特点 面向对象 强大标准库 海量第三方模块 可扩展性 1.3 python 2.x vs python 3.x 解释器不同,中文展示效果不同:
其他解释器:
二、运行Python的三种方式 2.1 解释器运行 python/python3 XXX.py
2.2 官方交互式运行 - python shell 用法:
优缺点:
第一章 类型推导 1. 理解模板类型推导 在模板类型推导时,有引用的实参会被视为无引用,他们的引用会被忽略 对于通用引用的推导,左值实参会被特殊对待 对于传值类型推导,const和/或volatile实参会被认为是non-const的和non-volatile的 在模板类型推导时,数组名或者函数名实参会退化为指针,除非它们被用于初始化引用 2. **理解auto类型推导 auto类型推导通常和模板类型推导相同,但是auto类型推导假定花括号初始化代表std::initializer_list,而模板类型推导不这样做 在C++14中auto允许出现在函数返回值或者lambda函数形参中,但是它的工作机制是模板类型推导那一套方案,而不是auto类型推导 3. **理解decltype decltype总是不加修改的产生变量或者表达式的类型。 对于T类型的不是单纯的变量名的左值表达式,decltype总是产出T的引用即T&。 C++14支持decltype(auto),就像auto一样,推导出类型,但是它使用decltype的规则进行推导。 4. 学会查看类型推导结果 类型推断可以从IDE看出,从编译器报错看出,从Boost TypeIndex库的使用看出 这些工具可能既不准确也无帮助,所以理解C++类型推导规则才是最重要的 第二章 Auto 5. **优先考虑auto而非显式类型声明 auto变量必须初始化,通常它可以避免一些移植性和效率性的问题,也使得重构更方便,还能让你少打几个字。 正如Item2和6讨论的,auto类型的变量可能会踩到一些陷阱。 6. **auto推导若非己愿,使用显式类型初始化惯用法 不可见的代理类可能会使auto从表达式中推导出“错误的”类型 显式类型初始器惯用法强制auto推导出你想要的结果 第三章 移步现代C++ 7. **区别使用()和{}创建对象 括号初始化是最广泛使用的初始化语法,它防止变窄转换,并且对于C++最令人头疼的解析有天生的免疫性 在构造函数重载决议中,括号初始化尽最大可能与std::initializer_list参数匹配,即便其他构造函数看起来是更好的选择 对于数值类型的std::vector来说使用花括号初始化和小括号初始化会造成巨大的不同 在模板类选择使用小括号初始化或使用花括号初始化创建对象是一个挑战。 8. **优先考虑nullptr而非0和NULL 优先考虑nullptr而非0和NULL 避免重载指针和整型 9. 优先考虑别名声明而非 typedefs typedef不支持模板化,但是别名声明支持(using ...)。 别名模板避免了使用“::type”后缀,而且在模板中使用typedef还需要在前面加上typename C++14提供了C++11所有type traits转换的别名声明版本 10.