首页 文章 精选 留言 我的

精选列表

搜索[千问小酒窝],共10004篇文章
优秀的个人博客,低调大师

基于微信小程序的方言转文字小程序

我国是一个拥有丰富民族语言资源的国家,各地方言不但是地域文化的活态载体,而且凝聚着独特的历史积淀和人文精神。现代社会快速发展的进程和普通话得到广泛使用的情况,使得许多方言面临传承方面的困难,尤其青少年群体在方言能力上表现出明显下降的趋势。不同方言系统之间差别很大,跨地域交流时的语言障碍问题因此变得突出,社会交往的有效性也因此受到限制[1]。

优秀的个人博客,低调大师

8千字干货教程|java反射精讲

java反射机制精讲目录 反射机制的概念 反射的基础Class类 反射的用法 反射的应用示例 作者简介:全栈学习笔记,一个正在努力的人 反射机制的概念:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。反射被视为动态语言的关键。简单来说反射就是java的各种成分映射成对应的java类。 通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。包括构造方法,属性,方法。 java反射机制提供的功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。 这其实也涉及到了语言的动态与静态,java语言本身不算是动态语言,但是他有一个非常突出的动态机制,就是我们所说的反射机制。什么是动态语言呢?就是说,程序在运行的时候,(注意是运行的时候,不是编译的时候)允许改变程序结构或者变量类型。反之静态就是没有这些特点了。 反射的基础Class类Class类是反射实现的基础,所以想要学会反射,必须先掌握Class类的一些基本的概念。类是什么?类是Class类的实例对象,所以说Class类是所有类的类。 要想解剖一个类,必须先获取到该类的字节码文件对象。而解剖使用的就是Class 类中的方法,所以先要获取每一个字节码文件对应的Class类型的对象。 Class类没有公共的构造方法,Class对象是在类加载的时候由Java虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。这里又涉及到一个东西,类的加载 简要的说明一下: 类加载器:当程序需要是用某个类时,如果该类还没有被加载到内存中,则,系统会通过加载,连接,初始化 这三步来对类进行初始化 加载:就是指将class文件读入内存(编译之后的文件是.class文件),并为之创建一个Class对象任何类被使用时,系统都会建立一个Class对象,第一次的时候会,第二次则会判断这个类是否存在。 连接:验证是否有正确的内部结构,并和其他类协调一致准备为类的静态成员分配内存,并设置默认初始化值并做一个解析:将类的二进制数据中的字符引用替换为直接引用。 上面说到Class对象是不能直接创建的,但是我们可以通过其他方式得到Class类的,目前有三种方式可以得到我们想要的Class类,得到Class类之后就能正常的使用反射了。 获取Class的三种方式(获取一个类的字节码对象): 第一种:使用对象获取,使用对象的getClass获取 Person person = new Person();Class clazz = person.getClass();第二种:使用静态属性class Class clazz = Person.class第三种:使用Class类的静态方法forName(字符串的类名)注;类名要写全包名 Class clazz = Calss.forName("…….");好了,重点来了,反射怎么玩才有趣! 反射的用法上面说了通过反射可以得到任意一个类的什么什么,下面来看看是不是真的。 第一步要干啥?当然是通过之前的哪三种方法来得到这个可以为所欲为的Class类。有三种方法,我们先都做个示例吧!上代码 //获取Class第一种方法Student student = new Student();Class clazz = student.getClass();//获取Class第二种方法Class clazzTwo = Student.class;//获取Class第三种方法Class clazzThree = Class.forName("demo.qzxxbj.entity.Student"); System.out.println("第一个"+clazz+"n第二个"+clazzTwo+"n第三个"+clazzThree);结果 第一个class demo.qzxxbj.entity.Student第二个class demo.qzxxbj.entity.Student第三个class demo.qzxxbj.entity.Student可以看到三种方法得到的Class对象是一样的,没有区别。第三种方法是会有一个找不到类的异常抛出的。其中Student就是一个简单的类,可以是任何类。 通过Class获取任意一个类的属性Student类的代码 package demo.qzxxbj.entity; /** @author 微信公众号:全栈学习笔记 @date 2020/3/29 @description*/ public class Student {private String name;private Integer age;private String sex;public int number; public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; }} 以下获取Class的方法都采用第二种,比较简洁 //获取Class第二种方法 Class clazzTwo = Student.class; //获取该类指定属性名的public成员变量,包括父类的 Field field = clazzTwo.getField("number"); //field public int demo.qzxxbj.entity.Student.number System.out.println("该类指定属性名的public成员变量,包括父类的"+field); //获取该类指定名称声明的变量,即不包括父类的 Field deField = clazzTwo.getDeclaredField("name"); // deField private java.lang.String demo.qzxxbj.entity.Student.name System.out.println("该类所有声明的变量,即不包括父类的"+deField); //获取该类所有的public声明的成员变量 Field fields[] = clazzTwo.getFields(); System.out.println("public声明的变量:"); //public int demo.qzxxbj.entity.Student.number for (Field field1:fields){ System.out.println(field1); } //获取该对象的所有成员变量 Field deFields[] = clazzTwo.getDeclaredFields(); System.out.println("该对象的所有成员变量"); //private java.lang.String demo.qzxxbj.entity.Student.name //private java.lang.Integer demo.qzxxbj.entity.Student.age //private java.lang.String demo.qzxxbj.entity.Student.sex //public int demo.qzxxbj.entity.Student.number for (Field field1:deFields){ System.out.println(field1); } 记住getFields(),getField(String name),getDeclaredFields(),getDeclaredField(String name)的区别,你就能好好掌握这个知识点! 通过Class获取任意成员方法 还是看代码吧! 获取成员方法Method //获取Class第二种方法 Class clazzTwo = Student.class; //根据方法名以及参数类型获取,只能获取public声明的方法,包括父类的 Method method = clazzTwo.getMethod("setAge",Integer.class); //public java.lang.Integer demo.qzxxbj.entity.Student.getAge() System.out.println(method); //根据方法名以及参数名称获取该类声明的所有的属性方法,不包括父类的 Method deMethod = clazzTwo.getDeclaredMethod("setAge", Integer.class); System.out.println(deMethod); //获取该对象声明的所有的public方法,包括父类的 Method methods[] = clazzTwo.getMethods(); //获取该对象声明的所有的方法,但是不包含父类的方法 Method deMethods[] = clazzTwo.getDeclaredMethods(); 一个Method方法打印出来是什么呢?上面代码中也包含了 public void demo.qzxxbj.entity.Student.setAge(java.lang.Integer)和之前讲的Field是不是很相似。既然说到了方法,那么就肯定涉及到了方法调用,我们得到了这些方法,又该怎么调用这个类里面的方法呢?使用invoke函数,Method这个类里面包含了一个invoke函数,英语好的就知道了,这个invoke的中文意思就是“调用”。怎么用呢? //获取Class第二种方法 Class clazzTwo = Student.class; //根据方法名以及参数类型获取,只能获取public声明的方法,包括父类的 Method method = clazzTwo.getMethod("setAge",Integer.class); //public java.lang.Integer demo.qzxxbj.entity.Student.getAge() System.out.println(method); //利用Class创建一个对象的实例 Student student = (Student) clazzTwo.newInstance(); //函数调用 Object value = method.invoke(student,20); //null System.out.println(value); 以上的代码,你可能会看不懂,我来讲一下,首先,我们获取一个类的Class,然后我们通过这个Class获取该类的一个setAge方法,获取到这个方法后继续调用这个方法,调用方法是不是应该调用一个实例对象里面的方法?所以我们需要先实例化一个对象,通过什么方法呢,通过class里面的newInstance(),创建一个实例,这种方法需要该实例化的类具有一个无参构造方法。还有其他方法也能创建一个实例,后面我们会说。创建出一个实例对象之后,我们就能开始调用方法了。通过invoke对方法进行调用,invoke的第一个参数就是一个实例化对象,不然我去哪找这个方法。第二个参数,或者第三个,等等,后面的所有参数都是我调用的该方法所具有的参数,按照顺序填进去就OK了。然后这个函数返回的是一个Object对象,你都能想到,我调用一个方法是不是要让他做一些事,做了这些事需要返回一个东西,不知道这个东西是啥,就用Object获取嘛。由于我们调用的这个方法不需要返回值,所以就是null了。很简单是不是。学到了记得给我点个关注哦!精彩美文第一时间推送到你的手中。 通过Class获取构造方法 这个被我放到了最后来学习,毕竟我觉得用的比例比较少。一起来学习一下怎么用Class获取构造方法,并调用他。 public Student(String name, int id) { this.name = name; this.id = id; }这里我们在Student类里面添加了一个构造方法。 然后我们来获取这个构造方法。 //获取Class第二种方法 Class clazzTwo = Student.class; //获取无参构造方法,public声明的,包括父类,加上参数时就是获取特定的构造方法 Constructor constructor = clazzTwo.getConstructor(); //public demo.qzxxbj.entity.Student() System.out.println(constructor); //获取该类所有的public声明的构造方法 Constructor constructors[] = clazzTwo.getConstructors(); //获取指定参数的构造方法 Constructor deConstructor = clazzTwo.getDeclaredConstructor(String.class,Integer.class); //获取所有的该类的构造方法,不包括父类的 Constructor deConstructors[] =clazzTwo.getDeclaredConstructors(); 上面代码应该很容易看懂吧,我就不细说了。这里说一下如何使用得到的构造方法,构造方法顾名思义就是来实例化对象的,上面我们也有说到怎么通过Class实例化一个对象,现在我们来通过构造方方法实例化一个对象 Student student = (Student) deConstructor.newInstance("全栈学习笔记",21); //21 System.out.println(student.getAge()); 现在知道了吧,我们差不都将反射的功能讲完了,就差一个反射的动态代理,这个比较重要,会专门出一篇博客,码字不易。希望点个关注。微信公众号:全栈学习笔记,精彩美文每天为你推送。 最后我根据我自己以前的经验写了一个java反射的sql语句拼接,相当于是一个反射的应用吧。 反射的应用示例通过反射动态的生成SQL语句,是不是也有点牛逼的感觉?直接上代码吧,我只发一个SQL语句,感兴趣的可以私信我找我拿完整的代码! public String insert(Object object) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {` //insert into student(id,name,sex) values (1,"全栈学习笔记","男") StringBuilder sql = new StringBuilder(); Class clazz = object.getClass(); sql.append("insert into "); sql.append(clazz.getSimpleName()+"("); Field[] fields = clazz.getDeclaredFields(); for(Field field:fields){ sql.append(field.getName()+","); } sql.deleteCharAt(sql.length()-1); sql.append(")"); sql.append(" values ("); for(Field field:fields){ field.setAccessible(true); Object value = field.get(object); String fieldName = field.getName(); String str1 = fieldName.substring(0,1).toUpperCase(); String str2 = fieldName.substring(1,fieldName.length()); String strValue = str1.concat(str2); //String strValue = fieldName.substring(0,1).toUpperCase().concat(fieldName.substring(1,fieldName.length())); Method method = clazz.getMethod("get"+strValue,null); Object value1 = method.invoke(object,null); // if(value1.getClass().equals(String.class))// if(field.getType().equals(String.class)) if(value1 instanceof String){ sql.append("\"").append(value1).append("\"").append(","); }else { sql.append(value1).append(","); } } sql.deleteCharAt(sql.length()-1); sql.append(")"); System.out.println(sql.toString()); return sql.toString(); }原文地址https://www.cnblogs.com/swzx-1213/p/12597159.html

