.ipynb文件的三种打开方式、java回溯法矩阵中的路径、AOP简单理解和应用、旋转数组的最小数字

.ipynb文件的三种打开方式

重点说下.ipynb文件的三种打开方式:

1,GitHub 中可以直接打开 .ipynb 文件。
2,可以把 .ipynb 文件对应的下载链接复制到 https://nbviewer.jupyter.org/ 中查看。
3,安装 Anaconda,从开始菜单中打开 jupyter notebook 的快捷方式(prompt 中用该命令打开同理),默认启动路径在 C:\Users\yourname 类似的文件夹。把 .ipynb 文件复制到这个目录下面,找到并打开即可查看。

 “.ipynb” 文件是使用 Jupyter Notebook 来编写Python程序时的文件。

Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本,支持运行 40 多种编程语言。在jupyter下的File—>Download as —>python(.py)可以将.ipynb转化为.py文件。

打开方式:

1. 在GitHub中可以直接打开。

2.打开网站  http:// https://nbviewer.jupyter.org/,然后将.ipynb文件的链接复制进去即可打开。

 3.如果已安装 Anaconda,自带jupyter软件。

从开始菜单中打开 jupyter notebook 的快捷方式(prompt 中用该命令打开同理),就会自动打开一个http://localhost:8888/的链接。此时web端属于是登录了一个“账号”,你可以根据需要,在线执行代码等操作。通过upload选择电脑本地文件,上传即可打开和运行。

注意终端不可关闭。而在本地终端这里则是一直停留在运行界面,如果你不小心关闭就算注销了。所以你可以在web页面里在线注销,也可以在本地终端里Ctrl+C退出,此时就会显示弹窗服务终止。我们就无法通过web页面来访问本地文件了。

从jupyter notebook里打开的.ipynb文件才是格式正确,层次分明的交互式笔记文件了。很多项目程序里都以这样的文件格式方式来保存的。当然,jupyter notebook其实并不仅仅用于机器学习。

 

 

## java回溯法矩阵中的路径 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
package algorithmBasic;

/**
 * @author kegekeqi
 * @version 1.0
 * @date 2021-12-12 22:24
 */
