• [技术干货] JdbcTemplate详解
    一、JdbcTemplate(概念和准备) 1 、什么是 JdbcTemplate(Template译为模板) ( 1 ) Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作 2 、准备工作 ( 1 )引入相关 jar 包 ( 2 )在 spring 配置文件配置数据库连接池 com.alibaba.druid.pool.DruidDataSource和com.mysql.jdbc.Driver 都是引入的jar包内的类,不需要自己创建 ( 3 )配置 JdbcTemplate 对象,注入 DataSource(即数据库、数据源) JdbcTemplate是jar包里的类,不是自己创建的。 JdbcTemplate中有个属性叫:dataSource,源码中已经为其设置了set方法,所以用的是set方法注入属性 JdbcTemplate的属性dataSource注入的正是上面数据库连接池对象,等于说把JdbcTemplate对象和数据库连接起来了   (4 )使用注解来创建对象和注入属性,所以需要开启组件扫描   完整的xml: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:context="http://www.springframework.org/schema/context"        xmlns:aop="http://www.springframework.org/schema/aop"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">       <!-- 数据库连接池 -->     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"           destroy-method="close">         <property name="url" value="jdbc:mysql:///user_db" /><!--对应SQLyog里的数据库-->         <property name="username" value="root" />            <!-- 用户名 -->         <property name="password" value="4.233928" />        <!-- 密码 -->         <property name="driverClassName" value="com.mysql.jdbc.Driver" />     </bean>       <!-- JdbcTemplate对象 -->     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">         <!--注入dataSource属性-->         <property name="dataSource" ref="dataSource"></property>     </bean>     <!-- 组件扫描 -->     <context:component-scan base-package="JDBC"></context:component-scan> </beans> 二、JdbcTemplate 操作数据库(添加) 需求:在表Book中添加一行数据(下图是已经添加完的)  1、对应数据库创建实体类(三个属性对应表Book的三个参数) package JDBC;   public class Book {       private String userid;     private String username;     private String ustatus;       public String getUserid() {         return userid;     }       public String getUsername() {         return username;     }       public String getUstatus() {         return ustatus;     }       public void setUserid(String userid) {         this.userid = userid;     }       public void setUsername(String username) {         this.username = username;     }       public void setUstatus(String ustatus) {         this.ustatus = ustatus;     } } 2、接口BookDao,定义增删查改方法 package JDBC;   public interface BookDao {     //添加(增)     public void add(Book book); } 3、接口BookDao的实现类:BookDaoImp 重写add(Book book)方法,向数据库的表中添加数据 JdbcTemplate是jar包org.springframework.jdbc.core中的,添加注解@Autowired后,已经自动注入到JdbcTemplate jdbcTemplate中了。 package JDBC;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository;   @Repository public class BookDaoImp implements BookDao{       //按类型、自动注入了JdbcTemplate对象(jdbcTemplate即已经是有实体的对象了)     //JdbcTemplate对象对象里有增删查改的方法,用来操作数据库     @Autowired     private JdbcTemplate jdbcTemplate;       @Override     public void add(Book book) {           //创建添加的sql语句         String addsql = "insert into Book values(?,?,?)";         //调用jdbcTemplate.update实现添加,book.getUserid()、book.getUsername()、book.getUstatus()对应values(?,?,?)里的三个问号         Object[] args = {book.getUserid(), book.getUsername(), book.getUstatus()};         int update = jdbcTemplate.update(addsql,args);         //返回值update代表添加了几行         System.out.println(update);//1     } }4、BookService类4、BookService类5 package JDBC;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;   @Service public class BookService {          //BookDaoImp类上添加了注解@Repository,即已经生成了他的对象     //按类型、自动注入了BookDaoImp的对象     @Autowired     private BookDao bookDao;       public void addBook(Book book){         bookDao.add(book);     } } 5、测试 :获取BookService类的对象bookService,调用addBook(book)。 package JDBC;   import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;   public class JDBCTest {       @Test     public void test(){           ApplicationContext context = new ClassPathXmlApplicationContext("bean7.xml");         BookService bookService = context.getBean("bookService", BookService.class);           Book book = new Book();         book.setUserid("1");         book.setUsername("java");         book.setUstatus("active");           bookService.addBook(book);       } }   ——一般这些是从网页上获得的,这里我们手动输入 最终效果: 三、JdbcTemplate 操作数据库(删、改)——只需修改以下几个文件 package JDBC;   public interface BookDao {     //添加(增)     public void add(Book book);         //修改     public void update(Book book);       //删除(根据id删除)     public void delete(String id);      } package JDBC;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository;   @Repository public class BookDaoImp implements BookDao{       //按类型、自动注入了JdbcTemplate对象     @Autowired     private JdbcTemplate jdbcTemplate;       @Override     public void add(Book book) {           //创建添加的sql语句         String addsql = "insert into Book values(?,?,?)";         //调用jdbcTemplate.update实现添加,book.getUserid()、book.getUsername()、book.getUstatus()对应values(?,?,?)里的三个问号         Object[] args = {book.getUserid(), book.getUsername(), book.getUstatus()};         int update = jdbcTemplate.update(addsql,args);         //返回值update代表添加了几行         System.out.println(update);     }       @Override     public void update(Book book) {         //根据id修改username ustatus         String updatesql = "update Book set username=?,ustatus=?where user_id=?";         Object[] args = {book.getUsername(), book.getUstatus(),book.getUserid(),};//注意参数顺序         int update = jdbcTemplate.update(updatesql,args);     }       @Override     public void delete(String id) {         //根据user_id删除         String deletesql = "delete from Book where user_id=?";         int update = jdbcTemplate.update(deletesql,id);     } }  package JDBC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BookService {     //按类型、自动注入了BookDaoImp的对象     @Autowired     private BookDao bookDao;       public void addBook(Book book){         bookDao.add(book);     }     public void update(Book book){         bookDao.update(book);     }       public void delete(String id){         bookDao.delete(id);     }   }  四、JdbcTemplate 查询操作 1、查询返回的是某个值 2、查询返回的是某个对象 3、查询返回的是某个集合 ———————————————— 原文链接:https://blog.csdn.net/qq_40643699/article/details/115582536 
  • Java中时间与时间戳的转换
    Java中时间与时间戳的转换 1. 时间转换成时间戳 方式一: /**   * 时间转换成时间戳,参数和返回值都是字符串   * @param  s   * @return res   * @throws ParseException  */ public static String dateToStamp(String s) throws ParseException {     String res;     //设置时间模版     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     Date date = simpleDateFormat.parse(s);     long ts = date.getTime();     res = String.valueOf(ts);     return res; } 在主函数中设置参数与运行结果   String date=dateToStamp("2021-09-07 09:09:39");  System.out.println(date); //结果:1630976979000 方式二:  /**   * 日期转换成时间戳,参数可以是日期,返回值是字符串  */ public static void Date2TimeStamp() {    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    String format = sdf.format(new Date());    try {        String valueOf = String.valueOf(sdf.parse(format).getTime() / 1000);        System.err.println(valueOf);    } catch (ParseException e) {        e.printStackTrace();    } } 2. 时间戳转换成时间 方式一:  /**   * 将时间戳转换为时间,参数和返回值都是字符串   * @param s   * @return res  */ public static String stampToDate(String s){     String res;     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     long lt = new Long(s);     Date date = new Date(lt);     res = simpleDateFormat.format(date);     return res; }  在主函数中设置参数与运行结果   String s="1630339200000";  String date=stampToDate(s);  System.out.println(date);  //2021-08-31 00:00:00 方式二:  /**   * 时间戳先转换成日期字符串再转换成日期类型,参数是字符串,返回值是字符串也可是日期  */ public static void TimeStamp2Date() {    String timestampString = "1631008034";    String formats = "yyyy-MM-dd HH:mm:ss";    Long timestamp = Long.parseLong(timestampString) * 1000;    //日期格式字符串    String dateStr = new SimpleDateFormat(formats, Locale.CHINA).format(new Date(timestamp));    System.err.println(dateStr);    Date date = null;    SimpleDateFormat formater = new SimpleDateFormat();    formater.applPattern("yyyy-MM-dd HH:mm:ss");    try {        date = formater.parse(dateStr);        System.err.println(date);    } catch (ParseException e) {        e.printStackTrace();    } } ———————————————— 原文链接:https://blog.csdn.net/qq_35297368/article/details/120162984 
  • [技术干货] springboot启动报jar包加载异常问题解决
    问题描述: springboot启动报jar包扫描错误,但不影响项目正常使用: Failed to scan [file:/Users/ds/.m2/repository/com/sun/xml/bind/jaxb-impl/2.2.11/jaxb-core.jar] from classloader hierarchy java.io.FileNotFoundException: /Users/ds/.m2/repository/com/sun/xml/bind/jaxb-impl/2.2.11/jaxb-core.jar (No such file or directory) 原因分析:高版本的tomcat除了加载maven管理的jar包外,还会对jar包中的manifest.mf文件进行分析,加载manifest.mf文件中classpath定义的jar包。 例如:com.sun.xml.bind.jaxb-impl-2.2.11.jar包的MANIFEST.MF文件中Class-Path有jaxb-core.jar,但是该jar包没有定义版本号和路径,导致tomcat从jaxb-impl-2.2.11.jar的路径加载jaxb-core.jar,从而找不到jaxb-core.jar出现Failed to scan的异常。但其实这个jar包已经在其它地方引用了。  解决方案: 方案一: 降低tomcat版本到8.5.0或以下,高版本tomcat会对jar包中的manifest.mf文件进行分析。 方案二: 在启动类中配置不扫描manifest文件 ———————————————— 版权声明:本文为CSDN博主「ds_trojan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_27990381/article/details/110042215  /** * 不扫描Manifest文件 * @return */ @Bean public TomcatServletWebServerFactory tomcatFactory() { return new TomcatServletWebServerFactory() { @Override protected void postProcessContext(Context context) { ((StandardJarScanner) context.getJarScanner()).setScanManifest(false); } }; }———————————————— 原文链接:https://blog.csdn.net/qq_27990381/article/details/110042215
  • [技术干货] IDEA中快速解决依赖冲突的妙招,赶紧收藏学习吧
    大家在实际项目中想必遇到依赖冲突是特别的头疼,如果项目比较复杂,比较大的话,那依赖冲突解决起来是特别耗费时间和精力的。  这几天在项目里加了个从阿里云OSS中下载文件的接口,其中用到了OSSClientBuilder这个方法,不过由于之前项目中集成的OSS版本太低,没有这个方法,所以需要更新版本,但是更新过版本后却报了依赖冲突的问题。还好用了IDEA中的这个插件,很快就搞定了!  一、插件下载 使用的插件叫做 Maven Helper ,大家可以根据下图的步骤去下载,下载后不用重启idea也是可以使用的。  二、解决冲突 在安装好这个插件后,打开自己的pom.xml文件,大家可以在文件右下角看到 Dependency Analyzer这个模块,点击进去   Conflicts:展示所有冲突。 All Dependencies as List:以列表的方式展示所有依赖。 All Dependencies as Tree:以树形的方式展示所有依赖。 我们选择 aliyun-java-sdk-core,选择以树形展示所有依赖,得到如下的信息显示。    从上图中我们就可以很清楚的看到 aliyun 的包和 spring-clould-starter-alicloud-ans 的包起了冲突,所以我们右键可以看到红框圈出来的 jump to Source 或者直接F4键可以直接跳到 pom.xml 文件中引用该依赖的地方,然后使用 Exclude 标签排除冲突依赖包的引用就可以完美的解决了。   再次启动项目,测试接口发现功能正常了,整个排查过程也就结束了,IDEA的功能还是很强大的。  总结 很多时候的 jar 包冲突,有些是我们很容易排除,例如在pom.xml 中我们就可以发现一些重复引入,但是版本不相同的依赖。还有一些是其他依赖传递依赖进来的,我们在 pom.xml 文件中不能很直观的发现,这时候我们借助工具可以发现这种冲突的依赖。  类似的依赖冲突基本都可以参考上述的方式进行排查,希望通过本篇文章对大家解决项目中依赖冲突有所帮助。 ————————————————  原文链接:https://blog.csdn.net/Lu_Dai_Ma/article/details/121808103 
  • [技术干货] 关于安装多个JDK和切换版本
    关于安装多个JDK和切换版本  前言 JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。而我们在开发的过程中,也许会需要不同版本的JDK来进行开发工作,那么如何安装多个JDK并随时切换版本呢,本文中将进行详细阐述。  一、下载安装JDK 本次操作我们这里采用JDK8和JDK11两个版本来进行示范操作参考的官方下载链接如下: 官网下载:https://www.oracle.com/java/technologies/downloads/ 下载之后进行安装即可  二、配置JDK 1.系统变量 在系统变量中新建变量,变量名JAVA_HOME,JAVA_HOME11,JAVA_HOME8如图所示:  这里JAVA_HOME11,JAVA_HOME8的变量值是你安装JDK8或JDK11的路径,到该目录级别就可,JDK8也是如此,如图所示:  之后设置Path里面的变量,加上%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; 最好加在最前面,因为安装JDK11之后会生成一个变量,该变量级别高于自己设置的这个变量,需要你在通过新建之后(新建后在最底下,通过后右边向上移动按钮向上移动)将我们新添加的变量通过向上移动,移动到C:\WINDOWS;C:\Program Files (x86)\Common Files\Oracle\Java\javapath和C:\Program Files\Common Files\Oracle\Java\javapath以及C:\WINDOWS\System32变量之上。  **必须做:**另外需要注意的是你需要将C:\Program Files (x86)\Common Files\Oracle\Java\javapath(或者C:\Program Files\Common Files\Oracle\Java\javapath)目录下的以下图片中的文件删除,请注意删除的是只有这三个的,如图:  如果下面图片这样的则不删除  删除完之后通过命令 javac -version和java -version查看是否匹配。  如果要更改版本,你只需要修改JAVA_HOME变量中的值即可 要修改为JDK8版本,则将JAVA_HOME变量值改为%JAVA_HOME8%即可 要修改为JDK11版本,则将JAVA_HOME变量值改为%JAVA_HOME11%即可 修改后需要重新打开cmd再用javac -version和java -version查看,才可以看到是否修改成功。 希望上面这些简单操作能够顺利帮你了解到怎么切换多版本JDK进行开发,加油。———————————————— 原文链接:https://blog.csdn.net/qq_45775798/article/details/122665158 
  • jdk1.8.0_151 java.security.InvalidKeyException: Illegal key size
     java.security.InvalidKeyException: Illegal key size 1、为什么会出现这个报错? JDK中包含有JRE(Java Runtime Environment,即:Java运行环境),JRE中包括Java虚拟机(Java Virtual Machine)、Java核心类库和支持文件,而我们今天要说的主角就在Java的核心类库中。在Java的核心类库中有一个JCE(Java Cryptography Extension),JCE是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现,所以这个是实现加密解密的重要类库。  在我们安装的JRE目录下有这样一个文件夹:%JAVE_HOME%\jre\lib\security(%JAVE_HOME%是JDK安装路径),其中包含有两个.jar文件:“local_policy.jar ”和“US_export_policy.jar”,这两个jar包就是我们JCE中的核心类库了。JRE中自带的“local_policy.jar ”和“US_export_policy.jar”是支持128位密钥的加密算法,而当我们要使用256位密钥算法的时候,已经超出它的范围,无法支持,所以才会报:“java.security.InvalidKeyException: Illegal key size”的异常。  2、解决方案 一般针对jdk1.6,jdk1.7, jdk1.8,这个问题可以去博客 https://blog.csdn.net/dafeige8/article/details/76019911 找到解决方案,需要下载对应的“local_policy.jar ”和“US_export_policy.jar”两个文件替换掉自己%JAVE_HOME%\jre\lib\security文件夹下对应的原文件;  不过针对jdk1.8.0_151版本稍微不一样,%JAVE_HOME%\jre\lib\security下多了个policy文件夹: policy下有2个文件夹limited和unlimited:  ├── limited │   ├── local_policy.jar │   └── US_export_policy.jar └── unlimited     ├── local_policy.jar     └── US_export_policy.jar  从Java 1.8.0_151和1.8.0_152开始, 提供了 无限制强度管辖策略, 默认是不启用的,简单修改下配置即可启用: 在 %JAVE_HOME%\jre\lib\security 文件夹下找到 java.security 文件,在826行左右会有如下配置:  #crypto.policy=unlimited 去掉前面的#,重启Java应用即可。 ———————————————— 原文链接:https://blog.csdn.net/angellee1988/article/details/123588983 
  • [技术干货] Java 20 提供的重要更新
    语言更新和改进JEP 432:记录模式(第二预览版) — 支持用户嵌套记录模式和类型模式,以创建强大、声明性且可组合的数据导航和处理形式,从而增强 Java 语言。这有助于开发人员扩展模式匹配,以实现更复杂和可定制的数据查询,从而提高工作效率。JEP 433:Switch 模式匹配(第四预览版 ) — 通过将模式匹配扩展到 switch,可以针对多个模式测试表达式,每个模式都有特定的操作,让用户可以安全、简洁地表达面向数据的复杂查询。增强 switch 表达式和语句的表达性、适用性有助于提高开发人员的工作效率。Project Loom 预览版/孵化器功能JEP 429:作用域值(孵化器) — 支持在线程内和跨线程共享不可变数据,这些数据优先于线程局部变量,尤其是在使用大量虚拟线程时。这可提高易用性、性能、稳定性和安全性。JEP 436:虚拟线程(第二预览版) — 通过向 Java 平台引入轻量级虚拟线程,显著减少编写、维护和观察高吞吐量并发应用的工作量。虚拟线程让开发人员可以轻松使用现有的 JDK 工具和技术,对并发应用进行故障排除、调试和分析,进而加快应用开发速度。JEP 437:结构化并发(二次孵化阶段) — 通过将运行于不同线程中的多个任务视为一个工作单元,简化多线程编程。这可帮助开发团队简化错误处理和取消工作,并提高可靠性和可观测性。Project Panama 预览版功能JEP 434:外部函数和内存 API(第二预览版) — Java 程序可以更容易地与 Java 运行时之外的代码和数据进行互操作。通过有效调用外部函数(即 Java Virtual Machine [JVM] 之外的代码),以及安全地访问外部内存(即不受 JVM 管理的内存),该特性支持 Java 程序无需 Java Native Interface 即可调用本地库和处理原生数据,从而提高易用性、性能、灵活性和安全性。JEP 438:矢量 API(五次孵化阶段) — 允许以一种在运行时,可靠地编译为支持的 CPU 架构上的向量指令方式表达向量计算,从而实现优于等效标量计算的性能。Java 20 是甲骨文公司工程师与全球 Java 开发人员社区成员通过 OpenJDK 社区 和 Java Community Process (JCP) 共同合作的成果。Java 20 除了推出了新的增强功能,也获得 Java Management Service 的支持,这是一项新的 Oracle 云基础设施远程软件服务(Oracle Cloud Infrastructure, OCI)原生服务,可帮助管理本地部署或任何云端的 Java 运行时和应用程序。支持 Java 客户和全球生态系统转载自https://www.sohu.com/a/657667541_121118996
  • [技术干货] Java 20 正式发布
    老铁们,JDK 20 / Java 20 正式发布了,这版本号简直超神了。。JDK 20 是一个短期维护版本,将获得六个月的支持。尽管如此,但它仍然可用于生产环境中。根据开发计划,下一个 LTS 版本就是将于 2023 年 9 月发布的 JDK 21。此版本包括 7 个 JEP(都处于不同的孵化和预览阶段),以及数百个较小的功能增强和数千个错误修复: 429:Scoped Values (Incubator)432:Record Patterns (Second Preview)433:Pattern Matching for switch (Fourth Preview)434:Foreign Function & Memory API (Second Preview)436:Virtual Threads (Second Preview)437:Structured Concurrency (Second Incubator)438:Vector API (Fifth Incubator)作用域值(Scoped Values)进入孵化阶段引入 Scoped Values,它可以在线程内和线程间共享不可变数据。它们优于线程局部变量,尤其是在使用大量虚拟线程时。记录模式 (Record Patterns) 进入第 2 预览阶段Record Patterns 可对 record 的值进行解构,Record patterns 和 Type patterns 通过嵌套能够实现强大的、声明性的、可组合的数据导航和处理形式。switch 模式匹配 (Pattern Matching for switch) 进入第 4 预览阶段用 switch 表达式和语句的模式匹配,以及对模式语言的扩展来增强 Java 编程语言。将模式匹配扩展到 switch 中,允许针对一些模式测试表达式,这样就可以简明而安全地表达复杂的面向数据的查询。外部函数和内存 API (Foreign Function & Memory API) 进入第 2 预览阶段引入一个 API,通过它,Java 程序可以与 Java 运行时之外的代码和数据进行互操作。通过有效地调用外部函数,以及安全地访问外部内存,该 API 使 Java 程序能够调用本地库并处理本地数据,而不会像 JNI 那样有漏洞和危险。虚拟线程 (Virtual Threads) 进入第 2 预览阶段为 Java 引入虚拟线程,虚拟线程是 JDK 实现的轻量级线程,它在其他多线程语言中已经被证实是十分有用的,比如 Go 中的 Goroutine、Erlang 中的进程。虚拟线程避免了上下文切换的额外耗费,兼顾了多线程的优点,简化了高并发程序的复杂,可以有效减少编写、维护和观察高吞吐量并发应用程序的工作量。结构化并发 (Structured Concurrency) 进入第 2 孵化阶段JDK 19 引入了结构化并发,这是一种多线程编程方法,目的是为了通过结构化并发 API 来简化多线程编程,并不是为了取代 java.util.concurrent。结构化并发将不同线程中运行的多个任务视为单个工作单元,从而简化错误处理、提高可靠性并增强可观察性。也就是说,结构化并发保留了单线程代码的可读性、可维护性和可观察性。向量 API (Vector API) 进入第 5 孵化阶段向量计算由对向量的一系列操作组成。向量 API 用来表达向量计算,该计算可以在运行时可靠地编译为支持的 CPU 架构上的最佳向量指令,从而实现优于等效标量计算的性能。向量 API 的目标是为用户提供简洁易用且与平台无关的表达范围广泛的向量计算。更多详情可查看:https://openjdk.org/projects/jdk/20/下载:https://jdk.java.net/20/转载自https://mp.weixin.qq.com/s/7WovwVFiXtFIAtaO871UHw
  • [技术干货] java程序员转正述职报告PPT-转载
     新公司转正述职报告,花了些时间准备了ppt和讲稿,这里分享一下  述职报告 时间过得很快,转眼就已经三个月了,三个月时间不长,完成的工作也有限,但是在这些工作中,我也学到了很多,现在对这三个月的工作和自己的收获做一个简短汇报。总共分为四部分:工作小结、个人收获、自我思考还有未来展望。  1.工作小结 首先,工作小结  这是我入职一周时试用期跟进表中填写的试用期目标,可以说试用期的工作主要是围绕着这些目标来进行的,时间过得很快,现在已经是入职第十二周了,我也已经写了十一份周报了,现在再回过头来看这份试用期目标,我个人觉得可能没有百分百优秀的完成,比如需求设计上还有很多不足。但是也基本上能达到我对自己的要求与期望了。  下面是工作内容,基本上就是写设计文档,写接口然后测试,改bug,当然前期最主要的工作内容还是熟悉和学习。熟悉项目的业务和项目代码以及我们开发与上线的流程。这个地方还要说一下我们的uu加速器,前几堂课是关于开发环境的课,对我有很大帮助。程序员的工作主要当然还是以写代码为主。 我们项目的迭代速度还是比较快的,基本上是每周都有上线,没有新需求的时候也会有一些以前功能的优化需求。这三个月我主要参与的迭代就是这些:balabalabala 你参与的项目完成的功能,写一下  2.个人收获 这一段时间里有工作上的收获,知识的丰富,经验的增长,同时也暴露出很多问题和不足,下面是我的个人收获,我在技术上和经验上分别作了一些总结。  首先这三个月的开发工作也让我学习到一些新的技术知识,比如 balabalabala………………  相比于技术上的学习,我觉得我在经验上的收获可能更多的,可能也是因为我这方面的不足也比较多,进步空间比较大。  首先在功能设计上要提升全局观念,沟通意识,先有规划再写代码,开发前的设计阶段真的很重要,设计逻辑理顺了,剩下的开发就相对比较轻松。确定方案的时候要结合线上的使用情况,不能只看开发和测试环境就拍脑袋。 代码上要考虑到所写的代码是否有走弯路,自己所做的模块是否能有效的和其他同事所做的模块相融合,加强代码的优化,争取所写的每一句代码都能发挥起作用。我的问题就比较疏于代码优化,对系统性能要求不高;全局考虑欠缺,写一步算一步,以至于走了很多弯路。最大的不足就是粗心大意考虑问题不够细致,不太注重细节。这可能也是我个人的性格原因,最后体现在工作上,也体现在代码上。认识到了以后现在也正在慢慢修改。 在需求上,因为我们项目经常会有功能优化的需求,对以前的代码做一些改动,这些其实都还好,因为有产品的业务需求会比较清楚,如果是进行代码优化的话就需要自己去把这一块的业务逻辑理清再修改,否则就容易想当然,字段在我眼里就只是字段没有什么特别的,但是可能他在这块的业务逻辑上是需要特殊处理的,这些在优化之前都是需要搞清楚的。 最后就是要注重沟通了,咱们的项目都不是一个人去开发的,沟通一定要及时到位。  3.自我思考  在新环境中的一些思考与感悟,以及对所属业务的理解和对公司、部门的理解。  首先是我的一些工作心得,这虽然不是我的第一份工作,但是其实算是真正意义上我一个人进入一个完全陌生的大团队里去工作,当然现在已经非常熟了。有导师时常在周围点播我帮助我成长,有小伙伴一起相互促进共同进步。这种新的定位让我感受到在工作之中团队的重要性,在团队里每个人各司其职,任何一个人掉队都有可能导致机器瘫痪,只有协同合作,才能实现我们的共同价值。 然后就是责任感,我觉得我们应该对自己的代码负责,对自己的项目负责,首先要避免出问题,出了问题要主动承担,发现错误认识错误改正错误,团队协作,出了问题从来都不是一个人的事,所以发现项目中不足的地方也要主动的去优化提出。 在公司上,balabalabala…………写下你对公司业务的理解,公司文化的感受啥的  4.未来展望  未来会继续学习,加深对业务,行业的理解。同时在技术上也要继续努力,在写好业务代码的同时深入学习,能尽快成为独当一面的工程师,往资深架构的目标持续努力。 为了实现这些目标,要保持自我复盘,强化优势,持续学习,注重业务实践,这些事情看起来可能很简单,但是能持之以恒的做下去应该也不容易,我会继续这样要求自己,也欢迎大家监督。 最后,试用期完成的工作有限,我也有很多不足之处,处理问题的方式也有待提高,未来我会总结反思和保持积极向上的态度,认证细心的处理好每段代码,努力在公司实现自己的目标,和公司一起成长。  都是套话,修改一下就可以直接用,ppt打开演讲者模式照着稿子念,舒服  文中的PPT已经上传了,需要的可以自行下载 点击下载 https://download.csdn.net/download/weixin_48356746/86796115 that’s all ———————————————— 版权声明:本文为CSDN博主「LxyrichBos」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_48356746/article/details/122249379 
  • [其他] java多线程
    多线程实现方法1.继承 java.lang.Thread,重写 run方法// 定义线程类 public class MyThread extends Thread{ public void run(){ } } // 创建线程对象 MyThread t = new MyThread(); // 启动线程。 t.start();2.实现 java.lang.Runnable 接口,实现run方法// 定义一个可运行的类 public class MyRunnable implements Runnable { public void run(){ } } // 创建线程对象 Thread t = new Thread(new MyRunnable()); // 启动线程 t.start();或者用匿名类public class ThreadTest04 { public static void main(String[] args) { // 创建线程对象,采用匿名内部类方式。 Thread t = new Thread(new Runnable(){ @Override public void run() { for(int i = 0; i < 100; i++){ System.out.println("t线程---> " + i); } } }); // 启动线程 t.start(); for(int i = 0; i < 100; i++){ System.out.println("main线程---> " + i); } } }Thread和Runnable的区别如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。总结:实现Runnable接口比继承Thread类所具有的优势:1):适合多个相同的程序代码的线程去处理同一个资源2):可以避免java中的单继承的限制3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类线程状态转换1、新建状态(New):新创建了一个线程对象。2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种: (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。线程同步1、synchronized关键字的作用域有二种: 1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法; 2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/区块/},它的作用域是当前对象;3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;
  • [其他] Java集合介绍和使用场景
    集合的分类集合List和Set都继承于Collection,都是单个储存元素的都是可以迭代的。1. List特点是是可重复、有序的,存入和迭代取出的次序相同。List的子类又有ArrayList、LinkedList、Vector。ArrayList底层采用数组结构存储,适合做查询笔试和频繁的增删,单线程操作效率高,随机增删效率低,多线程不安全。 初始10,按照1.5倍扩容Vector和ArrayList底层原理相同,但是使用sychorinized保证了多线程安全,效率低少使用。 初始10,按照2倍扩容LinkedList底层采用双向链表结构存储元素,增删效率高,随机查找效率低。不能通过数学表达式计算被查找元素的内存地址,每一次查找都是从头节点开始遍历,直到找到为止。所以LinkedList集合检索/查找的效率较低。2. Set特点是元素无序不可重复,不能按照index取值,适合做数据字典。HashSet底层是一个哈希表(散列表),实际是一个HashMap。SortedSet特点是存取无序且不可重复,但是存的元素可以自动按照大小排列。TreeSet继承于SortedSet,底层是一个二叉树TreeMap。3. Map双列集合Map,和Collection集合没有关系,Map集合以key-value的形式储存元素,key和value都是存储java对象的内存地址,所有Map集合的特点都是无序不可重复。Map和Set集合存储元素的特点相同。HashMap底层是哈希表,非线程安全,在JDK8后如果哈希表单向元素超过8个就编程红黑树结构,红黑树的节点数量小于6个又编程单项链表结构,为的是提交检索效率。 初始容量是16,按照2倍扩容。HashTable底层也是哈希表,用sychorinized是线程安全的,key和value不允许为null。 初始容量11,按照 原容量*2+1 方式扩容。Properties继承于HashTable,线程安全,key和value只能是String类型。常用方法1.Collection的常用方法方法名说明boolean add(E e)添加元素到集合的末尾(追加)boolean remove(Object o)删除指定的元素,成功则返回true(底层调用equles)void clear()清空集合boolean contains(Object o)判断元素在集合中是否存在,存在则返回true(底层调用equles)boolean isEmpty()判断集合是否为空,空则返回trueint size()返回集合中元素个数Iterator iterator()迭代器2.ArrayList的常用方法方法名说明public ArrayList()创建一个空集合public boolean add(E e)将指定的参数元素追加到集合的末尾public void add(int index ,E e)在集合的指定位置添加指定的元素(插入元素)public void addAll(E object)用于将指定集合中所有元素添加到当前集合中public boolean remove(Object o)删除指定的元素,成功则返回truepublic E remove(int index)删除指定索引位置的元素,返回被删除的元素public E set(int index,E e)修改指定索引位置的元素,返回修改前的元素public E get(int index)获取指定索引对应的元素public int size()获取结合中元素个数3.Map的基本方法方法名说明V put(K key,V value)设置键值对V remove(Object key)删除元素void clear()清空集合boolean containsKey(Object key)判断键是否存在,存在则返回trueboolean containsValue(Object value)判断值是否存在,存在则返回trueboolean isEmpty()判断集合是否为空int size()获取集合元素个数
  • [区域初赛赛题问题] 为什么我提交了好几次,但是系统显示我的排名和分数一直不变
    为什么我提交了好几次,但是系统显示我的排名和分数一直不变
  • [常见FAQ] Java如何debug
    想问问,Java版本调试的方法,有没有具体教程,上面的说明不是看的很懂
  • [区域初赛赛题问题] Java 包管理
    【如题】Java该怎么安排文件路劲呢?放src下的.java 类都被删掉了。总不能一个Main写几千行吧 XD
  • [技术干货] 第十三届蓝桥杯省赛 C++ A 组 F 题、Java A 组 G题、C组 H 题、Python C 组 I 题——青蛙过河(AC)-转载
     1.青蛙过河 1.题目描述 小青蛙住在一条河边, 它想到河对岸的学校去学习。小青蛙打算经过河里 的石头跳到对岸。  河里的石头排成了一条直线, 小青蛙每次跳跃必须落在一块石头或者岸上。 不过, 每块石头有一个高度, 每次小青蛙从一块石头起跳, 这块石头的高度就 会下降 1 , 当石头的高度下降到 0 时小青蛙不能再跳到这块石头上(某次跳跃 后使石头高度下降到 0 是允许的)。  小青蛙一共需要去学校上 x xx 天课, 所以它需要往返 2 x 2x2x 次。当小青蛙具有 一个跳跃能力 y yy 时, 它能跳不超过 y yy 的距离。  请问小青蛙的跳跃能力至少是多少才能用这些石头上完 x xx 次课。  2.输入格式 输入的第一行包含两个整数 n , x n,xn,x, 分别表示河的宽度和小青蛙需要去学校 的天数。请注意 2 x 2x2x 才是实际过河的次数。 第二行包含 n − 1 n−1n−1 个非负整数 H 1 , H 2 , ⋯ , H n − 1 H_1,H_2,⋯,H_{n-1}H  1 ​  ,H  2 ​  ,⋯,H  n−1 ​  , 其中 H i > 0 H_i>0H  i ​  >0表 示在河中与 小青蛙的家相距 i ii 的地方有一块高度为 H i H_iH  i ​   ​的石头, H i = 0 H_i =0H  i ​  =0 表示这个位置没有石头。  3.输出格式 输出一行, 包含一个整数, 表示小青蛙需要的最低跳跃能力。  4.样例输入 5 1 1 0 1 0  5.样例输出 4  6.数据范围 1 ≤ n ≤ 1 0 5 , 1 ≤ x ≤ 1 0 9 , 1 ≤ H i ≤ 1 0 4 。 1≤n≤10^5 ,1≤x≤10^9,1≤H i ≤10^ 4 。1≤n≤10  5  ,1≤x≤10  9  ,1≤Hi≤10  4  。  7.原题链接 青蛙过河  2.解题思路 假设青蛙可以按照某条路线S SS从家跳往对岸,路线S SS上所有的石子高度均减1,这个操作等价于“青蛙从对岸按照路线S SS反向跳回家,路线S SS上所有的石子高度均减1”。  这也说明,判断小青蛙能否往返2 x 2x2x次,等价于判断小青蛙能否从左往右跳重复2 x 2x2x次。  由题目可以发现,设小青蛙的跳跃能力为y yy,当小青蛙跳跃能力y yy越大,越容易满足“重复2x次”的约束,即求解的y yy存在单调性:  当y yy越大时,小青蛙每次可以跳的范围更大,可以跳更少的步数到达对岸,即更容易重复2 x 2x2x次,当y = n y=ny=n时,无需经过任何石子就可以跳到对岸。 当y yy越小时,小青蛙需要使用更多的步数才能到达对岸,更不容易满足“重复2 x 2x2x次”的约束。 本题最终需要求解的是:恰好满足约束的最小的y yy 答案存在单调性,显然可以用二分答案的算法进行求解,初始区间[ l , r ] = [ 1 , n ] [l,r]=[1,n][l,r]=[1,n]:  求出区间[ l , r ] [l,r][l,r]的中点m i d midmid,m i d = ( l + r ) / / 2 mid=(l+r)//2mid=(l+r)//2 判断当小青蛙跳跃能力等于m i d midmid时,能否从左往右跳重复2 x 2x2x次 如果可以,则更新a n s = m i d ans=midans=mid,调整搜索区间为[ l , m i d − 1 ] [l,mid-1][l,mid−1](求最小值,因此调整右端点) 否则,调整搜索区间为[ m i d + 1 , r ] [mid+1,r][mid+1,r] 如果l > r l > rl>r,终止循环,否则回到1 11 二分答案将求解最值问题转换成判定性问题,问题转变成当跳跃能力等于y yy时,判断小青蛙能否从左往右跳2 x 2x2x次。  小青蛙最开始位于0处,跳跃能力等于y yy,需要重复跳跃2 x 2x2x次,则首先要求从1 − y 1-y1−y的石子高度必须大于等于2 x 2x2x,不然小青蛙迈出的第一步都无法重复2 x 2x2x次。  这个结论可以推广——“所有长度为y yy的区间中石子高度之和必须大于等于2 x 2x2x”。  如果所有长度为y yy的区间中,石子高度之和等于2 x : 2x:2x:则存在H i = H i + y H_i=H_{i+y}H  i ​  =H  i+y ​  ,则只要保证第一步在[ 1 , y ] [1,y][1,y]中选择一个可以跳跃的石子i ii,则后续跳跃只需从当前位置i ii跳到i + y i+yi+y即可。这样可以保证重复2 x 2x2x次; 如果所有长度为y yy的区间中,石子高度之和大于2 x 2x2x:**则可以考虑去除某些石子的高度,从而构造出情况1,此时也是可以保证重复2 x 2x2x次的; 如果可以重复跳跃2 x 2x2x次,所有区间长度为y yy的区间中石子高度之和大于等于2 x 2x2x:对于任意区间[ i , i + y ] [i,i+y][i,i+y],每次跳跃必须在区间中落脚。利用反证法,如果不在区间[ i , i + y ] [i,i+y][i,i+y]中落脚,等价于从i ii的左边跳到了i + y i+yi+y的右边,此时跳跃长度超过了能力上限y yy,因此不合法。也就是说,每次跳跃对于任意长度等于y yy的区间都落脚1次,重复2 x 2x2x次则说明该区间石子之和大于等于2 x 2x2x。 通过上面三点可以证明:“当跳跃能力等于y yy时重复2 x 2x2x次”等价于“所有区间长度等于y yy的区间石子高度之和大于等于2 x 2x2x”,利用这个结论进行二分答案的判定即可。  实现过程中事先预处理前缀和,从而可以O ( 1 )​O(1)​O(1)​求解区间和,时间复杂度O ( n log ⁡ n )​O(n\log n)​O(nlogn)​。  实际上使用双指针,维护区间和始终大于 2 x 2x2x,得到的最小区间长度则是答案,这样可做到 O ( n ) O(n)O(n) 的复杂度。  Ac_code 1.C++ #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long uLL; typedef pair<int, int> PII; #define pb(s) push_back(s); #define SZ(s) ((int)s.size()); #define ms(s,x) memset(s, x, sizeof(s)) #define all(s) s.begin(),s.end() const int inf = 0x3f3f3f3f; const int mod = 1000000007; const int N = 200010;  LL n, x; void solve() {     cin >> n >> x;     std::vector<LL> s(n + 1);     for (int i = 1; i < n; ++i) {         cin >> s[i];         s[i] += s[i - 1];     }     //最后一块石头,也就是终点,可以无限跳     s[n] = 1e18;     int l = 1, r = n;     auto check = [&](int g) {         for (int i = 0; i + g <= n; ++i) {             int r = i + g;             if (s[r] - s[i] < 2 * x) return false;         }         return true;     };     while (l < r) {         int mid = l + r  >> 1;         if (check(mid)) r = mid;         else l = mid + 1;     }     cout << r << '\n'; } int main() {     ios_base :: sync_with_stdio(false);     cin.tie(0); cout.tie(0);     int t = 1;     while (t--)     {         solve();     }     return 0; } 2.Java import java.util.Scanner;   public class Main {     public static void main(String[] args) {         Scanner sc=new Scanner(System.in);         int n=sc.nextInt();         long x=sc.nextLong();         long []arr=new long[n+1];         for (int i=1;i<n;i++){             arr[i]=sc.nextLong()+arr[i-1];         }         arr[n]=100000000000L;         int l=0;         int ans=0;         for (int r=1;r<=n;r++){             if (arr[r]-arr[l]>= 2*x){                 ans=Math.max(ans,r-l);                 l+=1;             }         }         System.out.println(ans);     } } ———————————————— 版权声明:本文为CSDN博主「执 梗」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_57487901/article/details/129136195 
总条数:2301 到第 页
上滑加载中