优秀的个人博客,低调大师

千奇百怪的数据库故障

昨天阿里云在运维上出现了严重的事故,引发文件删除,让我想起这篇文章,补充再发出来。总有很多情形,你无法想象,数据库的故障遭遇也是如此。 如果没有完善的流程、规范,并且进行规范化的审核,那么什么故障都可能发生,人、流程和工具,必须要互相匹配,完美结合才能发挥最佳效应,而运维就是要疯狂躲避各种坑。 分享几则我们遇到过的客户恢复故障,与大家共为警醒,注意这些都是真实的案例: 服务器找不到了 某次客户找我们恢复数据库,说某个数据库出现故障,原本以为不再需要了,现在还需要其中的数据,可能是时间太久远了,工程师到现场后,客户说服务器找不到了,就算了。 三个月后,客户来电说,服务器找到了,我们又去帮用户恢复了数据。 服务器搬走了 某次客户数据库故障,检查发现,是RAC的某个节点服务器被搬走了,以为不用了,郁闷的是,断电还导致了ASM磁盘头损坏,还好11g修复ASM磁盘头很简单,迅速帮助用户恢复了数据库运行,再搬回服务器,加入节点。 磁盘搬走了 也是今年的某个客户,新上线服务器,客户找了一块以为不用的磁盘,强制拉过来格式化,发现另外一个业务库应声倒下了。 DBA走了 最近提到过的一个客户,因为把DBA解雇掉了,结果,DBA偷偷上来把整个库给删除掉了,业务挂了很久很久。 网线拔了 这是2015的案例,在业务高峰,新上一个交换机,网络运维把生产数据库的网线拔了,影响业务10分钟。这是金融业务,据说客户的人都跑到机房,机房满员。 磁盘故障 这也是2015年的新案例,客户的存储工程师划分给数据库ASM的磁盘小于请求容量,数据库文件扩展时越界产生了故障。这是队友埋的坑。 同志们,Oracle是坚强的,但是数据安全是脆弱的,警惕随时可能发生的故障,不断强化数据安全,加强运维规范化,如何都不为过。 本文出自数据和云公众号,原文链接