public class HuiSuo {
	public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
		if (null == matrix || rows < 1 || cols < 1 || str == null) {
			return false;
		}
		boolean[][] visited = new boolean[rows][cols];
		for (int row = 0; row < rows; row++) {
			for (int col = 0; col < cols; col++) {
				if (hasPath(matrix, rows, cols, row, col, str, 0, visited)) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean hasPath(char[] matrix, int rows, int cols, int row, int col,
							char[] str, int index, boolean[][] visited) {
		if (index == str.length) {
			return  true;
		}

		if (row >= 0 && row < rows && col >= 0 && col < cols && !visited[row][col]
				&& matrix[cols * row + col] == str[index]) {
			visited[row][col] = true;
			if (hasPath(matrix, rows, cols, row - 1, col, str, index + 1, visited)
					|| hasPath(matrix, rows, cols, row + 1, col, str, index + 1, visited)
					|| hasPath(matrix, rows, cols, row, col - 1, str, index + 1, visited)
					|| hasPath(matrix, rows, cols, row, col + 1, str, index + 1, visited)) {
				return true;
			}
			visited[row][col] = false;
		}
		return false;

	}
}

AOP简单理解和应用

AOP(面向切面编程),实际就是代理的一个应用,常用的场景有日志、事务、缓存等,分为静态代理和动态代理。

他们的区别是静态代理只能作用在方法上,且代理类是手动编写,常见的就是使用AspectJ,静态代理是在编译期织入。

而动态代理作用域更广泛,可以在属性,方法,构造器等上插入,常用的是cglib,和jdk,动态代理是在运行期枳织入。

cglib和jdk的区别是jdk必须要有实现类,而cglib是生成一个继承类作为代理类。

他们的都是字节码增强

下面简单介绍一下AspectJ:

AspectJ 支持 5 种类型的通知注解:

@Before:前置通知,在方法执行之前执行

@After:后置通知,在方法执行之后执行 (无论是否发生异常都会执行)

@AfterRunning:返回通知,在方法返回结果之后执行

@AfterThrowing:异常通知,在方法抛出异常之后

@Around:环绕通知,围绕着方法执行

例子(接口日志异步入库):


 
@Aspect
@Component
public class LogAspect {
 
  @Autowired
  private SaveLogService saveLogService;
 
  // 定义切点
  @Pointcut("@annotation(com.zdww.cd.sx.config.MyLog)")
  public void LogPointCut() {
  }
 
  //切面(通知和切点) 配置通知
  @After("LogPointCut()")
  // 一共有五种通知,after在方法之后执行
  public void saveOperation(JoinPoint joinPoint) {
 
    //用于保存日志
    com.zdww.cd.sx.pojo.MyLog log = new com.zdww.cd.sx.pojo.MyLog();
 
    //从连接点处通过反射机制获取连接点处的方法签名对象
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    //获取连接点所在的方法
    Method method = signature.getMethod();
    //获取操作方法上的MyLog注解的值
    MyLog myLog = method.getAnnotation(MyLog.class);
    if (myLog != null) {
      String operation = myLog.operation();
      log.setOperation(operation);
      String type = myLog.type();
      log.setType(type);
    }
    HttpServletRequest request = ((ServletRequestAttributes) Objects
        .requireNonNull(RequestContextHolder
            .getRequestAttributes())).getRequest();
    String requestURL = request.getRequestURL().toString();
    log.setUrl(requestURL);
    String ip = IPUtil.getIP(request);
    log.setLoginIp(ip);
    Date now = new Date();
    log.setCreateTime(now);
    User user = (User) request.getSession().getAttribute("user");
    if (user != null) {
      String userId = user.getAccount();
      String userName = user.getUsername();
      log.setUserId(userId);
      log.setUserName(userName);
      saveLogService.saveLog(log);
    }
  }
}

获取切入方法对象三种方法:

1.通过反射机制获取切入点目标类的方法

public void invoke(JoinPoint joinPoint) throws Throwable{

//登录拦截

MethodInvocationProceedingJoinPoint methodPoint = (MethodInvocationProceedingJoinPoint)joinPoint;

Field proxy = methodPoint.getClass().getDeclaredField(“methodInvocation”);

proxy.setAccessible(true);

ReflectiveMethodInvocation j = (ReflectiveMethodInvocation) proxy.get(methodPoint);

Method method = j.getMethod();

Login login = method.getAnnotation(Login.class);

2.通过JoinPoint的getTarget()获取连接点所在的目标对象

public void invoke(JoinPoint joinPoint) throws Throwable{

//拦截的实体类

Object target = joinPoint.getTarget();

//拦截的方法名称

String methodName = joinPoint.getSignature().getName();

//拦截的方法参数

Object[] argsa = joinPoint.getArgs();

//拦截的放参数类型

Class[] parameterTypes = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterTypes();

Method method = target.getClass().getMethod(methodName, parameterTypes);

Login login = method.getAnnotation(Login.class);

3.通过JoinPoint的getSignature()获取连接点的方法签名对象

public void invoke(JoinPoint joinPoint) throws Throwable{

MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

Method method = methodSignature.getMethod();

Login login = method.getAnnotation(Login.class);

旋转数组的最小数字【记录】

解法一

package algorithmBasic;

/**
 * @author kegekeqi
 * @version 1.0
 * @date 2021-12-12 18:01
 */
public class RotateArray {
	public int minArray(int[] numbers) {
		if (null == numbers || numbers.length == 0) {
			return 0;
		}
		int low = 0;
		int high = numbers.length - 1;
		while (low < high) {
			int mid = (low + high) / 2;
			if (numbers[mid] < numbers[high]) {
				high = mid;
			} else if (numbers[mid] > numbers[high]) {
				low = mid + 1;
			} else {
				high--;
			}
		}
		return numbers[low];
	}

	public static void main(String[] args) {
		RotateArray array = new RotateArray();
		int[] numbers = {3, 4, 5, 1, 2};
		int minArray = array.minArray(numbers);
		System.out.println(minArray);
	}
}

package algorithmBasic;

/**
 * @author kegekeqi
 * @version 1.0
 * @date 2021-12-12 18:16
 */
public class RotateArray2 {
	public int minInReversingList(int[] arr){
		if(arr==null){
			return -1;
		}
		int leftIndex = 0;
		int rightIndex = arr.length -1;
		int midIndex = leftIndex;
		while(arr[leftIndex]>= arr[rightIndex]){
			if(rightIndex - leftIndex <= 1){
				midIndex = rightIndex;
				break;
			}
			midIndex = (leftIndex+rightIndex)/2;
			if(arr[leftIndex]== arr[rightIndex] && arr[midIndex]== arr[leftIndex]){
				return MinInOrder(arr,leftIndex,rightIndex);
			}
			if(arr[midIndex] >= arr[leftIndex]){
				leftIndex = midIndex;
			}else if(arr[midIndex] < arr[rightIndex]){
				rightIndex = midIndex;
			}
		}
		return arr[midIndex];
	}
	public int MinInOrder(int[] arr,int leftIndex,int rightIndex){
		int result = arr[leftIndex];
		for(int i = leftIndex +1;i<rightIndex;i++){
			if(result> arr[i]){
				result = arr[i];
			}
		}
		return result;
	}
	public static void main(String[] args){
		RotateArray2 test = new RotateArray2();
		int[] arr = {3, 4, 5, 1, 2};
		System.out.println(test.minInReversingList(arr));

	}
}

  • 12
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,下面是使用AOPJava Spring Boot将日志保存到文件的代码示例: 1. 首先,我们需要添加依赖,如下所示: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.14.0</version> </dependency> ``` 其,`spring-boot-starter-aop`是Spring Boot的AOP依赖,`log4j-slf4j-impl`是Log4j的SLF4J适配器,这里我们使用Log4j来实现日志的文件输出。 2. 然后,我们需要在`application.properties`添加Log4j的配置,如下所示: ```properties logging.level.root=info logging.file.path=D:/code/logs logging.file.name=coursemanagement.log logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n ``` 这里我们将日志级别设为`info`,并指定日志文件路径文件名,日志输出的格式也可以自定义,这里我们将日志输出到控制台和文件。 3. 接下来,我们需要定义一个切面类,如下所示: ```java import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { private static final Logger logger = LogManager.getLogger(LoggingAspect.class); @Before("execution(* com.example.coursemanagement.controller.*.*(..))") public void logBefore(JoinPoint joinPoint) { logger.info("Entering {}.{}() with arguments {}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(), joinPoint.getArgs()); } @AfterThrowing(pointcut = "execution(* com.example.coursemanagement.controller.*.*(..))", throwing = "ex") public void logAfterThrowing(JoinPoint joinPoint, Throwable ex) { logger.error("Exception in {}.{}() with cause = {}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(), ex.getCause() != null ? ex.getCause() : "NULL"); } } ``` 在上面的代码,我们定义了一个名为`LoggingAspect`的切面类,在类上使用了`@Aspect`和`@Component`注解。 在类,我们定义了两个切面方法,分别是`logBefore`和`logAfterThrowing`,分别用于记录方法进入和方法异常信息。 其,我们使用了Log4j的`LogManager`和`Logger`类来定义日志记录器,使用了`@Before`和`@AfterThrowing`注解来定义切面方法的类型和切入点,使用`joinPoint`参数来获取方法签名和参数信息,最后使用日志记录器来输出日志信息。 4. 最后,我们需要在`application.properties`指定日志输出的类型为`file`,如下所示: ```properties logging.type=file ``` 这样,日志信息就可以输出到指定路径下的文件了。 希望这段代码可以帮助你更好地理解使用AOPJava Spring Boot将日志保存到文件的方法。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值