优秀的个人博客,低调大师

面试被问MySQL 主从复制,怎么破?

一、前言 随着应用业务数据不断的增大,应用的响应速度不断下降,在检测过程中我们不难发现大多数的请求都是查询操作。 此时,我们可以将数据库扩展成主从复制模式,将读操作和写操作分离开来,多台数据库分摊请求,从而减少单库的访问压力,进而应用得到优化。整理了一份328页MySQLPDF文档 本次测试使用两个虚拟机:ip:192.168.2.21(主) ip:192.168.2.22(从) 二、主从复制原理 同步操作通过 3 个线程实现,其基本步骤如下: 主服务器将数据的更新记录到二进制日志中(记录被称作二进制日志事件)-- 主库线程; 从库将主库的二进制日志复制到本地的中继日志(relay log)-- 从库 I/O 线程; 从库读取中继日志中的事件,将其重放到数据中 -- 从库 SQL 线程。 三、配置主库 # 3.1 创建用户 为了安全起见,准备创建一个新用户用于从库连接主库。 # 创建用户 create user 'repl'@'%' identified by 'repl'; # 授权,只授予复制和客户端访问权限 grant replication slave,replication client on *.* to 'repl'@'%' identified by 'repl'; # 3.2 修改配置文件 1)vim /etc/my.cnf 在[mysqld]下添加: log-bin = mysql-bin log-bin-index = mysql-bin.index binlog_format = mixed server-id = 21 sync-binlog = 1 character-set-server = utf8 2)保存文件并重启主库: service mysqld restart 配置说明: log-bin:设置二进制日志文件的基本名; log-bin-index:设置二进制日志索引文件名; binlog_format:控制二进制日志格式,进而控制了复制类型,三个可选值 -STATEMENT:语句复制 -ROW:行复制 -MIXED:混和复制,默认选项 server-id:服务器设置唯一ID,默认为1,推荐取IP最后部分; sync-binlog:默认为0,为保证不会丢失数据,需设置为1,用于强制每次提交事务时,同步二进制日志到磁盘上。 # 3.3 备份主数据库数据 若主从数据库都是刚刚装好且数据都是一致的,直接执行 show master status 查看日志坐标。 若主库可以停机,则直接拷贝所有数据库文件。 若主库是在线生产库,可采用 mysqldump 备份数据,因为它对所有存储引擎均可使用。 1)为了获取一个一致性的快照,需对所有表设置读锁: flush tables with read lock; 2)获取二进制日志的坐标: show master status; 返回结果: +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) 3)备份数据: # 针对事务性引擎 mysqldump -uroot -ptiger --all-database -e --single-transaction --flush-logs --max_allowed_packet=1048576 --net_buffer_length=16384 > /data/all_db.sql # 针对 MyISAM 引擎,或多引擎混合的数据库 mysqldump -uroot --all-database -e -l --flush-logs --max_allowed_packet=1048576 --net_buffer_length=16384 > /data/all_db.sql 1 row in set (0.00 sec) 4)恢复主库的写操作: unlock tables; 四、配置从库 # 4.1 修改配置文件 1)vim /etc/my.cnf 在[mysqld]下添加: log-bin = mysql-bin binlog_format = mixed log-slave-updates = 0 server-id = 22 relay-log = mysql-relay-bin relay-log-index = mysql-relay-bin.index read-only = 1 slave_net_timeout = 10 2)保存文件并重启从库: service mysqld restart 配置说明: log-slave-updates:控制 slave 上的更新是否写入二进制日志,默认为0;若 slave 只作为从服务器,则不必启用;若 slave 作为其他服务器的 master,则需启用,启用时需和 log-bin、binlog-format 一起使用,这样 slave 从主库读取日志并重做,然后记录到自己的二进制日志中; relay-log:设置中继日志文件基本名; relay-log-index:设置中继日志索引文件名; read-only:设置 slave 为只读,但具有super权限的用户仍然可写; slave_net_timeout:设置网络超时时间,即多长时间测试一下主从是否连接,默认为3600秒,即1小时,这个值在生产环境过大,我们将其修改为10秒,即若主从中断10秒,则触发重新连接动作。 # 4.2 导入备份数据 如果 3.3 步骤中没进行备份,忽略此步骤。 mysql -uroot -p < /data/all_db.sql # 4.3 统一二进制日志的坐标 根据 3.3 步骤获取的坐标,统一到从库中: change master to master_host='192.168.2.21', master_user='repl', master_password='repl', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=120; 注意:此处使用的是新创建的账户。 # 4.4 启动主从复制 1)启动从库 slave 线程: start slave; 2)查看从服务器复制功能状态: show slave status\G; 返回结果: *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.2.21 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 120 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 283 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 120 此处只张贴部分返回结果。 结果说明: Slave_IO_Running:此进程负责 slave 从 master 上读取 binlog 日志,并写入 slave 上的中继日志。 Slave_SQL_Running:此进程负责读取并执行中继日志中的 binlog 日志。 这两个进程的状态需全部为 YES,只要有一个为 NO,则复制就会停止。 当 Relay_Master_Log_File = Master_Log_File 且 Read_Master_Log_Pos = Exec_Master_Log_Pos 时,则表明 slave 和 master 处于完全同步的状态。 五、验证 使用一个简单的例子: 在主库创建名为 mysql_test 的数据库,如果同步成功,那么在从库中也能查询出名为 mysql_test 数据库。 六、参考资料 MySQL 官网整理了一份328页MySQLPDF文档 dev.mysql.com/doc/refman/…

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册